Improve WebSocket shutdown

This commit is contained in:
Přemysl Eric Janouch 2018-10-16 04:09:59 +02:00
parent 7cefdd496f
commit 7f6db9d39f
Signed by: p
GPG Key ID: A0420B94F92B9493
1 changed files with 13 additions and 12 deletions

View File

@ -540,10 +540,6 @@ struct ws_handler
/// The connection is about to close. @a close_code may, or may not, be one /// The connection is about to close. @a close_code may, or may not, be one
/// of enum ws_status. The @a reason is never NULL. /// of enum ws_status. The @a reason is never NULL.
// TODO; also note that ideally, the handler should (be able to) first
// receive a notification about the connection being closed because of
// an error (recv()) returns -1, and call on_close() in reaction.
// Actually, calling push() could work pretty fine for this.
void (*on_close) (struct ws_handler *, int close_code, const char *reason); void (*on_close) (struct ws_handler *, int close_code, const char *reason);
// Virtual method callbacks: // Virtual method callbacks:
@ -551,8 +547,9 @@ struct ws_handler
/// Write a chunk of data to the stream /// Write a chunk of data to the stream
void (*write_cb) (struct ws_handler *, const void *data, size_t len); void (*write_cb) (struct ws_handler *, const void *data, size_t len);
/// Close the connection /// Close the connection. If @a half_close is false, you are allowed to
void (*close_cb) (struct ws_handler *); /// destroy the handler directly from within the callback.
void (*close_cb) (struct ws_handler *, bool half_close);
}; };
static void static void
@ -777,7 +774,7 @@ ws_handler_on_close_timeout (EV_P_ ev_timer *watcher, int revents)
// TODO: anything else to do here? Invalidate our state? // TODO: anything else to do here? Invalidate our state?
if (self->close_cb) if (self->close_cb)
self->close_cb (self); self->close_cb (self, false /* half_close */);
} }
static void static void
@ -2205,12 +2202,13 @@ client_ws_write_cb (struct ws_handler *handler, const void *data, size_t len)
} }
static void static void
client_ws_close_cb (struct ws_handler *handler) client_ws_close_cb (struct ws_handler *handler, bool half_close)
{ {
FIND_CONTAINER (self, handler, struct client_ws, handler); FIND_CONTAINER (self, handler, struct client_ws, handler);
// FIXME: we should probably call something like client_shutdown(), if (half_close)
// which may have an argument whether we should really use close() ; // FIXME: we should probably call something like client_shutdown()
client_destroy (&self->client); else
client_destroy (&self->client);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -2219,7 +2217,10 @@ static void
client_ws_shutdown (struct client *client) client_ws_shutdown (struct client *client)
{ {
FIND_CONTAINER (self, client, struct client_ws, client); FIND_CONTAINER (self, client, struct client_ws, client);
ws_handler_close (&self->handler, WS_STATUS_GOING_AWAY, NULL, 0); if (self->handler.state == WS_HANDLER_CONNECTING)
; // TODO: abort the connection immediately
else if (self->handler.state == WS_HANDLER_OPEN)
ws_handler_close (&self->handler, WS_STATUS_GOING_AWAY, NULL, 0);
} }
static void static void