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.

What is the proper way to disconnect a client from the server side?

See original GitHub issue

Greetings, I am trying to disconnect a client from the server side. I use aiohttp with socketio.

I use:

class GlobalNamespaceServer(AsyncNamespace):
    # namespace for /
    async def on_disconnect(self, sid: str):
        await self.emit('disconnect', room=sid)

    async def on_connect(self, sid, environ):
        # I need to send event 'accessDenied'
        await self.emit('accessDenied', 'smth', room=sid)
        loop.create_task(self.disconnect(sid))
        return True

As far as I know, the problem is here:

            ret = await s.handle_get_request(environ)
            if s.closed:
                # websocket connection ended, so we are done (socket has already been deleted by `sio.disconnect()`)
                del self.sockets[sid]
            return ret

in _handle_connect function.

Logs

2019-10-23 17:46:33,558 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Sending packet OPEN data {'sid': 'e6c6d024dd41435084460bd42ffc93bb', 'upgrades': [], 'pingTimeout': 60000, 'pingInterval': 25000}
2019-10-23 17:46:33,559 [INFO] socketio.server: emitting event "accessDenied" to e6c6d024dd41435084460bd42ffc93bb [/]
2019-10-23 17:46:33,560 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Sending packet MESSAGE data 2["accessDenied",{"data":{"code":"notAuthorized","description":"text"},"headers":{}}]
2019-10-23 17:46:33,561 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Sending packet MESSAGE data 0
2019-10-23 17:46:33,561 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Received request to upgrade to websocket
2019-10-23 17:46:33,562 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Upgrade to websocket successful
2019-10-23 17:46:38,564 [INFO] socketio.server: emitting event "disconnect" to e6c6d024dd41435084460bd42ffc93bb [/]
2019-10-23 17:46:38,565 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Sending packet MESSAGE data 2["disconnect",null]
2019-10-23 17:46:38,565 [INFO] socketio.server: Disconnecting e6c6d024dd41435084460bd42ffc93bb [/]
2019-10-23 17:46:38,565 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Sending packet MESSAGE data 1
2019-10-23 17:46:38,565 [INFO] engineio.server: e6c6d024dd41435084460bd42ffc93bb: Sending packet CLOSE data None
2019-10-23 17:46:38,569 [ERROR] aiohttp.server: Error handling request
Traceback (most recent call last):
  File ".../lib/python3.7/site-packages/aiohttp/web_protocol.py", line 418, in start
    resp = await task
  File "...lib/python3.7/site-packages/aiohttp/web_app.py", line 458, in _handle
    resp = await handler(request)
  File "...lib/python3.7/site-packages/aiohttp/web_middlewares.py", line 119, in impl
    return await handler(request)
  File "...lib/python3.7/site-packages/aiohttp/web_middlewares.py", line 109, in impl
    return await handler(request)
  File "...lib/python3.7/site-packages/engineio/asyncio_server.py", line 234, in handle_request
    b64, jsonp_index)
  File "...lib/python3.7/site-packages/engineio/asyncio_server.py", line 388, in _handle_connect
    del self.sockets[sid]
KeyError: 'e6c6d024dd41435084460bd42ffc93bb'

Could you please give me advice, what is the proper way?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:27 (12 by maintainers)

github_iconTop GitHub Comments

1reaction
miguelgrinbergcommented, Jun 30, 2020

It appears this issue is the same as the one reported in miguelgrinberg/python-engineio#179, which is now fixed.

0reactions
dskorykhcommented, Nov 13, 2019

Hello! I have the same problem but with socketio.Server (using eventlet as async_mode). I found this happening after upgrading python-socketio to v4.3.1 and I get an error what occurs when I call disconnect from the server side, it’s not persistent (exception is raised approx one time out of ten). It can be related to doing some stuff in the disconnect handler (cleaning hooks bound to client take a little time), but earlier I didn’t see this behavior.

