Back
Dec 11, 2016

Auto WebSocket Reconnection with RxJS (with Example)

Igor Tokarev

As we know, WebSocket connection does not work on the basis of a request-response principle, instead the persistent connection is established between client and server, where both sides can initiate data exchange. When we restart the server, this connection cuts out and we need to restore it somehow.

The typical solution to restore the connection is as follows:

false

In this RxJS tutorial article, we will focus on restoring the websocket connection when using RxJS library. As the Websocket exchange of data is bidirectional, Subject will be the most appropriate tool for this in RxJS. Subject represents two patterns: Observable (will be used to subscribe to the data and events that come from the server) and Observer (will be used to send data to the server).

The first thing I tried to do is to use WebSocketSubject from RxJS 5, inherit from this class, and replace the custom closeObserver in the constructor:

false

In this rxjs websocket reconnection example, we’ve added two new reconnectInterval arguments - an interval between attempts to reconnect and reconnectAttempts - is a number of attempts to reconnect, and we’ve added closeObserver. While closing connection, WebSocketSubject calls closeObserver where we are trying to restore it. The problem is that when the connection is restored, all subscribers are lost, so in order to avoid this, we have to rewrite most of WebSocketSubject, so I came up with other solution to create a wrapper over WebSocketSubject.

Wrapper for WebSocketSubject

false

In this solution, I added connectionStatus attribute, which is necessary for us in order to have the ability to block the user interface when the connection is lost with the server, and unlock it when the connection is restored. When restoring the connection, we try to create a new WebSocketSubject without touching the current subscription, so after the connection recovery, we will not need to resubscribe to our Subject.

Example of usage

We create a small template with textarea in which the connection log will be recorded and there will be a button to send a message.

false

We create the connection

false

We subscribe to the click event for the button, and send the message in a handler.

false

We subscribe to messages from the server and write them in the textarea. We also subscribe to connection status and lock the button when the connection is lost

false

Here’s the server side for testing, written in python 3.5 using aiohttp library. Server part is very simple, we set rxjs observable websocket connection and while connecting / disconnecting, send those events to all clients.

views.py:

false

runserver.py:

false

You can test it like this:

  • run the server python runserver.py
  • open 127.0.0.1:8080
  • click the button of sending message a few times
  • go to the console and stop the server with CTRL + C
  • see that the message sending interface is blocked, and the message about the loss of websocket connection is recorded in the log
  • after a few seconds, run the server. The connection will be automatically restored, and the message on the connection will be recorded to the log, and we can send messages to the server again.

Full working rxjs websocket example can be found here.

More thoughts