Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <algorithm>
- #include <regex>
- #include <map>
- #include <uwebsockets/App.h>
- /*
- * Протокол
- * MESSAGE_TO::1025::Привет, мир!
- *
- * MESSAGE_FROM::1026::Какой то текст
- *
- * SET_NAME::Мой ник
- *
- * MESSAGE_ALL::Привет всем
- */
- const std::string MESSAGE_TO = "MESSAGE_TO::";
- const std::string SET_NAME = "SET_NAME::";
- const uint32_t START_USER_ID = 1024;
- std::string parseUserId(std::string message) {
- std::string rest = message.substr(MESSAGE_TO.size());
- int pos = rest.find("::");
- return rest.substr(0, pos);
- }
- std::string parseUserText(std::string message) {
- std::string rest = message.substr(MESSAGE_TO.size());
- int pos = rest.find("::");
- return rest.substr(pos + 2);
- }
- std::string parseName(std::string message) {
- return message.substr(SET_NAME.size());;
- }
- bool isValidName(std::string message) {
- return message.find("::") == std::string::npos and message.size() <= 255;
- }
- bool isMessageTo(std::string message) {
- return message.find(MESSAGE_TO) == 0;
- }
- bool isSetName(std::string message) {
- return message.find(SET_NAME) == 0;
- }
- std::string messageFrom(std::string user_id, std::string senderName, std::string message) {
- return "MESSAGE_FROM::" + user_id + "::[" + senderName + "] " + message;
- }
- std::string to_lower(std::string txt) {
- transform(txt.begin(), txt.end(), txt.begin(), ::tolower);
- return txt;
- }
- int main() {
- std::map<std::string, std::string> database = {
- {"hello", "oh hi how are you?"},
- {"how are you", "Im doing just fine, LOL"},
- {"what are you doing", "I'm answering stupid question"},
- {"where are you from", "I'm from within your mind"},
- {"how old are you", "I'm only 10 nanoseconds old"},
- {"what are you", "I'm your friendly ChatBot2021"},
- {"exit", "Ok byyyyeeee"},
- };
- struct PerSocketData {
- std::string name;
- uint32_t user_id;
- };
- uint32_t last_user_id = START_USER_ID;
- uWS::App().
- ws<PerSocketData>("/*", {
- .idleTimeout = 1200,
- .open = [&last_user_id](auto* ws) {
- PerSocketData* userData = (PerSocketData*)ws->getUserData();
- userData->name = "UNNAMED";
- userData->user_id = last_user_id++;
- std::cout << "New user connected, id = " << userData->user_id << std::endl;
- ws->subscribe("user#" + std::to_string(userData->user_id));
- ws->subscribe("broadcast");
- std::cout << "Total users connected: " << last_user_id - START_USER_ID << std::endl;
- },
- .message = [&last_user_id, database](auto* ws, std::string_view message, uWS::OpCode opCode) {
- std::string strMessage = std::string(message);
- PerSocketData* userData = (PerSocketData*)ws->getUserData();
- std::string senderId = std::to_string(userData->user_id);
- if (isMessageTo(strMessage)) {
- std::string reseiverId = parseUserId(strMessage);
- std::string text = parseUserText(strMessage);
- std::string outgoingMessage = messageFrom(senderId, userData->name, text);
- uint32_t reseiver = std::stoi(reseiverId);
- if (reseiver == 1) {
- std::string question = to_lower(text);
- for (auto entry : database) {
- std::regex pattern = std::regex(".*" + entry.first + ".*");
- if (regex_match(question, pattern)) {
- ws->publish("user#" + senderId, entry.second);
- }
- }
- }
- else {
- if (std::stoi(reseiverId) < last_user_id and std::stoi(reseiverId) >= START_USER_ID) {
- ws->publish("user#" + reseiverId, outgoingMessage);
- std::cout << "Author #" << senderId << " wrote message to " << reseiverId << std::endl;
- }
- else {
- std::string noUserMessage = "Error, there is no user with ID = " + reseiverId;
- ws->publish("user#" + senderId, noUserMessage);
- std::cout << noUserMessage << std::endl;
- }
- }
- }
- if (isSetName(strMessage)) {
- std::string newName = parseName(strMessage);
- if (isValidName(newName)) {
- userData->name = newName;
- std::cout << "User #" << senderId << " set name " << newName << std::endl;
- }
- }
- },
- .close = [&last_user_id](auto*/*ws*/, int /*code*/, std::string_view /*message*/) {
- last_user_id--;
- std::cout << "Total users connected: " << last_user_id - START_USER_ID << std::endl;
- }
- })
- .listen(9001, [last_user_id](auto* listen_socket) {
- if (listen_socket) {
- std::cout << "Listening on port " << 9001 << std::endl;
- std::cout << "Total users connected: " << last_user_id - START_USER_ID << std::endl;
- }
- })
- .run();
- }
Advertisement
Add Comment
Please, Sign In to add comment