summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgnacio Casal Quinteiro <icq@gnome.org>2016-10-18 09:21:59 +0200
committerIgnacio Casal Quinteiro <icq@gnome.org>2016-10-20 09:25:05 +0200
commita4d097593e2ec058774446a927e5a4234905c265 (patch)
treef369b84bd91718284b7e1d816a7328405091a957
parent207444e7e2e6fe5dba3a280ba639c8c64246c240 (diff)
downloadlibsoup-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.c111
-rw-r--r--libsoup/soup-websocket-connection.h7
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__ */