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.

Avisek SSarma
  • 177
  • 1
  • 4
  • 10

2 Answers2

3

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.')
ngShravil.py
  • 4,742
  • 3
  • 18
  • 30
2

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.

Jacob
  • 21
  • 1