Add a few more events
This commit is contained in:
+24
-18
@@ -1,29 +1,35 @@
|
|||||||
#include "App.h"
|
#include "App.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
/* ws->getUserData returns one of these */
|
||||||
|
struct PerSocketData {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/* Very simple WebSocket echo server */
|
/* Very simple WebSocket echo server */
|
||||||
uWS::App().ws<void>("/*", {
|
uWS::App().ws<PerSocketData>("/*", {
|
||||||
/*.compression = */true,
|
/* Settings */
|
||||||
/*.maxPayloadLength*/
|
.compression = true,
|
||||||
|
.maxPayloadLength = 16 * 1024,
|
||||||
/*.open = */[](auto *ws, auto *req) {
|
/* Handlers */
|
||||||
|
.open = [](auto *ws, auto *req) {
|
||||||
|
|
||||||
},
|
},
|
||||||
/*.message = */[](auto *ws, std::string_view message, uWS::OpCode opCode) {
|
.message = [](auto *ws, std::string_view message, uWS::OpCode opCode) {
|
||||||
ws->send(message, opCode);
|
ws->send(message, opCode);
|
||||||
|
},
|
||||||
|
.drain = [](auto *ws) {
|
||||||
|
/* Check getBufferedAmount here */
|
||||||
|
},
|
||||||
|
.ping = [](auto *ws) {
|
||||||
|
|
||||||
|
},
|
||||||
|
.pong = [](auto *ws) {
|
||||||
|
|
||||||
|
},
|
||||||
|
.close = [](auto *ws, int code, std::string_view message) {
|
||||||
|
|
||||||
}
|
}
|
||||||
/*.drain = []() {
|
|
||||||
|
|
||||||
},
|
|
||||||
.ping = []() {
|
|
||||||
|
|
||||||
},
|
|
||||||
.pong = []() {
|
|
||||||
|
|
||||||
},
|
|
||||||
.close = []() {
|
|
||||||
|
|
||||||
}*/
|
|
||||||
}).listen(9001, [](auto *token) {
|
}).listen(9001, [](auto *token) {
|
||||||
if (token) {
|
if (token) {
|
||||||
std::cout << "Listening on port " << 9001 << std::endl;
|
std::cout << "Listening on port " << 9001 << std::endl;
|
||||||
|
|||||||
+29
-22
@@ -6,7 +6,7 @@
|
|||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
struct PerSocketData {
|
struct PerSocketData {
|
||||||
|
int hello;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*const char *key_file_name;
|
/*const char *key_file_name;
|
||||||
@@ -14,34 +14,41 @@ int main(int argc, char **argv) {
|
|||||||
const char *passphrase;
|
const char *passphrase;
|
||||||
const char *dh_params_file_name;*/
|
const char *dh_params_file_name;*/
|
||||||
|
|
||||||
uWS::SSLApp({
|
uWS::App(/*SSLApp({
|
||||||
"/home/alexhultman/key.pem",
|
"/home/alexhultman/key.pem",
|
||||||
"/home/alexhultman/cert.pem",
|
"/home/alexhultman/cert.pem",
|
||||||
"1234"
|
"1234"
|
||||||
}).get("/hello", [](auto *res, auto *req) {
|
}*/).get("/hello", [](auto *res, auto *req) {
|
||||||
res->end("Hello HTTP!");
|
res->end("Hello HTTP!");
|
||||||
}).ws<void>("/*", {
|
}).ws<PerSocketData>("/*", {
|
||||||
/*.compression = */true,
|
/* Settings */
|
||||||
/*.maxPayloadLength*/
|
.compression = true,
|
||||||
|
.maxPayloadLength = 16 * 1024,
|
||||||
/*.open = */[](auto *ws, auto *req) {
|
/* Handlers */
|
||||||
|
.open = [](auto *ws, auto *req) {
|
||||||
|
std::cout << "WebSocket connected" << std::endl;
|
||||||
|
/* Access per socket data */
|
||||||
|
/*PerSocketData *perSocketData = */ws->getUserData();
|
||||||
|
/*perSocketData->hello = 13;*/
|
||||||
},
|
},
|
||||||
/*.message = */[](auto *ws, std::string_view message, uWS::OpCode opCode) {
|
.message = [](auto *ws, std::string_view message, uWS::OpCode opCode) {
|
||||||
ws->send(message, opCode);
|
ws->send(message, opCode);
|
||||||
|
},
|
||||||
|
.drain = [](auto *ws) {
|
||||||
|
std::cout << "Drainage: " << ws->getBufferedAmount() << std::endl;
|
||||||
|
},
|
||||||
|
.ping = [](auto *ws) {
|
||||||
|
std::cout << "Ping" << std::endl;
|
||||||
|
},
|
||||||
|
.pong = [](auto *ws) {
|
||||||
|
std::cout << "Pong" << std::endl;
|
||||||
|
},
|
||||||
|
.close = [](auto *ws, int code, std::string_view message) {
|
||||||
|
std::cout << "WebSocket disconnected: " << code << "[" << message << "]" << std::endl;
|
||||||
|
/* Access per socket data */
|
||||||
|
//PerSocketData *perSocketData = ws->getUserData<PerSocketData>();
|
||||||
|
//std::cout << "OK per socket data: " << (perSocketData->hello == 13) << std::endl;
|
||||||
}
|
}
|
||||||
/*.drain = []() {
|
|
||||||
|
|
||||||
},
|
|
||||||
.ping = []() {
|
|
||||||
|
|
||||||
},
|
|
||||||
.pong = []() {
|
|
||||||
|
|
||||||
},
|
|
||||||
.close = []() {
|
|
||||||
|
|
||||||
}*/
|
|
||||||
}).listen(9001, [](auto *token) {
|
}).listen(9001, [](auto *token) {
|
||||||
if (token) {
|
if (token) {
|
||||||
std::cout << "Listening on port " << 3000 << std::endl;
|
std::cout << "Listening on port " << 3000 << std::endl;
|
||||||
|
|||||||
@@ -54,8 +54,13 @@ public:
|
|||||||
|
|
||||||
struct WebSocketBehavior {
|
struct WebSocketBehavior {
|
||||||
bool compression = false;
|
bool compression = false;
|
||||||
|
int maxPayloadLength = 16 * 1024;
|
||||||
std::function<void(uWS::WebSocket<SSL, true> *, HttpRequest *)> open = nullptr;
|
std::function<void(uWS::WebSocket<SSL, true> *, HttpRequest *)> open = nullptr;
|
||||||
std::function<void(uWS::WebSocket<SSL, true> *, std::string_view, uWS::OpCode)> message = nullptr;
|
std::function<void(uWS::WebSocket<SSL, true> *, std::string_view, uWS::OpCode)> message = nullptr;
|
||||||
|
std::function<void(uWS::WebSocket<SSL, true> *)> drain = nullptr;
|
||||||
|
std::function<void(uWS::WebSocket<SSL, true> *)> ping = nullptr;
|
||||||
|
std::function<void(uWS::WebSocket<SSL, true> *)> pong = nullptr;
|
||||||
|
std::function<void(uWS::WebSocket<SSL, true> *, int, std::string_view)> close = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class UserData>
|
template <class UserData>
|
||||||
@@ -75,6 +80,8 @@ public:
|
|||||||
|
|
||||||
/* Copy all handlers */
|
/* Copy all handlers */
|
||||||
webSocketContext->getExt()->messageHandler = behavior.message;
|
webSocketContext->getExt()->messageHandler = behavior.message;
|
||||||
|
webSocketContext->getExt()->drainHandler = behavior.drain;
|
||||||
|
webSocketContext->getExt()->closeHandler = behavior.close;
|
||||||
|
|
||||||
return get(pattern, [webSocketContext, this, behavior](auto *res, auto *req) {
|
return get(pattern, [webSocketContext, this, behavior](auto *res, auto *req) {
|
||||||
/* If we have this header set, it's a websocket */
|
/* If we have this header set, it's a websocket */
|
||||||
@@ -125,8 +132,6 @@ public:
|
|||||||
behavior.open(webSocket, req);
|
behavior.open(webSocket, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "oh hey!" << std::endl;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* For now we do not support having HTTP and websocket routes on the same URL */
|
/* For now we do not support having HTTP and websocket routes on the same URL */
|
||||||
res->close();
|
res->close();
|
||||||
|
|||||||
@@ -95,6 +95,13 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns the user space backpressure. */
|
||||||
|
int getBufferedAmount() {
|
||||||
|
AsyncSocketData<SSL> *asyncSocketData = (AsyncSocketData<SSL> *) getExt();
|
||||||
|
|
||||||
|
return asyncSocketData->buffer.size();
|
||||||
|
}
|
||||||
|
|
||||||
/* Write in three levels of prioritization: cork-buffer, syscall, socket-buffer. Always drain if possible.
|
/* Write in three levels of prioritization: cork-buffer, syscall, socket-buffer. Always drain if possible.
|
||||||
* Returns pair of bytes written (anywhere) and wheter or not this call resulted in the polling for
|
* Returns pair of bytes written (anywhere) and wheter or not this call resulted in the polling for
|
||||||
* writable (or we are in a state that implies polling for writable). */
|
* writable (or we are in a state that implies polling for writable). */
|
||||||
|
|||||||
@@ -39,6 +39,17 @@ private:
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/* Returns pointer to the per socket user data */
|
||||||
|
//template <typename K>
|
||||||
|
void *getUserData() {
|
||||||
|
WebSocketData *webSocketData = (WebSocketData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this);
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See AsyncSocket */
|
||||||
|
using Super::getBufferedAmount;
|
||||||
|
|
||||||
/* Send or buffer a WebSocket frame, compressed or not. Returns false on increased user space backpressure. */
|
/* Send or buffer a WebSocket frame, compressed or not. Returns false on increased user space backpressure. */
|
||||||
bool send(std::string_view message, uWS::OpCode opCode = uWS::OpCode::BINARY, bool compress = false) {
|
bool send(std::string_view message, uWS::OpCode opCode = uWS::OpCode::BINARY, bool compress = false) {
|
||||||
/* Transform the message to compressed domain if requested */
|
/* Transform the message to compressed domain if requested */
|
||||||
|
|||||||
+10
-6
@@ -47,7 +47,7 @@ private:
|
|||||||
static bool setCompressed(uWS::WebSocketState<isServer> *wState, void *s) {
|
static bool setCompressed(uWS::WebSocketState<isServer> *wState, void *s) {
|
||||||
//WebSocketData *webSocketData = (WebSocketData *) us_socket_ext((us_socket *) s);
|
//WebSocketData *webSocketData = (WebSocketData *) us_socket_ext((us_socket *) s);
|
||||||
|
|
||||||
std::cout << "set compressed" << std::endl;
|
//std::cout << "set compressed" << std::endl;
|
||||||
|
|
||||||
WebSocketData *webSocketData = (WebSocketData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) s);
|
WebSocketData *webSocketData = (WebSocketData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) s);
|
||||||
|
|
||||||
@@ -264,14 +264,13 @@ private:
|
|||||||
|
|
||||||
std::cout << "close!" << std::endl;
|
std::cout << "close!" << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Handle WebSocket data streams */
|
/* Handle WebSocket data streams */
|
||||||
static_dispatch(us_ssl_socket_context_on_data, us_socket_context_on_data)(getSocketContext(), [](auto *s, char *data, int length) {
|
static_dispatch(us_ssl_socket_context_on_data, us_socket_context_on_data)(getSocketContext(), [](auto *s, char *data, int length) {
|
||||||
|
|
||||||
//std::cout << "websocket data" << std::endl;
|
|
||||||
|
|
||||||
/* We always cork on data */
|
/* We always cork on data */
|
||||||
AsyncSocket<SSL> *webSocket = (AsyncSocket<SSL> *) s;
|
AsyncSocket<SSL> *webSocket = (AsyncSocket<SSL> *) s;
|
||||||
webSocket->cork();
|
webSocket->cork();
|
||||||
@@ -279,13 +278,14 @@ private:
|
|||||||
/* We need the websocket data */
|
/* We need the websocket data */
|
||||||
WebSocketData *wsState = (WebSocketData *) (static_dispatch(us_ssl_socket_ext, us_socket_ext)(s));
|
WebSocketData *wsState = (WebSocketData *) (static_dispatch(us_ssl_socket_ext, us_socket_ext)(s));
|
||||||
|
|
||||||
// this parser requires almost no time -> 215k req/sec of 215k possible
|
/* This parser has virtually no overhead */
|
||||||
uWS::WebSocketProtocol<isServer, WebSocketContext<SSL, isServer>>::consume(data, length, wsState, s);
|
uWS::WebSocketProtocol<isServer, WebSocketContext<SSL, isServer>>::consume(data, length, wsState, s);
|
||||||
|
|
||||||
|
|
||||||
// todo: check for failures here just like for HTTP
|
// todo: check for failures here just like for HTTP
|
||||||
webSocket->uncork();
|
webSocket->uncork();
|
||||||
|
|
||||||
|
// I guess we need to check drain here
|
||||||
|
|
||||||
// are we shutdown?
|
// are we shutdown?
|
||||||
if (wsState->isShuttingDown) {
|
if (wsState->isShuttingDown) {
|
||||||
webSocket->shutdown();
|
webSocket->shutdown();
|
||||||
@@ -306,6 +306,10 @@ private:
|
|||||||
// check for failures and shutdown just like in data event
|
// check for failures and shutdown just like in data event
|
||||||
webSocket->write(nullptr, 0); // drainage - also check for shutdown!
|
webSocket->write(nullptr, 0); // drainage - also check for shutdown!
|
||||||
|
|
||||||
|
// call drain here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,10 @@ template <bool, bool> struct WebSocket;
|
|||||||
|
|
||||||
template <bool SSL>
|
template <bool SSL>
|
||||||
struct WebSocketContextData {
|
struct WebSocketContextData {
|
||||||
|
/* The callbacks for this context */
|
||||||
std::function<void(WebSocket<SSL, true> *, std::string_view, uWS::OpCode)> messageHandler;
|
std::function<void(WebSocket<SSL, true> *, std::string_view, uWS::OpCode)> messageHandler;
|
||||||
|
std::function<void(uWS::WebSocket<SSL, true> *)> drainHandler;
|
||||||
|
std::function<void(uWS::WebSocket<SSL, true> *, int, std::string_view)> closeHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user