Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Skillbox chat day 2.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
- //
- #include <iostream>
- #include <uwebsockets/App.h>
- using namespace std;
- // START OF DAY 1
- #include <regex>
- #include <algorithm>
- map<string, string> knowledge = {
- {"hello", "oh,. hello, human"},
- {"what", "ChatBot ewfgwegwthth"},
- {"how", "fine qgkqogk wffw"},
- {"do", "Coding gqokgoqgkq"}
- };
- string to_lower(string text) {
- transform(text.begin(), text.end(), text.begin(), ::tolower);
- return text;
- }
- string botAnswer(string question) {
- string answer;
- question = to_lower(question);
- for (auto entry : knowledge) {
- regex expression = regex(".*" + entry.first + ".*");
- if (answer.empty() && regex_match(question, expression)) {
- // отвечаем на первый попавшийся знакомый вопрос
- // пока не умею создавать массивы неизвестной длины, чтобы выдать N ответов
- answer = entry.second;
- }
- }
- if (answer.empty()) {
- answer = "Unknown command";
- }
- return answer;
- }
- // END OF DAY 1
- const string SET_NAME = "SET_NAME::";
- const string DIRECT = "DIRECT::";
- bool isSetNameCommand(string_view message) {
- return message.find(SET_NAME) == 0;
- }
- bool isInvalidName(string_view message) {
- const string name = string(message.substr(SET_NAME.length() + 2));
- if (name.find("::") != string::npos) {
- return true;
- }
- if (name.length() > 255) {
- return true;
- }
- return false;
- }
- string parseName(string_view message) {
- return string(message.substr(SET_NAME.length()));
- }
- string parseReceiverId(string_view message) {
- string_view rest = message.substr(DIRECT.length());
- int pos = rest.find("::");
- string_view id = rest.substr(0, pos);
- return string(id);
- }
- string parseDirectMessage(string_view message) {
- string_view rest = message.substr(DIRECT.length());
- int pos = rest.find("::");
- string_view text = rest.substr(pos + 2);
- return string(text);
- }
- bool isDirectCommand(string_view message) {
- return message.find(DIRECT) == 0;
- }
- /* This is a simple WebSocket echo server example.
- * You may compile it with "WITH_OPENSSL=1 make" or with "make" */
- int main() {
- /* ws->getUserData returns one of these */
- struct PerSocketData {
- /* Fill with user data */
- int user_id;
- string name;
- };
- int last_user_id = 2;
- /* Keep in mind that uWS::SSLApp({options}) is the same as uWS::App() when compiled without SSL support.
- * You may swap to using uWS:App() if you don't need SSL */
- //uWS::SSLApp({
- // /* There are example certificates in uWebSockets.js repo */
- // .key_file_name = "../misc/key.pem",
- // .cert_file_name = "../misc/cert.pem",
- // .passphrase = "1234"
- //})
- uWS::App()
- .ws<PerSocketData>("/*", {
- /* Settings */
- .compression = uWS::SHARED_COMPRESSOR,
- .maxPayloadLength = 16 * 1024,
- .idleTimeout = 600,
- .maxBackpressure = 1 * 1024 * 1024,
- /* Handlers */
- .upgrade = nullptr,
- .open = [&last_user_id](auto* connection) {
- /* Open event here, you may access ws->getUserData() which points to a PerSocketData struct */
- cout << "New connection created" << endl;
- PerSocketData* userData = (PerSocketData*)connection->getUserData();
- userData->user_id = last_user_id++;
- userData->name = "Unnamed";
- connection->subscribe("broadcast");
- connection->subscribe("user#" + to_string(userData->user_id));
- connection->publish("broadcast", "Total users connected: " + to_string(last_user_id - 2));
- },
- .message = [&last_user_id](auto* connection, std::string_view message, uWS::OpCode opCode) {
- cout << "New message received: " << message << endl;
- PerSocketData* userData = (PerSocketData*)connection->getUserData();
- if (isSetNameCommand(message)) {
- if (isInvalidName(message)) {
- cout << "ERROR: Trying to set invalid name\n";
- connection->publish("user#" + to_string(userData->user_id), "Name is invalid (contain :: or too long)");
- }
- else {
- cout << "User set their name\n";
- userData->name = parseName(message);
- }
- }
- if (isDirectCommand(message)) {
- string receiver = parseReceiverId(message);
- string text = parseDirectMessage(message);
- int id = stoi(receiver);
- const string selfChannel = "user#" + to_string(userData->user_id);
- if (id > last_user_id || id < 1) {
- cout << "ERROR: User trying to send message to wrong id \n";
- connection->publish(selfChannel, "Error, there is no user with ID = " + receiver);
- }
- else if (id == 1) {
- cout << "User sent direct message to BOT\n";
- connection->publish(selfChannel, botAnswer(text));
- }
- else {
- cout << "User sent direct message\n";
- connection->publish("user#" + receiver, text);
- }
- }
- },
- .close = [](auto*/*ws*/, int /*code*/, std::string_view /*message*/) {
- /* You may access ws->getUserData() here */
- cout << "Connection closed" << endl;
- }
- //.drain = [](auto*/*ws*/) {
- // /* Check ws->getBufferedAmount() here */
- //},
- //.ping = [](auto*/*ws*/) {
- // /* Not implemented yet */
- //},
- //.pong = [](auto*/*ws*/) {
- // /* Not implemented yet */
- //},
- })
- .listen(9001, [](auto* listen_socket) {
- if (listen_socket) {
- cout << "Listening on port " << 9001 << endl;
- }
- })
- .run();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement