Receive and send messages
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,3 +8,4 @@
|
|||||||
/tools.o
|
/tools.o
|
||||||
/user.o
|
/user.o
|
||||||
/yourchat
|
/yourchat
|
||||||
|
*.o
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ SOURCES += main.cpp \
|
|||||||
server.cpp \
|
server.cpp \
|
||||||
room.cpp \
|
room.cpp \
|
||||||
user.cpp \
|
user.cpp \
|
||||||
tools.cpp
|
tools.cpp \
|
||||||
|
base.cpp
|
||||||
|
|
||||||
DISTFILES += \
|
DISTFILES += \
|
||||||
config/chatconfig.json
|
config/chatconfig.json
|
||||||
@@ -19,7 +20,8 @@ HEADERS += \
|
|||||||
server.h \
|
server.h \
|
||||||
room.h \
|
room.h \
|
||||||
user.h \
|
user.h \
|
||||||
tools.h
|
tools.h \
|
||||||
|
base.h
|
||||||
|
|
||||||
LIBS += -ljsoncpp \
|
LIBS += -ljsoncpp \
|
||||||
-lpthread
|
-lpthread
|
||||||
|
|||||||
52
base.cpp
Normal file
52
base.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#include "base.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace Yc {
|
||||||
|
namespace Lib {
|
||||||
|
|
||||||
|
std::string Base::getJsonString(Json::Value json) {
|
||||||
|
std::string outString;
|
||||||
|
std::stringstream outStream;
|
||||||
|
outStream << json;
|
||||||
|
return outStream.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Base::send(int socket, std::string out) {
|
||||||
|
write(socket, out.c_str(), out.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Base::send(int socket, Json::Value out) {
|
||||||
|
std::string outString = getJsonString(out);
|
||||||
|
send(socket, outString);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Base::readSocket(int socket)
|
||||||
|
{
|
||||||
|
std::string msg("");
|
||||||
|
char buffer[256];
|
||||||
|
bzero(buffer, 256);
|
||||||
|
while (int received = recv(socket, buffer, 255, 0) > 0) {
|
||||||
|
msg += std::string(buffer);
|
||||||
|
if (received < 255) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value Base::getJsonTree(std::string msg) {
|
||||||
|
Json::Value inputTree;
|
||||||
|
Json::CharReaderBuilder rbuilder;
|
||||||
|
std::unique_ptr<Json::CharReader> const reader(rbuilder.newCharReader());
|
||||||
|
JSONCPP_STRING inputJsonString(msg);
|
||||||
|
reader->parse(inputJsonString.data(), inputJsonString.data() + inputJsonString.size(), &inputTree, NULL);
|
||||||
|
return inputTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Lib
|
||||||
|
} // namespace Yc
|
||||||
21
base.h
Normal file
21
base.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef YC_LIB_BASE_H
|
||||||
|
#define YC_LIB_BASE_H
|
||||||
|
|
||||||
|
#include <json/json.h>
|
||||||
|
|
||||||
|
namespace Yc {
|
||||||
|
namespace Lib {
|
||||||
|
|
||||||
|
class Base {
|
||||||
|
protected:
|
||||||
|
std::string getJsonString(Json::Value json);
|
||||||
|
void send(int socket, std::string out);
|
||||||
|
void send(int socket, Json::Value out);
|
||||||
|
std::string readSocket(int socket);
|
||||||
|
Json::Value getJsonTree(std::string msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Lib
|
||||||
|
} // namespace Yc
|
||||||
|
|
||||||
|
#endif // YC_LIB_BASE_H
|
||||||
23
room.cpp
23
room.cpp
@@ -18,6 +18,10 @@ namespace Yc {
|
|||||||
thread = new std::thread(&Room::run, this);
|
thread = new std::thread(&Room::run, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Room::~Room() {
|
||||||
|
delete thread;
|
||||||
|
}
|
||||||
|
|
||||||
void Room::run() {
|
void Room::run() {
|
||||||
while (!_stop) {
|
while (!_stop) {
|
||||||
if (_msgQueue.size() > 0 && !_blocked) {
|
if (_msgQueue.size() > 0 && !_blocked) {
|
||||||
@@ -26,12 +30,12 @@ namespace Yc {
|
|||||||
Message message = _msgQueue.front();
|
Message message = _msgQueue.front();
|
||||||
_msgQueue.pop();
|
_msgQueue.pop();
|
||||||
for (auto &user: _users) {
|
for (auto &user: _users) {
|
||||||
user.sendMsg(message.type, message.messageTr, message.userName, message.color);
|
user->sendMsg(message.type, message.messageTr, message.userName, message.color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_blocked = false;
|
_blocked = false;
|
||||||
}
|
}
|
||||||
usleep(50000);
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,14 +43,14 @@ namespace Yc {
|
|||||||
if (_password != "" && _password == _password && std::find(std::begin(_allowedUsers), std::end(_allowedUsers), _userName) == std::end(_allowedUsers)) {
|
if (_password != "" && _password == _password && std::find(std::begin(_allowedUsers), std::end(_allowedUsers), _userName) == std::end(_allowedUsers)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
User newUser(this, _userName, color, socket);
|
User *newUser = new User(this, _userName, color, socket);
|
||||||
_users.push_back(newUser);
|
_users.push_back(newUser);
|
||||||
newUser.sendMsg(User::roomList, _parent->jsonRoomList(), "", "");
|
newUser->sendMsg(User::roomList, _parent->jsonRoomList(), "", "");
|
||||||
addMessage(User::system, "room_entered", newUser.name(), newUser.color());
|
addMessage(User::system, "room_entered", newUser->name(), newUser->color());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Room::addUser(User user, std::string password) {
|
bool Room::addUser(User *user, std::string password) {
|
||||||
if (password == _password) {
|
if (password == _password) {
|
||||||
_users.push_back(user);
|
_users.push_back(user);
|
||||||
return true;
|
return true;
|
||||||
@@ -56,7 +60,7 @@ namespace Yc {
|
|||||||
|
|
||||||
bool Room::userNameExists(std::string userName) {
|
bool Room::userNameExists(std::string userName) {
|
||||||
for (auto &user: _users) {
|
for (auto &user: _users) {
|
||||||
if (user.name() == userName) {
|
if (user->name() == userName) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,9 +68,10 @@ namespace Yc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Room::removeUser(std::string _token) {
|
void Room::removeUser(std::string _token) {
|
||||||
for (std::vector<User>::iterator user = _users.begin(); user != _users.end(); ++user) {
|
for (std::vector<User*>::iterator user = _users.begin(); user != _users.end(); ++user) {
|
||||||
if (user->validateToken(_token)) {
|
if ((*user)->validateToken(_token)) {
|
||||||
_users.erase(user);
|
_users.erase(user);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
room.h
5
room.h
@@ -16,10 +16,11 @@ namespace Yc {
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Room(Server *parent, std::string name, std::string password = "", std::vector<std::string> allowedUsers = std::vector<std::string>());
|
Room(Server *parent, std::string name, std::string password = "", std::vector<std::string> allowedUsers = std::vector<std::string>());
|
||||||
|
~Room();
|
||||||
void run();
|
void run();
|
||||||
std::string name();
|
std::string name();
|
||||||
bool addUser(std::string userName, std::string color, std::string password, int socket);
|
bool addUser(std::string userName, std::string color, std::string password, int socket);
|
||||||
bool addUser(User user, std::string password);
|
bool addUser(User *user, std::string password);
|
||||||
bool userNameExists(std::string userName);
|
bool userNameExists(std::string userName);
|
||||||
void removeUser(std::string _token);
|
void removeUser(std::string _token);
|
||||||
void setStop();
|
void setStop();
|
||||||
@@ -36,7 +37,7 @@ namespace Yc {
|
|||||||
std::string _name;
|
std::string _name;
|
||||||
std::string _password;
|
std::string _password;
|
||||||
std::vector<std::string> _allowedUsers;
|
std::vector<std::string> _allowedUsers;
|
||||||
std::vector<User> _users;
|
std::vector<User*> _users;
|
||||||
bool _blocked;
|
bool _blocked;
|
||||||
bool _stop;
|
bool _stop;
|
||||||
std::queue<Message> _msgQueue;
|
std::queue<Message> _msgQueue;
|
||||||
|
|||||||
21
server.cpp
21
server.cpp
@@ -6,7 +6,6 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <strings.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -91,15 +90,7 @@ namespace Yc {
|
|||||||
}
|
}
|
||||||
int flags = 1;
|
int flags = 1;
|
||||||
setsockopt(userSock, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
|
setsockopt(userSock, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
|
||||||
std::string msg("");
|
std::string msg = readSocket(userSock);
|
||||||
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 == "") {
|
if (msg == "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -107,11 +98,7 @@ namespace Yc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Server::inputSwitcher(int userSocket, std::string input) {
|
void Server::inputSwitcher(int userSocket, std::string input) {
|
||||||
Json::Value inputTree;
|
Json::Value inputTree = getJsonTree(input);
|
||||||
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") {
|
if (inputTree["type"] == "init") {
|
||||||
initUser(userSocket, inputTree);
|
initUser(userSocket, inputTree);
|
||||||
}
|
}
|
||||||
@@ -128,6 +115,10 @@ namespace Yc {
|
|||||||
|
|
||||||
void Server::initUser(int userSocket, Json::Value data) {
|
void Server::initUser(int userSocket, Json::Value data) {
|
||||||
if (userExists(data["name"].asString())) {
|
if (userExists(data["name"].asString())) {
|
||||||
|
Json::Value errorJson;
|
||||||
|
errorJson["type"] = User::error;
|
||||||
|
errorJson["message"] = "loggedin";
|
||||||
|
send(userSocket, errorJson);
|
||||||
close(userSocket);
|
close(userSocket);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
3
server.h
3
server.h
@@ -4,12 +4,13 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "room.h"
|
#include "room.h"
|
||||||
|
#include "base.h"
|
||||||
#include <json/value.h>
|
#include <json/value.h>
|
||||||
|
|
||||||
namespace Yc {
|
namespace Yc {
|
||||||
namespace Lib {
|
namespace Lib {
|
||||||
|
|
||||||
class Server
|
class Server: public Base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Server(Yc::Lib::Config *config);
|
Server(Yc::Lib::Config *config);
|
||||||
|
|||||||
46
user.cpp
46
user.cpp
@@ -3,7 +3,6 @@
|
|||||||
#include <tools.h>
|
#include <tools.h>
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <future>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "room.h"
|
#include "room.h"
|
||||||
@@ -23,7 +22,12 @@ namespace Yc {
|
|||||||
_stop(false) {
|
_stop(false) {
|
||||||
_token = Yc::Lib::Tools::generateRandomString(32);
|
_token = Yc::Lib::Tools::generateRandomString(32);
|
||||||
sendMsg(token, _token, "", "");
|
sendMsg(token, _token, "", "");
|
||||||
std::async(std::bind(&User::checkerTask, this));
|
thread = new std::thread(&User::checkerTask, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
User::~User() {
|
||||||
|
delete thread;
|
||||||
|
_parent->addMessage(User::system, "leaved_chat", _name, _color);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string User::name() const {
|
std::string User::name() const {
|
||||||
@@ -44,11 +48,7 @@ namespace Yc {
|
|||||||
sendMessage["message"] = message;
|
sendMessage["message"] = message;
|
||||||
sendMessage["userName"] = userName;
|
sendMessage["userName"] = userName;
|
||||||
sendMessage["color"] = color;
|
sendMessage["color"] = color;
|
||||||
std::string outString;
|
send(sendMessage);
|
||||||
std::stringstream outStream;
|
|
||||||
outStream << sendMessage;
|
|
||||||
outString = outStream.str();
|
|
||||||
write(_socket, outString.c_str(), outString.length());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void User::sendMsg(User::MsgType type, Json::Value message, std::string userName, std::string color) {
|
void User::sendMsg(User::MsgType type, Json::Value message, std::string userName, std::string color) {
|
||||||
@@ -57,11 +57,7 @@ namespace Yc {
|
|||||||
sendMessage["message"] = message;
|
sendMessage["message"] = message;
|
||||||
sendMessage["userName"] = userName;
|
sendMessage["userName"] = userName;
|
||||||
sendMessage["color"] = color;
|
sendMessage["color"] = color;
|
||||||
std::string outString;
|
send(sendMessage);
|
||||||
std::stringstream outStream;
|
|
||||||
outStream << sendMessage;
|
|
||||||
outString = outStream.str();
|
|
||||||
write(_socket, outString.c_str(), outString.length());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void User::checkerTask() {
|
void User::checkerTask() {
|
||||||
@@ -71,11 +67,19 @@ namespace Yc {
|
|||||||
FD_SET(_socket, &readSd);
|
FD_SET(_socket, &readSd);
|
||||||
timeval tv;
|
timeval tv;
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 100;
|
tv.tv_usec = 500;
|
||||||
if (select(_socket + 1, &readSd, NULL, NULL, &tv) < 0 && errno != ETIMEDOUT) {
|
int selectResult = select(_socket + 1, &readSd, NULL, NULL, &tv);
|
||||||
|
std::cout << selectResult << "/" << FD_ISSET(_socket, &readSd) << std::endl;
|
||||||
|
if (selectResult == 1 && FD_ISSET(_socket, &readSd) == 1) {
|
||||||
_parent->removeUser(_token);
|
_parent->removeUser(_token);
|
||||||
_stop = true;
|
_stop = true;
|
||||||
}
|
}
|
||||||
|
std::string msg = readSocket(_socket);
|
||||||
|
if (msg == "") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::cout << msg << std::endl;
|
||||||
|
handleMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,5 +91,19 @@ namespace Yc {
|
|||||||
return _color;
|
return _color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void User::send(std::string out) {
|
||||||
|
Base::send(_socket, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void User::send(Json::Value out) {
|
||||||
|
Base::send(_socket, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void User::handleMessage(std::string message) {
|
||||||
|
Json::Value jsonTree = getJsonTree(message);
|
||||||
|
if (jsonTree["type"].asString() == "message") {
|
||||||
|
_parent->addMessage(User::message, jsonTree["message"].asString(), _name, _color);
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace Lib
|
} // namespace Lib
|
||||||
} // namespace Yc
|
} // namespace Yc
|
||||||
|
|||||||
10
user.h
10
user.h
@@ -3,15 +3,18 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
#include <thread>
|
||||||
|
#include "base.h"
|
||||||
|
|
||||||
namespace Yc {
|
namespace Yc {
|
||||||
namespace Lib {
|
namespace Lib {
|
||||||
|
|
||||||
class Room;
|
class Room;
|
||||||
|
|
||||||
class User {
|
class User: public Base {
|
||||||
public:
|
public:
|
||||||
enum MsgType {
|
enum MsgType {
|
||||||
|
error = -1,
|
||||||
token = 1,
|
token = 1,
|
||||||
userListe = 2,
|
userListe = 2,
|
||||||
roomList = 3,
|
roomList = 3,
|
||||||
@@ -20,6 +23,7 @@ namespace Yc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
User(Room *parent, std::string name, std::string color, int socket);
|
User(Room *parent, std::string name, std::string color, int socket);
|
||||||
|
~User();
|
||||||
std::string name() const;
|
std::string name() const;
|
||||||
bool validateToken(std::string token);
|
bool validateToken(std::string token);
|
||||||
bool isUser(User *toValidate);
|
bool isUser(User *toValidate);
|
||||||
@@ -35,6 +39,10 @@ namespace Yc {
|
|||||||
int _socket;
|
int _socket;
|
||||||
std::string _token;
|
std::string _token;
|
||||||
bool _stop;
|
bool _stop;
|
||||||
|
std::thread *thread;
|
||||||
|
void send(std::string out);
|
||||||
|
void send(Json::Value out);
|
||||||
|
void handleMessage(std::string message);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Lib
|
} // namespace Lib
|
||||||
|
|||||||
Reference in New Issue
Block a user