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)); } }
void ChatMsgProcessor::processMsg(MessageInterface* msg) { // Pseudocode: // Get common header CommonHeader* header = msg->getHeader(); // Determine sub type for message Msg::Sub::Type subtype = header->getMsgSubtype(); // Retrieve the payload Chat* ChatMessage = ((Message<Chat>*)msg)->getPayload(); // If subtype == normal (1) if (Msg::Sub::NORMAL == subtype) { std::cout << "Processing normal chat Message\n"; // Get the client info for the client id ClientInfo* client = m_MessageProcessor->client_manager->getClientInfo(header->getClientID()); // try to get chat room infor ChatRoomInfo* chatRoom = m_MessageProcessor->chatroom_manager->getChatRoomInfo(header->getDestinationID()); // if nothing comes back, then it's not a valid chat room if (NULL == chatRoom) { CommonHeader* returnHeader = new CommonHeader(Msg::STATUS_AND_ERROR, Msg::Sub::UNKNOWN, header->getDestinationID(), header->getClientID()); StatusAndError* status = new StatusAndError(Status::INVALID_DESTINATION_ID, Msg::CHAT, Msg::Sub::NORMAL, "Destination is not a chat room."); Message<StatusAndError>* returnMsg = new Message<StatusAndError>(*returnHeader, *status); m_ComManager->sendMessage(returnMsg); delete returnHeader; delete status; delete returnMsg; } // check if user is in chat room else if (!chatRoom->CheckChatRoomClients(client->getClientId())) { CommonHeader* returnHeader = new CommonHeader(Msg::STATUS_AND_ERROR, Msg::Sub::UNKNOWN, header->getDestinationID(), header->getClientID()); StatusAndError* status = new StatusAndError(Status::INVALID_DESTINATION_ID, Msg::CHAT, Msg::Sub::NORMAL, "User is not in destination chat room."); Message<StatusAndError>* returnMsg = new Message<StatusAndError>(*returnHeader, *status); m_ComManager->sendMessage(returnMsg); delete returnHeader; delete status; delete returnMsg; } else { //first get username of sending client and append to new payload ChatMessage->setMessage(m_MessageProcessor->client_manager-> getClientInfo(header->getClientID())->getUserName()+": "+ChatMessage->getMessage()); // get list of clients in chat room std::vector<int>* clientsInRoom = chatRoom->getClients(); for (std::vector<int>::const_iterator it = clientsInRoom->begin(); it != clientsInRoom->end(); ++it) { if(*it == header->getClientID()) { //send echo message with modified payload m_ComManager->sendMessage(msg); } else { //send message to all other clients in chat room CommonHeader* returnHeader = new CommonHeader(Msg::CHAT, Msg::Sub::NORMAL, header->getDestinationID(), *it); Message<Chat>* returnMsg = new Message<Chat>(*returnHeader, *ChatMessage); m_ComManager->sendMessage(returnMsg,*it); delete returnHeader; delete returnMsg; } } } } // else if subtype == whisper (2) else if (Msg::Sub::WHISPER == subtype) { std::cout << "Processing whisper chat Message\n"; // Get the client info for the client id ClientInfo* destClient = m_MessageProcessor->client_manager->getClientInfo(header->getDestinationID()); // if client is null, they aren't a client or don't exist if (NULL == destClient) { CommonHeader* returnHeader = new CommonHeader(Msg::STATUS_AND_ERROR, Msg::Sub::UNKNOWN, header->getDestinationID(), header->getClientID()); StatusAndError* status = new StatusAndError(Status::INVALID_DESTINATION_ID, Msg::CHAT, Msg::Sub::WHISPER, "Destination is not a user."); Message<StatusAndError>* returnMsg = new Message<StatusAndError>(*returnHeader, *status); m_ComManager->sendMessage(returnMsg); delete returnHeader; delete status; delete returnMsg; } // send message to client CommonHeader* destHeader = new CommonHeader(Msg::CHAT, Msg::Sub::WHISPER, header->getClientID(), header->getDestinationID()); Chat* destMessage = new Chat(ChatMessage->getMessage()); Message<Chat>* destReturnMsg = new Message<Chat>(*destHeader, *destMessage); m_ComManager->sendMessage(destReturnMsg); // send message to sender CommonHeader* sourceHeader = new CommonHeader(Msg::CHAT, Msg::Sub::WHISPER, header->getDestinationID(), header->getClientID()); Chat* sourceMessage = new Chat(ChatMessage->getMessage()); Message<Chat>* SourceReturnMsg = new Message<Chat>(*sourceHeader, *sourceMessage); m_ComManager->sendMessage(SourceReturnMsg); delete destHeader; delete destMessage; delete destReturnMsg; delete sourceHeader; delete sourceMessage; delete SourceReturnMsg; } // else if subtype == admin (3) else if (Msg::Sub::ADMIN == subtype) { std::cout << "Processing admin chat Message\n"; // Get the client info for the client id ClientInfo* client = m_MessageProcessor->client_manager->getClientInfo(header->getClientID()); // check if user has permission to send admin message if (!client->getAdmin()) { CommonHeader* returnHeader = new CommonHeader(Msg::STATUS_AND_ERROR, Msg::Sub::UNKNOWN, header->getDestinationID(), header->getClientID()); StatusAndError* status = new StatusAndError(Status::INVALID_DESTINATION_ID, Msg::CHAT, Msg::Sub::ADMIN, "User does not have appropriate permissions."); Message<StatusAndError>* returnMsg = new Message<StatusAndError>(*returnHeader, *status); m_ComManager->sendMessage(returnMsg); delete returnHeader; delete status; delete returnMsg; } else { // get list of all clients std::vector<int> clients = m_MessageProcessor->client_manager->getAllClients(); // send message to each client for (std::vector<int>::const_iterator it = clients.begin(); it != clients.end(); ++it) { CommonHeader* returnHeader = new CommonHeader(Msg::CHAT, Msg::Sub::ADMIN, header->getDestinationID(), ((int)*it)); Chat* chatmsg = new Chat(ChatMessage->getMessage()); Message<Chat>* returnMsg = new Message<Chat>(*returnHeader, *chatmsg); m_ComManager->sendMessage(returnMsg); delete returnHeader; delete chatmsg; delete returnMsg; } } } // Else else { // Send error response std::cout << "Invalid Message Subtype received\n"; CommonHeader* returnHeader = new CommonHeader(Msg::STATUS_AND_ERROR, Msg::Sub::UNKNOWN, header->getDestinationID(), header->getClientID()); StatusAndError* status = new StatusAndError(Status::INVALID_MESSAGE_SUB_TYPE, Msg::CHAT, header->getMsgSubtype(), "Invalid message subtype"); Message<StatusAndError>* returnMsg = new Message<StatusAndError>(*returnHeader, *status); m_ComManager->sendMessage(returnMsg); delete returnHeader; delete status; delete returnMsg; } }