I saw this PR https://github.com/miguelgrinberg/python-engineio/pull/146, and what do you think about adding the same logic to the engineio/server.py?

Error trace:

127.0.0.1 - - [13/Nov/2019 20:05:43] "POST /socket.io/?EIO=3&transport=polling&t=Mvbkc3Z&sid=6152cec661024233ad1108683dfea2ab HTTP/1.1" 200 219 0.000988
127.0.0.1 - - [13/Nov/2019 20:05:43] "GET /socket.io/?EIO=3&transport=polling&t=Mvbkc3a&sid=6152cec661024233ad1108683dfea2ab HTTP/1.1" 200 183 0.054349
reboot called
disconnect hooks
disconnect hooks ended
127.0.0.1 - - [13/Nov/2019 20:05:44] "GET /socket.io/?EIO=3&transport=websocket&sid=6152cec661024233ad1108683dfea2ab HTTP/1.1" 200 0 0.789681
Exception in thread Thread-26:
Traceback (most recent call last):
  File "../lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "../lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "../lib/python2.7/dist-packages/socketio/server.py", line 648, in _handle_event_internal
    r = server._trigger_event(data[0], namespace, sid, *data[1:])
  File "../lib/python2.7/dist-packages/socketio/server.py", line 677, in _trigger_event
    return self.handlers[namespace][event](*args)
  File "../lib/python2.7/dist-packages/flask_socketio/__init__.py", line 284, in _handler
    *args)
  File "../lib/python2.7/dist-packages/flask_socketio/__init__.py", line 698, in _handle_event
    ret = handler(*args)
  File "/home/dmitry/projects/Flask-SocketIO/test_disconnect/app_test.py", line 37, in reboot
    disconnect()
  File "../lib/python2.7/dist-packages/flask_socketio/__init__.py", line 922, in disconnect
    return socketio.server.disconnect(sid, namespace=namespace)
  File "../lib/python2.7/dist-packages/socketio/server.py", line 508, in disconnect
    self.eio.disconnect(sid)
  File "../lib/python2.7/dist-packages/engineio/server.py", line 292, in disconnect
    del self.sockets[sid]
KeyError: '6152cec661024233ad1108683dfea2ab'

Simplified server-side code

#!/usr/bin/env python
import eventlet
eventlet.monkey_patch()

from flask import Flask, render_template
from flask_socketio import SocketIO, disconnect


async_mode = 'eventlet'

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode=async_mode)


def do_some_stuff(): # if there is a some cpu-bound hook, chance of failure increases (just to reproduce)
    a = 0
    for i in range(10000000):
        a += i


@app.route('/')
def index():
    return render_template('index.html', async_mode=socketio.async_mode)


@socketio.on('disconnect')
def disconnect_handler():
    print("run disconnect hooks")
    do_some_stuff()
    print("disconnect hooks done")


@socketio.on('reboot')
def reboot():
    print("reboot called")
    disconnect()
    # reboot 


if __name__ == '__main__':
    socketio.run(app, host="0.0.0.0", port=2000, debug=True)

Read more comments on GitHub >

github_iconTop Results From Across the Web

force client disconnect from server with socket.io and nodejs
You can now simply call socket.disconnect() on the server side. My original answer: This is not possible yet. If you need it as...
Read more >
Disconnecting the Client - Win32 apps
To disconnect and shutdown a socket​​ When the client is done sending data to the server, the shutdown function can be called specifying...
Read more >
The Socket instance (client-side)
This identifier is synced with the value on the server-side. ... io client disconnect, The socket was manually disconnected using ...
Read more >
What does client.stop() do and how does if(client) work ...
When the server code is finished sending packets, it should call client.stop() to send the disconnect message. You must empty the client socket ......
Read more >
19 - Handle a Disconnect - Advanced Node and Express
When disconnecting, the socket client emits a final ' disconnect ' event. The server can listen for this, to know when a client...
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