void messagesLoop() { vector<size_t> messages_ids; Message msg; Group online; string src; string dst; string net_msg; int sock; size_t msg_id; while(true) { chat_mtx.lock(); messages_ids = chat.getMessagesIds(); for(auto const& id: messages_ids) { online = chat.getGroup(ONLINE_GROUP); msg = chat.getMessage(id); src = msg.getSrcUserName(); dst = msg.getDstUserName(); bool is_file = msg.hasTitle(); if(online.has(src) && online.has(dst)) { sock = chat.getSocketFromUser(dst); if(is_file) net_msg = hostToNetFileIncoming(msg); else net_msg = hostToNetMsgIncoming(msg); //cout << "sock1 = " << sock << endl; //sending message to destiny user if(send(sock, net_msg) < 0) { cout << "error sending message from " + src + " to " + dst << ":" << endl; perror(""); } else { msg_id = hash<Message>{}(msg); chat.delMessage(msg_id); sock = chat.getSocketFromUser(src); //cout << "sock2 = " << sock << endl; if(is_file) net_msg = hostToNetFileSent(msg_id); else net_msg = hostToNetMsgSent(msg_id); //notificating source user if(send(sock, net_msg) < 0) { cout << "error sending " << (is_file?"file":"message") << " from " << src << " to " << dst << ":" << endl; perror(""); } } } } chat_mtx.unlock(); this_thread::sleep_for(chrono::milliseconds(MSG_LOOP_TIME_MS)); } }
int handle(int socket, const string& str, const User& user) { char header; string answer; int ret = 0; header = netToHostHeader(str); switch(header) { case EXIT: { answer = hostToNetMsg(OK); ret = -1; break; } case WHO: { stringstream ss; vector<string> header = {"user", "status"}; chat_mtx.lock(); ChatView view(chat, ss); view.printUsersFromGroup(ONLINE_GROUP, header); view.printUsersFromGroup(OFFLINE_GROUP, false); chat_mtx.unlock(); answer = hostToNetUsersList(ss.str()); break; } case SEND_MSG: { Message msg = netToHostSendMsg(str); /*cout << "src | dst | content: " << msg.getSrcUserName() << " | " << msg.getDstUserName() << " | " << msg.getContent() << endl;*/ if(msg.getSrcUserName().empty()) { answer = hostToNetMsg(INVALID_REQUEST_ERR); break; } bool has_user, add_msg=true; chat_mtx.lock(); has_user = chat.hasUser(msg.getDstUserName()); if(has_user) add_msg = chat.addMessage(msg); chat_mtx.unlock(); if(!has_user) answer = hostToNetMsg(NO_MSG_DST_ERR); else if(!add_msg) answer = hostToNetMsg(MSG_EXISTS); else { size_t msg_id; msg_id = hash<Message>{}(msg); //cout << msg_id << endl; answer = hostToNetMsgQueued(msg_id); } break; } case SEND_FILE: { Message msg = netToHostSendFile(str); /*cout << "src | dst | content: " << msg.getSrcUserName() << " | " << msg.getDstUserName() << " | " << msg.getContent() << endl;*/ if(msg.getSrcUserName().empty()) { answer = hostToNetMsg(INVALID_REQUEST_ERR); break; } bool has_user, add_msg=true; chat_mtx.lock(); has_user = chat.hasUser(msg.getDstUserName()); if(has_user) add_msg = chat.addMessage(msg); chat_mtx.unlock(); if(!has_user) answer = hostToNetMsg(NO_MSG_DST_ERR); else if(!add_msg) answer = hostToNetMsg(MSG_EXISTS); else { size_t msg_id; msg_id = hash<Message>{}(msg); //cout << msg_id << endl; answer = hostToNetFileQueued(msg_id); } break; } case CREATE_GROUP: { string group_name = netToHostCreateGroup(str); if(group_name.empty()) { answer = hostToNetMsg(INVALID_REQUEST_ERR); break; } bool has_group; chat_mtx.lock(); has_group = chat.hasGroup(group_name); chat.addGroup(group_name); chat_mtx.unlock(); if(has_group) answer = hostToNetMsg(GROUP_EXISTS); else answer = hostToNetMsg(GROUP_CREATED); break; } case JOIN_GROUP: { string group_name = netToHostJoinGroup(str); if(group_name.empty()) { answer = hostToNetMsg(INVALID_REQUEST_ERR); break; } bool has_group, add_user; chat_mtx.lock(); has_group = chat.hasGroup(group_name); add_user = chat.addUserToGroup(user.getName(), group_name); chat_mtx.unlock(); if(!has_group) answer = hostToNetMsg(NO_GROUP_ERR); else if(!add_user) answer = hostToNetMsg(USER_ALREADY_IN_GROUP); else answer = hostToNetMsg(USER_ADDED_TO_GROUP); break; } case SEND_GROUP: { pair<string, string> group_msg = netToHostSendGroup(str); if(group_msg.first.empty()) { answer = hostToNetMsg(INVALID_REQUEST_ERR); break; } Group group; bool in_group, has_group; string user_name = user.getName(); string group_name = group_msg.first; string group_msg_c = group_msg.second; chat_mtx.lock(); has_group = chat.hasGroup(group_name); if(has_group) { group = chat.getGroup(group_name); in_group = group.has(user_name); if(in_group) for(auto const& name: group.getUsersNames()) if(name != user_name) { Message msg = Message(user_name, name, group_msg_c); chat.addMessage(msg); } } chat_mtx.unlock(); if(has_group) { if(!in_group) answer = hostToNetMsg(NOT_IN_GROUP_ERR); else { size_t msg_id; Message msg = Message(user_name, group_name, group_msg_c); msg_id = hash<Message>{}(msg); //cout << msg_id << endl; answer = hostToNetMsgQueued(msg_id); } } else answer = hostToNetMsg(NO_GROUP_ERR); break; } default: answer = hostToNetMsg(INVALID_REQUEST_ERR); break; } if(send(socket, answer) < 0) error("send"); return ret; }