diff options
| author | Per Larsson <[email protected]> | 2022-02-21 15:14:11 +0100 |
|---|---|---|
| committer | Per Larsson <[email protected]> | 2022-02-21 15:14:11 +0100 |
| commit | db1c9605e3afbaf86f4231ba4eb7976d896f286b (patch) | |
| tree | 54b451da4247c69575ff1a05ed006ecef3905c85 /zenserver | |
| parent | If open(O_CREAT) is used then a file mode must be given (diff) | |
| parent | Removed optional offset for GetView. (diff) | |
| download | zen-db1c9605e3afbaf86f4231ba4eb7976d896f286b.tar.xz zen-db1c9605e3afbaf86f4231ba4eb7976d896f286b.zip | |
Initial support for websockets.
Diffstat (limited to 'zenserver')
| -rw-r--r-- | zenserver/config.cpp | 14 | ||||
| -rw-r--r-- | zenserver/config.h | 24 | ||||
| -rw-r--r-- | zenserver/testing/httptest.cpp | 34 | ||||
| -rw-r--r-- | zenserver/testing/httptest.h | 6 | ||||
| -rw-r--r-- | zenserver/zenserver.cpp | 21 |
5 files changed, 87 insertions, 12 deletions
diff --git a/zenserver/config.cpp b/zenserver/config.cpp index cb6d5ea6d..bcacc16c0 100644 --- a/zenserver/config.cpp +++ b/zenserver/config.cpp @@ -193,6 +193,20 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions) cxxopts::value<int>(ServerOptions.BasePort)->default_value("1337"), "<port number>"); + options.add_option("network", + "", + "websocket-port", + "Websocket server port", + cxxopts::value<int>(ServerOptions.WebSocketPort)->default_value("0"), + "<port number>"); + + options.add_option("network", + "", + "websocket-threads", + "Number of websocket I/O thread(s) (0 == hardware concurrency)", + cxxopts::value<int>(ServerOptions.WebSocketThreads)->default_value("0"), + ""); + #if ZEN_ENABLE_MESH options.add_option("network", "m", diff --git a/zenserver/config.h b/zenserver/config.h index 69e65498c..fd569bdb1 100644 --- a/zenserver/config.h +++ b/zenserver/config.h @@ -87,17 +87,19 @@ struct ZenServerOptions { ZenUpstreamCacheConfig UpstreamCacheConfig; ZenGcConfig GcConfig; - std::filesystem::path DataDir; // Root directory for state (used for testing) - std::filesystem::path ContentDir; // Root directory for serving frontend content (experimental) - std::filesystem::path AbsLogFile; // Absolute path to main log file - std::filesystem::path ConfigFile; // Path to Lua config file - std::string ChildId; // Id assigned by parent process (used for lifetime management) - std::string LogId; // Id for tagging log output - std::string HttpServerClass; // Choice of HTTP server implementation - std::string EncryptionKey; // 256 bit AES encryption key - std::string EncryptionIV; // 128 bit AES initialization vector - int BasePort = 1337; // Service listen port (used for both UDP and TCP) - int OwnerPid = 0; // Parent process id (zero for standalone) + std::filesystem::path DataDir; // Root directory for state (used for testing) + std::filesystem::path ContentDir; // Root directory for serving frontend content (experimental) + std::filesystem::path AbsLogFile; // Absolute path to main log file + std::filesystem::path ConfigFile; // Path to Lua config file + std::string ChildId; // Id assigned by parent process (used for lifetime management) + std::string LogId; // Id for tagging log output + std::string HttpServerClass; // Choice of HTTP server implementation + std::string EncryptionKey; // 256 bit AES encryption key + std::string EncryptionIV; // 128 bit AES initialization vector + int BasePort = 1337; // Service listen port (used for both UDP and TCP) + int OwnerPid = 0; // Parent process id (zero for standalone) + int WebSocketPort = 0; // Web socket port (Zero = disabled) + int WebSocketThreads = 0; bool InstallService = false; // Flag used to initiate service install (temporary) bool UninstallService = false; // Flag used to initiate service uninstall (temporary) bool IsDebug = false; diff --git a/zenserver/testing/httptest.cpp b/zenserver/testing/httptest.cpp index 230d5d6c5..10b69c469 100644 --- a/zenserver/testing/httptest.cpp +++ b/zenserver/testing/httptest.cpp @@ -8,6 +8,8 @@ namespace zen { +using namespace std::literals; + HttpTestingService::HttpTestingService() { m_Router.RegisterRoute( @@ -136,6 +138,38 @@ HttpTestingService::HandlePackageRequest(HttpServerRequest& HttpServiceRequest) return (InsertResult.first->second = new PackageHandler(*this, RequestId)).Get(); } +void +HttpTestingService::RegisterHandlers(WebSocketServer& Server) +{ + Server.RegisterRequestHandler("SayHello"sv, *this); +} + +bool +HttpTestingService::HandleRequest(const WebSocketMessage& RequestMsg) +{ + CbObjectView Request = RequestMsg.Body().GetObject(); + + std::string_view Method = Request["Method"].AsString(); + + if (Method != "SayHello"sv) + { + return false; + } + + CbObjectWriter Response; + Response.AddString("Result"sv, "Hello Friend!!"); + + WebSocketMessage ResponseMsg; + ResponseMsg.SetMessageType(WebSocketMessageType::kResponse); + ResponseMsg.SetCorrelationId(RequestMsg.CorrelationId()); + ResponseMsg.SetSocketId(RequestMsg.SocketId()); + ResponseMsg.SetBody(Response.Save()); + + SocketServer().SendResponse(std::move(ResponseMsg)); + + return true; +} + ////////////////////////////////////////////////////////////////////////// HttpTestingService::PackageHandler::PackageHandler(HttpTestingService& Svc, uint32_t RequestId) : m_Svc(Svc), m_RequestId(RequestId) diff --git a/zenserver/testing/httptest.h b/zenserver/testing/httptest.h index f7ea0c31c..57d2d63f3 100644 --- a/zenserver/testing/httptest.h +++ b/zenserver/testing/httptest.h @@ -5,6 +5,7 @@ #include <zencore/logging.h> #include <zencore/stats.h> #include <zenhttp/httpserver.h> +#include <zenhttp/websocket.h> #include <atomic> @@ -13,7 +14,7 @@ namespace zen { /** * Test service to facilitate testing the HTTP framework and client interactions */ -class HttpTestingService : public HttpService +class HttpTestingService : public HttpService, public WebSocketService { public: HttpTestingService(); @@ -40,6 +41,9 @@ public: }; private: + virtual void RegisterHandlers(WebSocketServer& Server) override; + virtual bool HandleRequest(const WebSocketMessage& Request) override; + HttpRequestRouter m_Router; std::atomic<uint32_t> m_Counter{0}; metrics::OperationTiming m_TimingStats; diff --git a/zenserver/zenserver.cpp b/zenserver/zenserver.cpp index ea0f52db2..78a62e202 100644 --- a/zenserver/zenserver.cpp +++ b/zenserver/zenserver.cpp @@ -15,6 +15,7 @@ #include <zencore/timer.h> #include <zencore/trace.h> #include <zenhttp/httpserver.h> +#include <zenhttp/websocket.h> #include <zenstore/basicfile.h> #include <zenstore/cas.h> #include <zenstore/cidstore.h> @@ -204,6 +205,15 @@ public: m_Http = zen::CreateHttpServer(ServerOptions.HttpServerClass); int EffectiveBasePort = m_Http->Initialize(ServerOptions.BasePort); + if (ServerOptions.WebSocketPort != 0) + { + const uint32 ThreadCount = + ServerOptions.WebSocketThreads > 0 ? uint32_t(ServerOptions.WebSocketThreads) : std::thread::hardware_concurrency(); + + m_WebSocket = zen::WebSocketServer::Create( + {.Port = gsl::narrow<uint16_t>(ServerOptions.WebSocketPort), .ThreadCount = Max(ThreadCount, uint32_t(16))}); + } + // Setup authentication manager { std::string EncryptionKey = ServerOptions.EncryptionKey; @@ -304,6 +314,11 @@ public: m_Http->RegisterService(m_TestingService); m_Http->RegisterService(m_AdminService); + if (m_WebSocket) + { + m_WebSocket->RegisterService(m_TestingService); + } + if (m_HttpProjectService) { m_Http->RegisterService(*m_HttpProjectService); @@ -396,6 +411,11 @@ public: OnReady(); + if (m_WebSocket) + { + m_WebSocket->Run(); + } + m_Http->Run(IsInteractiveMode); SetNewState(kShuttingDown); @@ -559,6 +579,7 @@ private: } zen::Ref<zen::HttpServer> m_Http; + std::unique_ptr<zen::WebSocketServer> m_WebSocket; std::unique_ptr<zen::AuthMgr> m_AuthMgr; std::unique_ptr<zen::HttpAuthService> m_AuthService; zen::HttpStatusService m_StatusService; |