Flask-socketio disconnect a client
Asked Answered
M

2

5

I am making a chat application using flask-socketio and now I want to emit a message to server with client's username when a client gets disconnected i.e. when client closes browser/tab so that I can emit that message from server to all existing clients for them to change their online friends list. I have googled for more than two hours and anything I have come close to is this and this but it doesn't work for me. I got a way in flask-socketio docs by the following way in server side but I don't know which client got disconnected so I could not change the online friends list.

@socketio.on('disconnect')
def test_disconnect():
    print('Client disconnected')
    emit('client disconnected','a client disconnected but I dont know who',broadcast = True) # i have imported emit 
    # but since i don't know which client disconnected i couldn't emit client name above.

So, I think it would be better to send message from client side like following but after that client closes browser,server does not get that message:

// handle disconnect
socket.on('disconnect',()=>{
      socket.emit('client disconnected',{'username':localStorage.getItem('username')})
})

I am new to flask-socketio and any help would be highly appreciated.

Musso answered 13/6, 2020 at 5:30 Comment(2)
You can make use of request.sid to know which user has disconnected.Transformer
yes I can see the id by that but i want to get the username of that disconnected client too like if client sends after it gets disconnected.Musso
T
4

You can make use of onbeforeunload event. This event gets fired, when a browser tab or a window is closing, trying navigate away from the page or reloading the page.

Client side:

<script>
    window.onbeforeunload = function () {
        socket.emit('client_disconnecting', {'username':localStorage.getItem('username')});
    }
</script>

Server side:

@socket.on('client_disconnecting')
def disconnect_details(data):
    print(f'{data['username']} user disconnected.')
Transformer answered 13/6, 2020 at 7:23 Comment(0)
I
4

Make use of the Flask 'request' object. Your server code would look something like this:

from flask import Flask, request
...
users = {} # rudimentary dict, but use your preferred user management system
@socketio.on('connect')
def connect():
    users[request.sid] = User()
... # I assume some code would go here for users to set/update their display names
@socketio.on('disconnect')
def disconnect():
    emit(
        'user disconnected', 
        {'user_id': request.sid, 'message': users[request.sid].username+' disconnected'}, 
        broadcast=True
    )

The idea would be to assign the sid to your users as they connect, that way you could access their display name via their ID.

Interurban answered 6/5, 2021 at 22:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.