diff --git a/misc/main.cpp b/misc/main.cpp index 6b5eb77..e95c99d 100644 --- a/misc/main.cpp +++ b/misc/main.cpp @@ -11,6 +11,8 @@ int main(int argc, char **argv) { res->end("Hello HTTP!"); }).ws("/*", [](auto *ws, auto *req) { std::cout << "WebSocket conntected to URL: " << req->getUrl() << std::endl; + }, [](auto *ws, std::string_view message) { + ws->send(message); }).listen(3000, [](auto *token) { if (token) { std::cout << "Listening on port " << 3000 << std::endl; diff --git a/src/App.h b/src/App.h index 2da2581..c4edf20 100644 --- a/src/App.h +++ b/src/App.h @@ -52,10 +52,12 @@ public: } // this method creates a new websocket context and attaches it to a path - TemplatedApp &ws(std::string pattern, std::function connectHandler) { + TemplatedApp &ws(std::string pattern, std::function connectHandler, std::function *, std::string_view)> messageHandler) { // init the websocket context here! uWS::WebSocketContext *webSocketContext = uWS::WebSocketContext::create(uWS::Loop::defaultLoop(), (typename StaticDispatch::SOCKET_CONTEXT_TYPE *) httpContext); + webSocketContext->getExt()->messageHandler = messageHandler; + return get(pattern, [webSocketContext, this, connectHandler](auto *res, auto *req) { std::string_view secWebSocketKey = req->getHeader("sec-websocket-key"); @@ -77,7 +79,7 @@ public: // rely on http context data // todo: sizeof websocket - WebSocket *webSocket = (WebSocket *) StaticDispatch::static_dispatch(us_ssl_socket_context_adopt_socket, us_socket_context_adopt_socket)( + WebSocket *webSocket = (WebSocket *) StaticDispatch::static_dispatch(us_ssl_socket_context_adopt_socket, us_socket_context_adopt_socket)( (typename StaticDispatch::SOCKET_CONTEXT_TYPE *) webSocketContext, (typename StaticDispatch::SOCKET_TYPE *) res, 150); webSocket->init(); diff --git a/src/WebSocket.h b/src/WebSocket.h index e04cbcf..c033023 100644 --- a/src/WebSocket.h +++ b/src/WebSocket.h @@ -3,13 +3,34 @@ #include "WebSocketData.h" +#include "WebSocketProtocol.h" + +#include + namespace uWS { -template +template struct WebSocket { private: public: + + void send(std::string_view message) { + + // this path should use AsyncSocket with cork and everything + + // format the response + char buf[100]; + int writeLength = WebSocketProtocol>::formatMessage(buf, message.data(), message.length(), uWS::OpCode::TEXT, message.length(), false); + + + us_socket_write((us_socket *) this, buf, writeLength, false); + + + + } + + // absolutely not public! void init() { // construct us diff --git a/src/WebSocketContext.h b/src/WebSocketContext.h index 8ecfd45..9d22d1a 100644 --- a/src/WebSocketContext.h +++ b/src/WebSocketContext.h @@ -13,6 +13,7 @@ namespace uWS { template struct WebSocketContext : StaticDispatch { + template friend struct TemplatedApp; private: using SOCKET_CONTEXT_TYPE = typename StaticDispatch::SOCKET_CONTEXT_TYPE; using SOCKET_TYPE = typename StaticDispatch::SOCKET_TYPE; @@ -23,6 +24,10 @@ private: return (SOCKET_CONTEXT_TYPE *) this; } + WebSocketContextData *getExt() { + return (WebSocketContextData *) us_socket_context_ext((SOCKET_CONTEXT_TYPE *) this); + } + // I don't even.. merge this with the context itself! template struct WebSocketProtcolImplementation { @@ -37,16 +42,16 @@ private: static bool handleFragment(char *data, size_t length, unsigned int remainingBytes, int opCode, bool fin, uWS::WebSocketState *webSocketState, void *s) { - // this path should use AsyncSocket with cork and everything + // this is maybe not the most elegant but who cares + WebSocketContextData *webSocketContextData = (WebSocketContextData *) us_socket_context_ext(us_socket_get_context((us_socket *) s)); - // format the response - char buf[100]; - int writeLength = WebSocketProtocol>::formatMessage(buf, data, length, (uWS::OpCode) opCode, length, false); - us_socket_write((SOCKET_TYPE *) s, buf, writeLength, false); + // emit message + webSocketContextData->messageHandler((WebSocket *) s, std::string_view(data, length)); + + // the only thing here to check is probably closed // why does it not do anything immediately on true? return false; - } static bool refusePayloadLength(uint64_t length, uWS::WebSocketState *wState) { diff --git a/src/WebSocketContextData.h b/src/WebSocketContextData.h index d12fc74..45b8aaf 100644 --- a/src/WebSocketContextData.h +++ b/src/WebSocketContextData.h @@ -1,11 +1,17 @@ #ifndef WEBSOCKETCONTEXTDATA_H #define WEBSOCKETCONTEXTDATA_H +#include +#include + namespace uWS { +template struct WebSocket; + template struct WebSocketContextData { + std::function *, std::string_view)> messageHandler; }; }