Fix up websocket close events
This commit is contained in:
+1
-1
@@ -12,7 +12,7 @@ int main(int argc, char **argv) {
|
|||||||
int hello;
|
int hello;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto app = uWS::SSLApp({
|
auto app = uWS::/*SSL*/App({
|
||||||
.key_file_name = "/home/alexhultman/key.pem",
|
.key_file_name = "/home/alexhultman/key.pem",
|
||||||
.cert_file_name = "/home/alexhultman/cert.pem",
|
.cert_file_name = "/home/alexhultman/cert.pem",
|
||||||
.passphrase = "1234"
|
.passphrase = "1234"
|
||||||
|
|||||||
+17
-13
@@ -89,29 +89,33 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Emit close event, start passive timeout */
|
/* Send websocket close frame, emit close event, send FIN if successful */
|
||||||
void close(int code, std::string_view message = {}) {
|
void close(int code, std::string_view message = {}) {
|
||||||
static const int MAX_CLOSE_PAYLOAD = 123;
|
/* Check if we already called this one */
|
||||||
int length = std::min<size_t>(MAX_CLOSE_PAYLOAD, message.length());
|
|
||||||
|
|
||||||
// todo: here we start a timeout and handle it accordingly in the timeout handler
|
|
||||||
|
|
||||||
WebSocketData *webSocketData = (WebSocketData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this);
|
WebSocketData *webSocketData = (WebSocketData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this);
|
||||||
|
if (webSocketData->isShuttingDown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* We postpone any FIN sending to either drainage or uncorking */
|
/* We postpone any FIN sending to either drainage or uncorking */
|
||||||
webSocketData->isShuttingDown = true;
|
webSocketData->isShuttingDown = true;
|
||||||
|
|
||||||
/* Format and send the close frame */
|
/* Format and send the close frame */
|
||||||
|
static const int MAX_CLOSE_PAYLOAD = 123;
|
||||||
|
int length = std::min<size_t>(MAX_CLOSE_PAYLOAD, message.length());
|
||||||
char closePayload[MAX_CLOSE_PAYLOAD + 2];
|
char closePayload[MAX_CLOSE_PAYLOAD + 2];
|
||||||
int closePayloadLength = protocol::formatClosePayload(closePayload, code, message.data(), length);
|
int closePayloadLength = protocol::formatClosePayload(closePayload, code, message.data(), length);
|
||||||
|
bool ok = send(std::string_view(closePayload, closePayloadLength), OpCode::CLOSE);
|
||||||
|
|
||||||
// but what if we are NOT corked, THEN we can FIN here if we succeeded
|
/* FIN if we are ok and not corked */
|
||||||
|
WebSocket<SSL, true> *webSocket = (WebSocket<SSL, true> *) this;
|
||||||
// if we are corked and send returns true we cannot know for sure if we can fin
|
if (!webSocket->isCorked()) {
|
||||||
send(std::string_view(closePayload, closePayloadLength), OpCode::CLOSE);
|
if (ok) {
|
||||||
|
/* If we are not corked, and we just sent off everything, we need to FIN right here.
|
||||||
// why should we fin here?
|
* In all other cases, we need to fin either if uncork was successful, or when drainage is complete. */
|
||||||
//us_socket_shutdown((us_socket *) this);
|
webSocket->shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Emit close event */
|
/* Emit close event */
|
||||||
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(
|
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(
|
||||||
|
|||||||
+27
-4
@@ -236,17 +236,38 @@ private:
|
|||||||
/* Always assume timeout is disabled when we are adopted.
|
/* Always assume timeout is disabled when we are adopted.
|
||||||
* HTTP requests should disable timeout anyways */
|
* HTTP requests should disable timeout anyways */
|
||||||
|
|
||||||
|
// beroende på state, skall close emitta eller inte emitta vår event
|
||||||
|
// om den sakll emitta, då blir det 1006 och noll meddelande
|
||||||
|
// annars, har vi redan emittat från den funktion som vi anropade dvs websocket::Close
|
||||||
|
|
||||||
|
// det tar 15 minuter för en ACK att tima ut
|
||||||
|
// så, vi ska endast nollställa timeout om vi skrivit och kernel har tagit emit den
|
||||||
|
// vi kan inte nollställa timeout vid send som inte lyckades
|
||||||
|
|
||||||
/* Handle socket disconnections */
|
/* Handle socket disconnections */
|
||||||
static_dispatch(us_ssl_socket_context_on_close, us_socket_context_on_close)(getSocketContext(), [](auto *s) {
|
static_dispatch(us_ssl_socket_context_on_close, us_socket_context_on_close)(getSocketContext(), [](auto *s) {
|
||||||
|
|
||||||
|
/* For whatever reason, if we already have emitted close event, do not emit it again */
|
||||||
WebSocketData *webSocketData = (WebSocketData *) (static_dispatch(us_ssl_socket_ext, us_socket_ext)(s));
|
WebSocketData *webSocketData = (WebSocketData *) (static_dispatch(us_ssl_socket_ext, us_socket_ext)(s));
|
||||||
|
if (!webSocketData->isShuttingDown) {
|
||||||
|
/* Emit close event */
|
||||||
|
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(
|
||||||
|
static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *)s)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (webSocketContextData->closeHandler) {
|
||||||
|
webSocketContextData->closeHandler((WebSocket<SSL, true> *) s, 1006, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Destruct in-placed data struct */
|
||||||
webSocketData->~WebSocketData();
|
webSocketData->~WebSocketData();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// writable, data samt send skall nollställa timeouten till idleTimeout? allitd
|
||||||
|
|
||||||
/* 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) {
|
||||||
|
|
||||||
@@ -254,9 +275,9 @@ private:
|
|||||||
|
|
||||||
/* If not in websocket shutdown state, for every */
|
/* If not in websocket shutdown state, for every */
|
||||||
|
|
||||||
// hur mycket sabbar denna?
|
// återställ inte om vi är i shutdown state, dvs, ge den inte massa tid på sig att skicka massa skit-frames mellan och upphålla oss!
|
||||||
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(
|
WebSocketContextData<SSL> *webSocketContextData = (WebSocketContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(
|
||||||
static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *)s)
|
static_dispatch(us_ssl_socket_get_context, us_socket_get_context)((SOCKET_TYPE *) s)
|
||||||
);
|
);
|
||||||
|
|
||||||
static_dispatch(us_ssl_socket_timeout, us_socket_timeout)((SOCKET_TYPE *) s, webSocketContextData->idleTimeout);
|
static_dispatch(us_ssl_socket_timeout, us_socket_timeout)((SOCKET_TYPE *) s, webSocketContextData->idleTimeout);
|
||||||
@@ -327,6 +348,8 @@ private:
|
|||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// dessa nedan är samma oavsett state, de closar alltid!
|
||||||
|
|
||||||
/* Handle FIN, HTTP does not support half-closed sockets, so simply close */
|
/* Handle FIN, HTTP does not support half-closed sockets, so simply close */
|
||||||
static_dispatch(us_ssl_socket_context_on_end, us_socket_context_on_end)(getSocketContext(), [](auto *s) {
|
static_dispatch(us_ssl_socket_context_on_end, us_socket_context_on_end)(getSocketContext(), [](auto *s) {
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ template <bool SSL>
|
|||||||
struct WebSocketContextData {
|
struct WebSocketContextData {
|
||||||
/* The callbacks for this context */
|
/* The callbacks for this context */
|
||||||
std::function<void(WebSocket<SSL, true> *, std::string_view, uWS::OpCode)> messageHandler = nullptr;
|
std::function<void(WebSocket<SSL, true> *, std::string_view, uWS::OpCode)> messageHandler = nullptr;
|
||||||
std::function<void(uWS::WebSocket<SSL, true> *)> drainHandler = nullptr;
|
std::function<void(WebSocket<SSL, true> *)> drainHandler = nullptr;
|
||||||
std::function<void(uWS::WebSocket<SSL, true> *, int, std::string_view)> closeHandler = nullptr;
|
std::function<void(WebSocket<SSL, true> *, int, std::string_view)> closeHandler = nullptr;
|
||||||
|
|
||||||
/* Settings for this context */
|
/* Settings for this context */
|
||||||
size_t maxPayloadLength = 0;
|
size_t maxPayloadLength = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user