From 36ff1cbd7b0ddcddd255a386aa79a8bc6a91bf3d Mon Sep 17 00:00:00 2001 From: C Date: Sun, 17 Jul 2022 15:41:13 +0500 Subject: [PATCH] first working --- ServerPixel/ServerPixel.cpp | 214 +++++++++++++++++++++++++---------- ServerPixel/session.h | 11 +- ServerPixel/sessionManager.h | 12 ++ 3 files changed, 175 insertions(+), 62 deletions(-) diff --git a/ServerPixel/ServerPixel.cpp b/ServerPixel/ServerPixel.cpp index 4a66b40..9d97d38 100644 --- a/ServerPixel/ServerPixel.cpp +++ b/ServerPixel/ServerPixel.cpp @@ -83,6 +83,25 @@ void EndProc(DWORD procId) } } +bool CreateProc( + std::string path, + std::string args, + PROCESS_INFORMATION* processInfo +) +{ + std::wstring path_ws = std::wstring(path.begin(), path.end()); + const wchar_t* path_cw = path_ws.c_str(); + + std::wstring cmd_ws = std::wstring(args.begin(), args.end()); + wchar_t* cmd_w = const_cast(cmd_ws.c_str()); + + // creating process + STARTUPINFO startupInfo = { sizeof(startupInfo) }; + if (!CreateProcess(path_cw, cmd_w, NULL, NULL, TRUE, 0, NULL, NULL, &startupInfo, processInfo)) + return false; + return true; +} + template uint32_t hash6(T arg) { @@ -105,19 +124,52 @@ int main(int argc, char* argv[]) SetConsoleMode(hInput, ENABLE_EXTENDED_FLAGS | (prev_mode & ~ENABLE_QUICK_EDIT_MODE)); - // ip and socket init - std::string ip("192.168.1.115"); - uint16_t sess_port = 13001; - auto const address = net::ip::make_address(ip); - auto const port = static_cast(std::atoi("8083")); - net::io_context ioc{ 1 }; + - tcp::acceptor acceptor{ ioc, {address, port} }; + // args + // 1 - copies amount + // 2 - path_to_node.js + // 3 - start_http_port + // 4 - start_streamer_port + + // 5 - path_to_application + // 6 - application_args (without -pixelStreamingPort cos its argv[3]) // sessions + uint16_t sessionLimit = std::atoi(argv[1]); sessionManager sessManager; - sessManager.setlimit(10); + sessManager.setlimit(sessionLimit); + + // merging app arguments + std::string appPath = argv[5]; + std::string appArgs; + for (int i = 6; i < argc; ++i) + appArgs += argv[i] + std::string(" "); + + appArgs += "-PixelStreamingPort="; + + // first app ports + uint16_t portHttp = std::atoi(argv[3]); + uint16_t portStream = std::atoi(argv[4]); + + // node js + /*std::string nodePath = "C:\\Program Files\\nodejs\\node.exe"; + std::string nodeFilePath = argv[2];*/ + + // starting node js servers + for (uint16_t i = 0; i < sessionLimit; ++i) + { + system((std::string("start node ") + argv[2] + " " + std::to_string(portHttp + i) + " " + std::to_string(portStream + i)).c_str()); + } + + // ip and socket init + std::string ip("192.168.1.115"); + uint16_t sess_port = 13002; + auto const address = net::ip::make_address(ip); + auto const port = static_cast(std::atoi("13001")); + net::io_context ioc{ 1 }; + tcp::acceptor acceptor{ ioc, {address, port} }; // stats count uint64_t user_n = 0; @@ -127,7 +179,19 @@ int main(int argc, char* argv[]) tcp::socket socket(ioc); acceptor.accept(socket); - std::thread([sock = std::move(socket), &sessManager, &ip, &sess_port, &user_n]() mutable + std::thread([ + sock = std::move(socket), + &sessManager, + &ip, + &sess_port, + &user_n, + appPath, + appArgs, + portStream, + portHttp + //nodePath, + //nodeFilePath + ]() mutable { std::string user_ip = sock.remote_endpoint().address().to_string(); uint64_t user_id = std::chrono::system_clock::now().time_since_epoch().count(); @@ -148,6 +212,18 @@ int main(int argc, char* argv[]) //session sessTmp; session* sessCur = nullptr; uint32_t sessId = 0; + uint16_t sessMinPort = sessManager.getMinPort(); + uint16_t sessHttpPort = sessMinPort ? sessMinPort + 1 : portHttp; + uint16_t sessStreamPort = portStream + (sessHttpPort - portHttp); + + //std::cout << "minPort: " << sessMinPort << std::endl; + + //std::cout << "httpPortDefault: " << portHttp << std::endl + // << "streamPortDefault: " << portStream << std::endl; + + //std::cout << "httpPort: " << sessHttpPort << std::endl + // << "streamPort: " << sessStreamPort << std::endl; + nlohmann::json jsonData; std::string message; @@ -207,6 +283,8 @@ int main(int argc, char* argv[]) { buffer.clear(); + sessManager.getMinPort(); + if (sessManager.isLimitReached()) { boost::beast::ostream(buffer) @@ -228,61 +306,79 @@ int main(int argc, char* argv[]) << std::string("{\"message\" : \"CREATING_SESSION\", \"content\" : \"true\"}").c_str(); ws.write(buffer.data()); - std::string path = "D:\\Builds\\Fortis_UnStable_57\\FORTIS_Taktika.exe"; - std::wstring path_ws = std::wstring(path.begin(), path.end()); - const wchar_t* path_cw = path_ws.c_str(); - - std::string cmd = "-PixelStreamingIP=localhost -PixelStreamingPort=12005 -RenderOffScreen -PixelStreamingEncoderMaxBitrate=15000000 -ResX 1280 -ResY 720 -PixelStreamingEncoderMinQP=25 -PixelStreamingEncoderMultipass=QUARTER -PixelStreamingWebRTCMaxFps=60"; - std::wstring cmd_ws = std::wstring(cmd.begin(), cmd.end()); - wchar_t* cmd_w = const_cast(cmd_ws.c_str()); - - // creating process - STARTUPINFO startupInfo = { sizeof(startupInfo) }; - PROCESS_INFORMATION processInfo; + PROCESS_INFORMATION appProcInfo; + //PROCESS_INFORMATION nodeProcInfo; - if (CreateProcess(path_cw, cmd_w, NULL, NULL, TRUE, 0, NULL, NULL, &startupInfo, &processInfo)) - { - // bind process close listen - std::thread([processInfo]() - { - WaitForSingleObject(processInfo.hProcess, INFINITE); - CloseHandle(processInfo.hProcess); - CloseHandle(processInfo.hThread); - }).detach(); - - - sessId = hash6(user_id); - - // create session - sessManager.add( - session( - GetProcessId(processInfo.hProcess), - sessId, - ip + std::to_string(sess_port), - user_ip - )); - - std::cout << "user(" << thisUserNum << ") created session (id: " << sessId << ")" << std::endl; - - if (sessManager.getById(sessId, &sessCur)) - { - sessCur->addUser(user(user_id)); - } - - buffer.clear(); - boost::beast::ostream(buffer) - << (std::string("{\"message\" : \"NEW_SESS\", \"content\" : \"") + std::to_string(sessId) + "\"}"); - ws.write(buffer.data()); - } - else + // create app process + if (!CreateProc(appPath, appPath + " " + appArgs + std::to_string(sessStreamPort), &appProcInfo)) { std::cout << "CreateProcess failed (" << GetLastError() << ")." << std::endl; + continue; + } + + // bind app process close listen + std::thread([appProcInfo]() + { + WaitForSingleObject(appProcInfo.hProcess, INFINITE); + CloseHandle(appProcInfo.hProcess); + CloseHandle(appProcInfo.hThread); + }).detach(); + + //std::string nodeArgs = nodePath + " " + nodeFilePath + " " + // + std::to_string(sessHttpPort) + " " + // + std::to_string(sessStreamPort); + + //// create node js server proc + //if (!CreateProc(nodePath, nodePath + " " + nodeFilePath + " " + // + std::to_string(sessHttpPort) + " " + // + std::to_string(sessStreamPort), &nodeProcInfo)) + //{ + // std::cout << "CreateProcess failed (" << GetLastError() << ")." << std::endl; + // continue; + //} + + ////bind node js close listen + //std::thread([nodeProcInfo]() + // { + // WaitForSingleObject(nodeProcInfo.hProcess, INFINITE); + // CloseHandle(nodeProcInfo.hProcess); + // CloseHandle(nodeProcInfo.hThread); + // }).detach(); + + sessId = hash6(user_id); + + // create session + sessManager.add( + session( + sessId, + ip + std::to_string(sess_port), + user_ip, + sessHttpPort + )); + + if (sessManager.getById(sessId, &sessCur)) + { + // add user + sessCur->addUser(user(user_id)); + + // add process ids + sessCur->addProcId(GetProcessId(appProcInfo.hProcess)); + //sessCur->addProcId(GetProcessId(nodeProcInfo.hProcess)); } + std::cout << "user(" << thisUserNum << ") created session (id: " << sessId << ")" << std::endl; + + // send respond + buffer.clear(); + boost::beast::ostream(buffer) + << (std::string("{\"message\" : \"SESS_CREATION\", \"id\" : \"") + + std::to_string(sessId) + "\", \"port\" : \"" + std::to_string(sessHttpPort) + "\"}"); + ws.write(buffer.data()); } - else if (message == "EXIS_SESS") + else if (message == "SESS_CONNECT") { + std::cout << "sess_connect" << std::endl; // read session id try { @@ -315,7 +411,7 @@ int main(int argc, char* argv[]) buffer.clear(); boost::beast::ostream(buffer) - << (std::string("{\"message\" : \"EXIS_SESS\", \"content\" : \"") + std::to_string(sessCur->getId()) + "\"}"); + << (std::string("{\"message\" : \"SESS_CONNECT\", \"content\" : \"") + std::to_string(sessCur->getPort()) + "\"}"); ws.write(buffer.data()); } else @@ -342,7 +438,9 @@ int main(int argc, char* argv[]) if (!sessCur->getUsersCount()) { std::cout << "destroy session (id: " << sessCur->getId() << ")" << std::endl; - EndProc(sessCur->getProcId()); + std::vector procIds(sessCur->getProcIds()); + for (auto& id : procIds) + EndProc(id); sessManager.remove(sessId); } } diff --git a/ServerPixel/session.h b/ServerPixel/session.h index 31d6145..d9e7870 100644 --- a/ServerPixel/session.h +++ b/ServerPixel/session.h @@ -7,20 +7,21 @@ class session { private: - DWORD procId = 0; + std::vector procIds; uint32_t sessId = 0; + uint16_t port = 0; std::string sessLink; std::vector users; std::string ownerIp; public: session() {} - session(DWORD procId, uint32_t sessId, std::string sessLink, std::string ownerIp) + session(uint32_t sessId, std::string sessLink, std::string ownerIp, uint16_t port) { - this->procId = procId; this->sessId = sessId; this->sessLink = sessLink; this->ownerIp = ownerIp; + this->port = port; } void addUser(user u) { @@ -34,7 +35,9 @@ public: } inline size_t getUsersCount() const { return users.size(); } inline const uint32_t& getId() const { return sessId; } - inline const DWORD& getProcId() const { return procId; } + inline const std::vector& getProcIds() const { return procIds; } + inline void addProcId(DWORD procId) { procIds.push_back(procId); } inline const std::string& getOwnerIp() const { return ownerIp; } + inline const uint16_t getPort() const { return port; } }; diff --git a/ServerPixel/sessionManager.h b/ServerPixel/sessionManager.h index d70bb79..3ca88a6 100644 --- a/ServerPixel/sessionManager.h +++ b/ServerPixel/sessionManager.h @@ -1,5 +1,6 @@ #include "session.h" #include +#include #pragma once class sessionManager @@ -48,5 +49,16 @@ public: { return limit == sessions.size(); } + + uint16_t getMinPort() + { + if (!sessions.size()) + return 0; + std::vector ports; + for (auto& s : sessions) + ports.push_back(s.getPort()); + std::sort(ports.begin(), ports.end()); + return *(ports.begin()); + } };