question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Disconnected callbacks firing multiple times when multiple connections are made in a session

See original GitHub issue
  • bleak version: 0.8.0
  • Python version: 3.8.5
  • Operating System: Windows 10 2004, build 19041.508

Description

When connecting to a BLE device, I am creating a new client and setting a disconnected callback using client.set_disconnected_callback(), then storing the client in self.connected_devices { } with a reference against the MAC address.

This all works great including the firing off the callback when the device is connected (either by client.disconnect() or wandering out of range, powered off, etc). The disconnect callback discards the client by deleting it from self.connected_devices when fired.

However after reconnecting to the same device in the same session (and again creating a new client, assigning the disconnected callback and stuffing it in the dict of connected devices), on disconnect the callback with run twice. And on the third time, three times, and so on.

I have determined as a workaround, I could try separately tracking all MAC addresses (a self.client_history dict, perhaps) and then avoid setting disconnection callbacks on any MAC addresses I find in there, but I wonder if this is going about things the wrong way? Is there some way the client instance is surviving having been discarded? It’s as if there is a stale reference to previously-connected devices somewhere.

What I Did

    async def __connect_device(self, mac):
        # connect to a device based on a mac address 
        print("Connecting to mac: {0}".format(mac),flush=True)
        client = BleakClient(mac)
        try:
            await client.connect()
        except BleakError as err:
            print(err)
        else:
            client.set_disconnected_callback(self.__disconnect_callback)
            await client.get_services()
            self.connected_devices[mac] = client

    async def __disconnect_device(self, mac):
        # connect to a device based on a mac address 
        print("Disconnecting mac: {0}".format(mac),flush=True)
        if mac in self.connected_devices:
            await self.connected_devices[mac].disconnect()

    def __disconnect_callback(self, device_client):
        # fires when a device is disconnected
        print("Disconnected from {0}".format(device_client.address))
        mac = device_client.address
        # remove from self.connected_devices
        if mac in self.connected_devices:
            del self.connected_devices[mac]

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
dpelaezcommented, Oct 7, 2020

No problem! On the subject of workarounds, maintaining a list of previously-connected MAC addresses and not setting callbacks on them again for the remainder of the session does seem to work quite nicely, insofar as even when connecting/disconnecting multiple different devices, a single disconnection event only ever triggered a single iteration of the disconnection callback.

I ran into the same problem and this workaround does work quite nicely.

0reactions
hbldhcommented, Sep 28, 2020

Amazing… that is similar to how I do it in the feature/winrt branch. I have never seen that method in the pythonnet world; But it is a method on the EventBinding, right? I must have not dir:ed them enough.

I prefer keeping solutions outside of the BleakBridge and if all event handler handling can be done with add and remove methods instead I am all for it!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Socket.IO handling disconnect event - Stack Overflow
The server side code that emits this disconnected event is inside the disconnect event callback which is fired when the socket loses connection....
Read more >
Understanding and Handling Connection Lifetime Events in ...
This article provides an overview of the SignalR connection, reconnection, and disconnection events that you can handle, and timeout and ...
Read more >
Analyzing Disconnects | Photon Engine
Analyzing Disconnects. When you build an online multiplayer game, you have to be aware that sometimes connections between clients and servers fail.
Read more >
Paho Python MQTT Client - Working with Connections
A look at client connections and the Paho MQTT client. Includes examples of good and failed connections and re-connections.
Read more >
Client API - Socket.IO
More information can be found here. Events​. Event: 'connect'​. Fired upon connection to the Namespace (including a successful reconnection).
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found