Initial submit
This commit is contained in:
149
server.cpp
149
server.cpp
@@ -1,12 +1,149 @@
|
||||
#include "server.h"
|
||||
|
||||
namespace Yp {
|
||||
namespace Lib {
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <thread>
|
||||
#include <future>
|
||||
#include <functional>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <json/json.h>
|
||||
#include <iostream>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sstream>
|
||||
|
||||
Server::Server()
|
||||
{
|
||||
namespace Yc {
|
||||
namespace Lib {
|
||||
|
||||
}
|
||||
Server::Server(Yc::Lib::Config *config) :
|
||||
_config(config),
|
||||
_stop(false) {
|
||||
struct sockaddr_in serverAddr;
|
||||
int opt = true;
|
||||
_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
|
||||
int flags = 1;
|
||||
setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
|
||||
serverAddr.sin_family = AF_INET;
|
||||
serverAddr.sin_addr.s_addr = INADDR_ANY;
|
||||
serverAddr.sin_port = htons(1235);
|
||||
if (bind(_socket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
|
||||
std::cout << "bind not possible" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
createRooms(config->group("rooms"));
|
||||
}
|
||||
|
||||
} // namespace Lib
|
||||
void Server::run() {
|
||||
if (listen(_socket, 5) < 0) {
|
||||
std::cout << "listen not possible" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
timeval origTv;
|
||||
origTv.tv_sec = 5;
|
||||
origTv.tv_usec = 0;
|
||||
int _maxSd = _socket;
|
||||
while (!_stop) {
|
||||
timeval tv(origTv);
|
||||
fd_set fd;
|
||||
FD_ZERO(&fd);
|
||||
FD_SET(_socket, &fd);
|
||||
if (select(_maxSd + 1, &fd, NULL, NULL, &tv) > 0) {
|
||||
std::async(std::launch::async, &Server::handleRequest, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> Server::roomList() {
|
||||
std::vector<std::string> list;
|
||||
for (auto &room: _rooms) {
|
||||
list.push_back(room->name());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
Json::Value Server::jsonRoomList() {
|
||||
Json::Value list;
|
||||
for (auto &room: _rooms) {
|
||||
list.append(room->name());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void Server::createRooms(Json::Value roomList) {
|
||||
for (auto &room: roomList) {
|
||||
std::vector<std::string> allowedUsers;
|
||||
for (auto &user: room["allowed"]) {
|
||||
allowedUsers.push_back(user.asString());
|
||||
}
|
||||
Room *newRoom = new Room(this, room["name"].asString(), room["password"].asString(), allowedUsers);
|
||||
_rooms.push_back(newRoom);
|
||||
}
|
||||
}
|
||||
|
||||
void Server::handleRequest() {
|
||||
struct sockaddr_in sockAddr;
|
||||
socklen_t sockAddrLen = sizeof(sockAddr);
|
||||
int userSock = accept(_socket, (struct sockaddr *)&sockAddr, &sockAddrLen);
|
||||
if (userSock < 0) {
|
||||
return;
|
||||
}
|
||||
int flags = 1;
|
||||
setsockopt(userSock, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
|
||||
std::string msg("");
|
||||
char buffer[256];
|
||||
bzero(buffer, 256);
|
||||
while (int received = recv(userSock, buffer, 255, 0) > 0) {
|
||||
msg += std::string(buffer);
|
||||
if (received < 255) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (msg == "") {
|
||||
return;
|
||||
}
|
||||
inputSwitcher(userSock, msg);
|
||||
}
|
||||
|
||||
void Server::inputSwitcher(int userSocket, std::string input) {
|
||||
Json::Value inputTree;
|
||||
Json::CharReaderBuilder rbuilder;
|
||||
std::unique_ptr<Json::CharReader> const reader(rbuilder.newCharReader());
|
||||
JSONCPP_STRING inputJsonString(input);
|
||||
reader->parse(inputJsonString.data(), inputJsonString.data() + inputJsonString.size(), &inputTree, NULL);
|
||||
if (inputTree["type"] == "init") {
|
||||
initUser(userSocket, inputTree);
|
||||
}
|
||||
}
|
||||
|
||||
bool Server::userExists(std::string userName) {
|
||||
for (auto &room: _rooms) {
|
||||
if (room->userNameExists(userName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Server::initUser(int userSocket, Json::Value data) {
|
||||
if (userExists(data["name"].asString())) {
|
||||
close(userSocket);
|
||||
return;
|
||||
}
|
||||
std::string room = data["room"].asString();
|
||||
bool added(false);
|
||||
for (auto &room: _rooms) {
|
||||
if (room->name() == data["room"].asString()) {
|
||||
if (room->addUser(data["name"].asString(), data["color"].asString(), data["password"].asString(), userSocket)) {
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!added) {
|
||||
close(userSocket);
|
||||
}
|
||||
}
|
||||
} // namespace Lib
|
||||
} // namespace Yp
|
||||
|
||||
Reference in New Issue
Block a user