#ifndef GROUP_UWS_H #define GROUP_UWS_H #include "WebSocket.h" #include "HTTPSocket.h" #include "Extensions.h" #include #include namespace uWS { enum ListenOptions { TRANSFERS }; struct Hub; template struct WIN32_EXPORT Group : private uS::NodeData { protected: friend struct Hub; friend struct WebSocket; friend struct HttpSocket; friend struct HttpSocket; std::function *, HttpRequest)> connectionHandler; std::function *)> transferHandler; std::function *, char *message, size_t length, OpCode opCode)> messageHandler; std::function *, int code, char *message, size_t length)> disconnectionHandler; std::function *, char *, size_t)> pingHandler; std::function *, char *, size_t)> pongHandler; std::function *)> httpConnectionHandler; std::function httpRequestHandler; std::function httpDataHandler; std::function httpCancelledRequestHandler; std::function *)> httpDisconnectionHandler; std::function *, HttpRequest)> httpUpgradeHandler; using errorType = typename std::conditional::type; std::function errorHandler; unsigned int maxPayload; Hub *hub; int extensionOptions; uS::Timer *timer = nullptr, *httpTimer = nullptr; std::string userPingMessage; std::stack iterators; // todo: cannot be named user, collides with parent! void *userData = nullptr; static void timerCallback(uS::Timer *timer); WebSocket *webSocketHead = nullptr; HttpSocket *httpSocketHead = nullptr; void addWebSocket(WebSocket *webSocket); void removeWebSocket(WebSocket *webSocket); // todo: remove these, template void addHttpSocket(HttpSocket *httpSocket); void removeHttpSocket(HttpSocket *httpSocket); Group(int extensionOptions, unsigned int maxPayload, Hub *hub, uS::NodeData *nodeData); void stopListening(); public: void onConnection(std::function *, HttpRequest)> handler); void onTransfer(std::function *)> handler); void onMessage(std::function *, char *, size_t, OpCode)> handler); void onDisconnection(std::function *, int code, char *message, size_t length)> handler); void onPing(std::function *, char *, size_t)> handler); void onPong(std::function *, char *, size_t)> handler); void onError(std::function handler); void onHttpConnection(std::function *)> handler); void onHttpRequest(std::function handler); void onHttpData(std::function handler); void onHttpDisconnection(std::function *)> handler); void onCancelledHttpRequest(std::function handler); void onHttpUpgrade(std::function *, HttpRequest)> handler); // Thread safe void broadcast(const char *message, size_t length, OpCode opCode); void setUserData(void *user); void *getUserData(); // Not thread safe void terminate(); void close(int code = 1000, char *message = nullptr, size_t length = 0); void startAutoPing(int intervalMs, std::string userMessage = ""); // same as listen(TRANSFERS), backwards compatible API for now void addAsync() { if (!async) { NodeData::addAsync(); } } void listen(ListenOptions listenOptions) { if (listenOptions == TRANSFERS && !async) { addAsync(); } } template void forEach(const F &cb) { uS::Poll *iterator = webSocketHead; iterators.push(iterator); while (iterator) { uS::Poll *lastIterator = iterator; cb((WebSocket *) iterator); iterator = iterators.top(); if (lastIterator == iterator) { iterator = ((uS::Socket *) iterator)->next; iterators.top() = iterator; } } iterators.pop(); } // duplicated code for now! template void forEachHttpSocket(const F &cb) { uS::Poll *iterator = httpSocketHead; iterators.push(iterator); while (iterator) { uS::Poll *lastIterator = iterator; cb((HttpSocket *) iterator); iterator = iterators.top(); if (lastIterator == iterator) { iterator = ((uS::Socket *) iterator)->next; iterators.top() = iterator; } } iterators.pop(); } static Group *from(uS::Socket *s) { return static_cast *>(s->getNodeData()); } }; } #endif // GROUP_UWS_H