diff options
author | Ignacio Casal Quinteiro <icq@gnome.org> | 2016-10-18 09:21:59 +0200 |
---|---|---|
committer | Ignacio Casal Quinteiro <icq@gnome.org> | 2016-10-20 09:25:05 +0200 |
commit | a4d097593e2ec058774446a927e5a4234905c265 (patch) | |
tree | f369b84bd91718284b7e1d816a7328405091a957 | |
parent | 207444e7e2e6fe5dba3a280ba639c8c64246c240 (diff) | |
download | libsoup-wip/keepalive.tar.gz |
websocket: add api to add a keepalive intervalwip/keepalive
This will send ping messages in that interval of time so the connection
is kept alive.
https://bugzilla.gnome.org/show_bug.cgi?id=773253
-rw-r--r-- | libsoup/soup-websocket-connection.c | 111 | ||||
-rw-r--r-- | libsoup/soup-websocket-connection.h | 7 |
2 files changed, 118 insertions, 0 deletions
diff --git a/libsoup/soup-websocket-connection.c b/libsoup/soup-websocket-connection.c index 46257168..84947334 100644 --- a/libsoup/soup-websocket-connection.c +++ b/libsoup/soup-websocket-connection.c @@ -81,6 +81,7 @@ enum { PROP_PROTOCOL, PROP_STATE, PROP_MAX_INCOMING_PAYLOAD_SIZE, + PROP_KEEPALIVE_INTERVAL, }; enum { @@ -107,6 +108,7 @@ struct _SoupWebsocketConnectionPrivate { char *origin; char *protocol; guint64 max_incoming_payload_size; + gint keepalive_interval; gushort peer_close_code; char *peer_close_data; @@ -131,6 +133,8 @@ struct _SoupWebsocketConnectionPrivate { /* Current message being assembled */ guint8 message_opcode; GByteArray *message_data; + + GSource *keepalive_timeout; }; #define MAX_INCOMING_PAYLOAD_SIZE_DEFAULT 128 * 1024 @@ -225,6 +229,18 @@ stop_output (SoupWebsocketConnection *self) } static void +keepalive_stop_timeout (SoupWebsocketConnection *self) +{ + SoupWebsocketConnectionPrivate *pv = self->pv; + + if (pv->keepalive_timeout) { + g_source_destroy (pv->keepalive_timeout); + g_source_unref (pv->keepalive_timeout); + pv->keepalive_timeout = NULL; + } +} + +static void close_io_stop_timeout (SoupWebsocketConnection *self) { SoupWebsocketConnectionPrivate *pv = self->pv; @@ -241,6 +257,7 @@ close_io_stream (SoupWebsocketConnection *self) { SoupWebsocketConnectionPrivate *pv = self->pv; + keepalive_stop_timeout (self); close_io_stop_timeout (self); if (!pv->io_closing) { @@ -998,6 +1015,10 @@ soup_websocket_connection_get_property (GObject *object, g_value_set_uint64 (value, pv->max_incoming_payload_size); break; + case PROP_KEEPALIVE_INTERVAL: + g_value_set_int (value, pv->keepalive_interval); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1042,6 +1063,10 @@ soup_websocket_connection_set_property (GObject *object, pv->max_incoming_payload_size = g_value_get_uint64 (value); break; + case PROP_KEEPALIVE_INTERVAL: + pv->keepalive_interval = g_value_get_int (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1080,6 +1105,7 @@ soup_websocket_connection_finalize (GObject *object) g_assert (pv->io_closing); g_assert (pv->io_closed); g_assert (!pv->close_timeout); + g_assert (!pv->keepalive_timeout); if (pv->message_data) g_byte_array_free (pv->message_data, TRUE); @@ -1229,6 +1255,26 @@ soup_websocket_connection_class_init (SoupWebsocketConnectionClass *klass) G_PARAM_STATIC_STRINGS)); /** + * SoupWebsocketConnection:keepalive-interval: + * + * Interval in seconds on when to send a ping message which will + * serve as a keepalive message. If set to -1 the keepalive message is + * disabled. + * + * Since: 2.58 + */ + g_object_class_install_property (gobject_class, PROP_KEEPALIVE_INTERVAL, + g_param_spec_int ("keepalive-interval", + "Keepalive interval", + "Keepalive interval", + -1, + G_MAXINT, + -1, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** * SoupWebsocketConnection::message: * @self: the WebSocket * @type: the type of message contents @@ -1647,3 +1693,68 @@ soup_websocket_connection_set_max_incoming_payload_size (SoupWebsocketConnection g_object_notify (G_OBJECT (self), "max-incoming-payload-size"); } } + +/** + * soup_websocket_connection_get_keepalive_interval: + * @self: the WebSocket + * + * Gets the keepalive interval in seconds or -1 if disabled. + * + * Returns: the keepalive interval. + * + * Since: 2.58 + */ +gint +soup_websocket_connection_get_keepalive_interval (SoupWebsocketConnection *self) +{ + SoupWebsocketConnectionPrivate *pv; + + g_return_val_if_fail (SOUP_IS_WEBSOCKET_CONNECTION (self), -1); + pv = self->pv; + + return pv->keepalive_interval; +} + +static gboolean +on_queue_ping (gpointer user_data) +{ + SoupWebsocketConnection *self = SOUP_WEBSOCKET_CONNECTION (user_data); + + g_debug ("sending ping message"); + send_message (self, SOUP_WEBSOCKET_QUEUE_URGENT, 0x09, NULL, 0); + + return G_SOURCE_CONTINUE; +} + +/** + * soup_websocket_connection_set_keepalive_interval: + * @self: the WebSocket + * @interval: the interval to send a ping message or -1 to disable it + * + * Sets the interval in seconds on when to send a ping message which will serve + * as a keepalive message. If set to -1 the keepalive message is disabled. + * + * Since: 2.58 + */ +void +soup_websocket_connection_set_keepalive_interval (SoupWebsocketConnection *self, + gint interval) +{ + SoupWebsocketConnectionPrivate *pv; + + g_return_if_fail (SOUP_IS_WEBSOCKET_CONNECTION (self)); + pv = self->pv; + + if (pv->keepalive_interval != interval) { + pv->keepalive_interval = interval; + g_object_notify (G_OBJECT (self), "keepalive-interval"); + + keepalive_stop_timeout (self); + + if (interval > 0) { + pv->keepalive_timeout = g_timeout_source_new_seconds (interval); + g_source_set_callback (pv->keepalive_timeout, on_queue_ping, self, NULL); + g_source_attach (pv->keepalive_timeout, pv->main_context); + } + } +} diff --git a/libsoup/soup-websocket-connection.h b/libsoup/soup-websocket-connection.h index 9d72e13d..4532b58e 100644 --- a/libsoup/soup-websocket-connection.h +++ b/libsoup/soup-websocket-connection.h @@ -112,6 +112,13 @@ SOUP_AVAILABLE_IN_2_56 void soup_websocket_connection_set_max_incoming_payload_size (SoupWebsocketConnection *self, guint64 max_incoming_payload_size); +SOUP_AVAILABLE_IN_2_58 +gint soup_websocket_connection_get_keepalive_interval (SoupWebsocketConnection *self); + +SOUP_AVAILABLE_IN_2_58 +void soup_websocket_connection_set_keepalive_interval (SoupWebsocketConnection *self, + gint interval); + G_END_DECLS #endif /* __SOUP_WEBSOCKET_CONNECTION_H__ */ |