SignalR core python client (V): Reconnecting Client
Tags: signalrcore, python, client, signalr
Published: 2019-06-16 16:25:26

---
title: SignalR core python client (V): Reconnecting Client
published: true
description: signalrcore library now dealing with auto reconnect
tags: signalrcore, python, client, signalr
series: SignalR core python client
cover_image: https://www.campusmvp.es/recursos/image.axd?picture=banner-asp-net-core-750x300.png
---

# Intro

These days I have been working on a new feature. The client reconnection. To know if a client has been disconnected we must set a maximum time without interaction with the socket, this will be stored on a variable that we update on the following cases:

 * last sent message
 * last received message 

So, now we have a variable with the last time we send/receive information through the socket. If this time has passed we must use the socket and check the connection. This action will revalidate our timeout or close our socket.

If our socket is closed we must stop app or try to reconnect. But, we cant reconnect randomly, we need to establish a policy of reconnections avoiding the saturation of the server. On the following lines i will describe implementations of the several options i had think about. 

## Last message in socket

I implement an connection state checker class, that classes purpose will check and update last_message variable. It that variable reaches that threshhold we send a ping, if that ping fails socket will close.

```python
class ConnectionStateChecker(threading.Thread):
    def __init__(
            self,
            ping_function,
            keep_alive_interval,
            sleep = 1):
        self.sleep = sleep
        self.keep_alive_interval = keep_alive_interval
        self.last_message = time.time()
        self.ping_function = ping_function
        self.runing = True

    def run(self):
        while self.runing:
            time.sleep(self.sleep)
            time_without_messages = time.time() - self.last_message
            if self.keep_alive_interval < time_without_messages:
                self.ping_function()
```

### Strategies

For now i only implement 2 strategies, will be activated, with the parameter "type" on the with_automatic_reconnect method.


```python
class ReconnectionType(Enum):
    raw = 0  # Reconnection with max reconnections and constant sleep time
    interval = 1  # variable sleep time
```

#### Intervals

This reconnection works with a array of 'delays' with this, an exponential reconnection will be easily implemented.

```python

class IntervalReconnectionHandler(ReconnectionHandler):
    def __init__(self, intervals):
        self._intervals = intervals

    def next(self):
        self.reconnecting = True
        index = self.attempt_number
        self.attempt_number += 1
        return self._intervals[index]
```
You can generate a list of exponential delays easily.

```python
delays = [pow(2, x) for x in range(1,10)]
# [2, 4, 8, 16, 32, 64, 128, 256, 512]  
```

#### 'raw' reconnect

At 'raw reconnect' i decided to establish a limit, but if limit is no established, connections will be infinite.


```python
class RawReconnectionHandler(ReconnectionHandler):
    def __init__(self, sleep_time, max_attempts):
        super(RawReconnectionHandler, self).__init__()
        self.sleep_time = sleep_time
        self.max_reconnection_attempts = max_attempts

    def next(self):
        self.reconnecting = True
        if self.max_reconnection_attempts is not None:
            if self.attempt_number <= self.max_reconnection_attempts:
                self.attempt_number += 1
                return self.sleep_time
            else:
                raise ValueError("Max attemps reached {0}".format(self.max_reconnection_attempts))
        else:  # Infinite reconnect
            return self.sleep_time
```


## Client syntax
Syntax will be similar to [net core signalr 3.0](https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-core-3-0-preview-4/)
```python
hub_connection = HubConnectionBuilder()\
    .with_url(server_url)\
    .with_automatic_reconnect({
        "type": "raw",
        "keep_alive_interval": 10,  # Ping function
        "reconnect_interval": 5, # 5s between attempts
        "max_attempts": 5
    }).build()

hub_connection = HubConnectionBuilder()\
    .with_url(server_url, options={
        "access_token_factory": lambda: signalr_core_example_login(login_url, username, password)
    }).with_automatic_reconnect({
        "type": "interval",
        "keep_alive_interval": 10, # Ping function
        "intervals": [1, 3, 5, 6, 7, 87, 3]
    })\
    .build()
```
## Links

[Github](https://github.com/mandrewcito/signalrcore)
[Pypi](https://pypi.org/project/signalrcore/)

Thank you for reading, and write any thought below :D