]> www.infradead.org Git - pidgin-chime.git/commitdiff
Handle unexpected closure of screen websocket
authorDavid Woodhouse <dwmw@amazon.co.uk>
Fri, 22 Nov 2019 21:20:48 +0000 (21:20 +0000)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Fri, 22 Nov 2019 21:20:48 +0000 (21:20 +0000)
I don't think this was a cause of dropouts because the reported behaviour
was a stall (no movement in the picture). And when the websocket drops,
the shared screen drops and other participants see that it's gone.

But we should handle it appropriately anyway. By visibly dropping and
reporting an error for now. If necessary we'll make it automatically
reconnect like the audio stream does.

chime/chime-call-screen.c
chime/chime-call-screen.h
chime/chime-call.c
chime/chime-connection-private.h

index 49ce1ec0377ab51d0deba07044a2fe3b7a27ad96..b88db61d6c1880a3c2a8692ac92245ff1bbc99fb 100644 (file)
@@ -117,10 +117,24 @@ static void screen_send_packet(ChimeCallScreen *screen, enum screen_pkt_type typ
 
 static void on_screenws_closed(SoupWebsocketConnection *ws, gpointer _screen)
 {
-       //      ChimeCallScreen *screen = _screen;
+       ChimeCallScreen *screen = _screen;
+
+       chime_debug("Screen websocket closed %d %s!\n",
+                   soup_websocket_connection_get_close_code(ws),
+                   soup_websocket_connection_get_close_data(ws));
+
+       /* This provokes the UI to tear down the GStreamer pipeline */
+       chime_call_screen_set_state(screen, CHIME_SCREEN_STATE_FAILED, "Websocket closed unexpectedly");
+
+       if (screen->screen_src) {
+               gst_app_src_set_callbacks(screen->screen_src, &no_appsrc_callbacks, NULL, NULL);
+               screen->screen_src = NULL;
+       }
 
-       //      chime_call_transport_disconnect(screen, FALSE);
-       //      chime_call_transport_connect(screen, screen->silent);
+       if (screen->screen_sink) {
+               gst_app_sink_set_callbacks(screen->screen_sink, &no_appsink_callbacks, NULL, NULL);
+               screen->screen_sink = NULL;
+       }
 }
 
 static void on_screenws_message(SoupWebsocketConnection *ws, gint type,
@@ -139,6 +153,7 @@ static void on_screenws_message(SoupWebsocketConnection *ws, gint type,
                return;
 
        const struct screen_pkt *pkt = d;
+
        switch(pkt->type) {
        case SCREEN_PKT_TYPE_HEARTBEAT_REQUEST:
                screen_send_packet(screen, SCREEN_PKT_TYPE_HEARTBEAT_RESPONSE, NULL, 0);
@@ -213,20 +228,39 @@ static void screen_ws_connect_cb(GObject *obj, GAsyncResult *res, gpointer _scre
        g_object_unref(cxn);
 }
 
-
-ChimeCallScreen *chime_call_screen_open(ChimeConnection *cxn, ChimeCall *call)
+ChimeCallScreen *chime_call_screen_open(ChimeConnection *cxn, ChimeCall *call, ChimeCallScreen *screen)
 {
-       ChimeCallScreen *screen = g_new0(ChimeCallScreen, 1);
+       if (screen) {
+               if (screen->state != CHIME_SCREEN_STATE_FAILED)
+                       return screen;
 
-       g_mutex_init(&screen->transport_lock);
+               /* It will already be closed. Just drop it. */
+               g_object_unref(screen->ws);
+               screen->ws = NULL;
 
-       screen->call = call;
-       screen->cancel = g_cancellable_new();
+               if (screen->screen_src) {
+                       gst_app_src_set_callbacks(screen->screen_src, &no_appsrc_callbacks, NULL, NULL);
+                       screen->screen_src = NULL;
+               }
+               if (screen->screen_sink) {
+                       gst_app_sink_set_callbacks(screen->screen_sink, &no_appsink_callbacks, NULL, NULL);
+                       screen->screen_sink = NULL;
+               }
+       }
+
+       if (!screen) {
+               screen = g_new0(ChimeCallScreen, 1);
+
+               g_mutex_init(&screen->transport_lock);
+
+               screen->call = call;
+               screen->cancel = g_cancellable_new();
+       }
 
        SoupURI *uri = soup_uri_new(chime_call_get_desktop_bithub_url(screen->call));
        SoupMessage *msg = soup_message_new_from_uri("GET", uri);
        soup_message_headers_append(msg->request_headers, "User-Agent", "BibaScreen/2.0");
-       soup_message_headers_append(msg->request_headers, "X-BitHub-Call-Id", chime_call_get_uuid(call));
+       soup_message_headers_append(msg->request_headers, "X-BitHub-Call-Id", chime_call_get_uuid(screen->call));
        soup_message_headers_append(msg->request_headers, "X-BitHub-Client-Type", "screen");
        soup_message_headers_append(msg->request_headers, "X-BitHub-Capabilities", "1");
        char *cookie_hdr = g_strdup_printf("_relay_session=%s",
@@ -255,6 +289,13 @@ static void on_final_screenws_close(SoupWebsocketConnection *ws, gpointer _unuse
 
 void chime_call_screen_close(ChimeCallScreen *screen)
 {
+       /* If the websocket is already closed, clear it now instead of trying to
+          close it gracefully */
+       if (screen->state == CHIME_SCREEN_STATE_FAILED && screen->ws) {
+               g_object_unref(screen->ws);
+               screen->ws = NULL;
+       }
+
        chime_call_screen_set_state(screen, CHIME_SCREEN_STATE_HANGUP, NULL);
 
        if (screen->cancel) {
@@ -299,6 +340,8 @@ static void screen_appsrc_destroy(gpointer _screen)
                screen_send_packet(screen, SCREEN_PKT_TYPE_VIEWER_END, NULL, 0);
                screen->screen_src = NULL;
                chime_call_screen_set_state(screen, CHIME_SCREEN_STATE_CONNECTED, NULL);
+       } else if (screen->state == CHIME_SCREEN_STATE_FAILED) {
+               screen->screen_src = NULL;
        }
 }
 
@@ -371,6 +414,8 @@ static void screen_appsink_destroy(gpointer _screen)
                screen_send_packet(screen, SCREEN_PKT_TYPE_PRESENTER_END, NULL, 0);
                screen->screen_sink = NULL;
                chime_call_screen_set_state(screen, CHIME_SCREEN_STATE_CONNECTED, NULL);
+       } else if (screen->state == CHIME_SCREEN_STATE_FAILED) {
+               screen->screen_sink = NULL;
        }
 }
 
index 06af8188436702a8afddcce903fc456f30d8cd66..46d87233d52d686d4d84c1bf28abfaa8d411a722 100644 (file)
@@ -39,7 +39,7 @@ struct _ChimeCallScreen {
 };
 
 /* Called from ChimeMeeting */
-ChimeCallScreen *chime_call_screen_open(ChimeConnection *cxn, ChimeCall *call);
+ChimeCallScreen *chime_call_screen_open(ChimeConnection *cxn, ChimeCall *call, ChimeCallScreen *screen);
 void chime_call_screen_close(ChimeCallScreen *screen);
 void chime_call_screen_view(ChimeCallScreen *screen);
 void chime_call_screen_unview(ChimeCallScreen *screen);
index 35a26cdbd7551341c9111dbaa45933d369b9af38..d203bed88cb8a0742172e5b1152008c4205b6420 100644 (file)
@@ -617,16 +617,14 @@ void chime_call_install_gst_app_callbacks(ChimeCall *call, GstAppSrc *appsrc, Gs
 
 void chime_call_view_screen(ChimeConnection *cxn, ChimeCall *call, GstAppSrc *appsrc)
 {
-       if (!call->screen)
-               call->screen = chime_call_screen_open(cxn, call);
+       call->screen = chime_call_screen_open(cxn, call, call->screen);
 
        chime_call_screen_install_appsrc(call->screen, appsrc);
 }
 
 void chime_call_send_screen(ChimeConnection *cxn, ChimeCall *call, GstAppSink *appsink)
 {
-       if (!call->screen)
-               call->screen = chime_call_screen_open(cxn, call);
+       call->screen = chime_call_screen_open(cxn, call, call->screen);
 
        chime_call_screen_install_appsink(call->screen, appsink);
 }
index 5c0b605abc29fc106ca877930be41e6738403caa..07740f1871ea36a6c68caa649230dff6cf076e90 100644 (file)
@@ -43,6 +43,8 @@
 #define soup_websocket_connection_send_text chime_websocket_connection_send_text
 #define soup_websocket_connection_send_binary chime_websocket_connection_send_binary
 #define soup_websocket_connection_close chime_websocket_connection_close
+#define soup_websocket_connection_get_close_code chime_websocket_connection_get_close_code
+#define soup_websocket_connection_get_close_data chime_websocket_connection_get_close_data
 #define SoupWebsocketConnection ChimeWebsocketConnection
 #endif