diff --git a/ServerPixel/ServerPixel.cpp b/ServerPixel/ServerPixel.cpp index 6d83d75..2ff5668 100644 --- a/ServerPixel/ServerPixel.cpp +++ b/ServerPixel/ServerPixel.cpp @@ -34,6 +34,12 @@ // session #include "sessionManager.h" +// current directory +#include + +// file read/write +#include + namespace beast = boost::beast; namespace http = beast::http; namespace websocket = beast::websocket; @@ -115,6 +121,20 @@ LRESULT CALLBACK GLWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) return DefWindowProc(hWnd, msg, wParam, lParam); } +// log +HANDLE hConsoleOutputColor; +std::ofstream logFile; +void LOG(std::stringstream&& s, WORD color) +{ + SetConsoleTextAttribute(hConsoleOutputColor, color); + std::cout << s.str() << std::endl; + if (logFile.is_open()) + { + logFile << s.str() << std::endl; + } + +} + int main(int argc, char* argv[]) { // disable console input @@ -124,13 +144,33 @@ int main(int argc, char* argv[]) SetConsoleMode(hInput, ENABLE_EXTENDED_FLAGS | (prev_mode & ~ENABLE_QUICK_EDIT_MODE)); + // configure logs function + { + // get output handle for log function + hConsoleOutputColor = GetStdHandle(STD_OUTPUT_HANDLE); + // open log file + std::string logsFolder = std::filesystem::current_path().string() + "\\ServerLogs"; + std::string logFileName = std::to_string(std::chrono::system_clock::now().time_since_epoch().count()) + ".log"; + std::wstring logsFolder_LPCWSTR = std::wstring(logsFolder.begin(), logsFolder.end()); + logFile.open(logsFolder + "\\" + logFileName, std::ios::out); + if (!logFile) + { + if (CreateDirectory(logsFolder_LPCWSTR.c_str(), NULL) || ERROR_ALREADY_EXISTS == GetLastError()) + { + logFile.open(logsFolder + "\\" + logFileName, std::ios::out); + } + else + { + std::cout << "create direcotry failed: " << logsFolder << std::endl; + } + } + } - // args - // 1 - server ip - // 2 - server port - // 3 - copies amount + // 1 - copies amount + // 2 - server ip + // 3 - server port // 4 - path_to_node.js // 5 - start_http_port // 6 - start_streamer_port @@ -139,7 +179,7 @@ int main(int argc, char* argv[]) // 8 - application_args (without -pixelStreamingPort cos its argv[3]) // sessions - uint16_t sessionLimit = std::atoi(argv[3]); + uint16_t sessionLimit = std::atoi(argv[1]); sessionManager sessManager; sessManager.setlimit(sessionLimit); @@ -166,11 +206,11 @@ int main(int argc, char* argv[]) } // ip and socket init - std::string ip(argv[1]); - std::cout << "ip: " << ip << std::endl; + std::string ip(argv[2]); + LOG((std::stringstream() << "ip: " << ip), 7); auto const address = net::ip::make_address(ip); - auto const port = static_cast(std::atoi(argv[2])); - std::cout << "port: " << port << std::endl; + auto const port = static_cast(std::atoi(argv[3])); + LOG((std::stringstream() << "port: " << port), 7); net::io_context ioc{ 1 }; tcp::acceptor acceptor{ ioc, {address, port} }; @@ -200,10 +240,19 @@ int main(int argc, char* argv[]) user_id = hash6(user_ip + std::to_string(user_id)); uint64_t thisUserNum = ++user_n; + LOG((std::stringstream() << "user(" << thisUserNum << ") connected (ip: " << user_ip << "), (id: " << user_id << ")"), 7); - std::cout << "user(" << thisUserNum << ") connected (ip: " << user_ip << "), (id: " << user_id << ")" << std::endl; + // init websocket websocket::stream ws(std::move(const_cast(sock))); ws.accept(); + /*try + { + ws.accept(); + } + catch (std::exception const& e) + { + std::cerr << "Error: " << e.what() << std::endl; + }*/ // Set a decorator to change the Server of the /*ws.set_option(websocket::stream_base::decorator( [](websocket::response_type& res) @@ -275,8 +324,6 @@ int main(int argc, char* argv[]) { buffer.clear(); - sessManager.getMinPort(); - if (sessManager.isLimitReached()) { boost::beast::ostream(buffer) @@ -295,7 +342,9 @@ int main(int argc, char* argv[]) // get session port uint16_t sessMinPort = sessManager.getMinPort(); - uint16_t sessHttpPort = sessMinPort ? sessMinPort + 1 : portHttp; + if (!sessMinPort) + sessMinPort = portHttp; + uint16_t sessHttpPort = sessMinPort + 1; uint16_t sessStreamPort = portStream + (sessHttpPort - portHttp); @@ -304,7 +353,7 @@ int main(int argc, char* argv[]) if (!CreateProc(appPath, appPath + " " + appArgs + std::to_string(sessStreamPort), &appProcInfo)) { - std::cout << "CreateProcess failed (" << GetLastError() << ")." << std::endl; + LOG((std::stringstream() << "CreateProcess failed (" << GetLastError() << ")."), 12); continue; } @@ -343,8 +392,8 @@ int main(int argc, char* argv[]) //sessCur->addProcId(GetProcessId(nodeProcInfo.hProcess)); } - std::cout << "user(" << thisUserNum << ") created session (id: " << sessId << - "), (httpPort: " << sessHttpPort << "), (streamPort: " << sessStreamPort << ")" << std::endl; + LOG((std::stringstream() << "session [" + << sessId << "] created, (httpPort: " << sessHttpPort << "), (streamPort: " << std::to_string(sessStreamPort) + ")"), 10); // send respond buffer.clear(); @@ -384,13 +433,12 @@ int main(int argc, char* argv[]) { if (sessCur->existsUserId(user_id)) { - std::cout << "user exists: " << user_id << std::endl; + LOG((std::stringstream() << "user exists: " << user_id), 7); continue; } sessCur->addUser(user(user_id)); - - std::cout << "user(" << thisUserNum << ") connected to session (id: " << sessCur->getId() - << "), (users: " << sessCur->getUsersCount() << ")" << std::endl; + LOG((std::stringstream() << "user(" << thisUserNum << ") connected to session (id: " << sessCur->getId() + << "), (users: " << sessCur->getUsersCount() << ")"), 14); buffer.clear(); boost::beast::ostream(buffer) @@ -399,7 +447,11 @@ int main(int argc, char* argv[]) } else { - std::cout << "no session (id: " << content << ")" << std::endl; + LOG((std::stringstream() << "no session (id: " << content << ")"), 14); + buffer.clear(); + boost::beast::ostream(buffer) + << (std::string("{\"message\" : \"SESS_NOT_EXISTS\"}")); + ws.write(buffer.data()); } } @@ -413,16 +465,22 @@ int main(int argc, char* argv[]) } catch (beast::system_error const& se) { - std::cout << "user(" << thisUserNum << ") disconnected" << std::endl; - if (!sessManager.getById(sessId, &sessCur)) - std::cout << "no session with id: " << sessId << std::endl; - if (sessCur) + LOG((std::stringstream() << "user(" << thisUserNum << ") disconnected"), 7); + + if (sessId) { + sessManager.getById(sessId, &sessCur); + if (sessCur == nullptr) + { + std::cout << "nullptr session" << std::endl; + continue; + } + sessCur->removeUserById(user_id); if (!sessCur->getUsersCount()) { - std::cout << "destroy session (id: " << sessCur->getId() << ")" << std::endl; + LOG((std::stringstream() << "session [" << sessCur->getId() << "] destroyed"), 12); std::vector procIds(sessCur->getProcIds()); for (auto& id : procIds) EndProc(id); @@ -442,5 +500,6 @@ int main(int argc, char* argv[]) } }).detach(); } + logFile.close(); return 0; } \ No newline at end of file diff --git a/ServerPixel/ServerPixel.vcxproj b/ServerPixel/ServerPixel.vcxproj index 75ea8d4..6a9e581 100644 --- a/ServerPixel/ServerPixel.vcxproj +++ b/ServerPixel/ServerPixel.vcxproj @@ -149,6 +149,7 @@ _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true C:\Libraries\json-develop\include;C:\Libraries\boost\include\boost_1_79_0;%(AdditionalIncludeDirectories) + stdcpp17 Console @@ -164,6 +165,7 @@ NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true C:\Libraries\json-develop\include;C:\Libraries\boost\include\boost_1_79_0;%(AdditionalIncludeDirectories) + stdcpp17 Console diff --git a/ServerPixel/sessionManager.h b/ServerPixel/sessionManager.h index b79feb6..021d86a 100644 --- a/ServerPixel/sessionManager.h +++ b/ServerPixel/sessionManager.h @@ -65,7 +65,8 @@ public: std::vector ports; for (auto& s : sessions) ports.push_back(s.getPort()); - std::sort(ports.begin(), ports.end()); + + std::sort(ports.begin(), ports.end(), [](uint16_t a, uint16_t b) { return a > b; }); return *(ports.begin()); } };