heroku-python / flask-sockets

[DEPRECATED] Alternative: https://github.com/miguelgrinberg/flask-sock
MIT License
1.74k stars 164 forks source link

question about receive and close #33

Open StudentForever opened 8 years ago

StudentForever commented 8 years ago

Hi

I attached the python server and Js client code.

I have added my questions as inline comments in the code but here they are

  1. ws.receive() seems to be blocking until it receives message from websocket client from the JS code
  2. when I close the socket from JavaScript client, I don't think the connection is getting closed. I might be doing something dumb but cannot figure it out yet.

Tried this from chrome (Version 49.0.2623.112 m) and IE (version: 11.0.9600.18163).

On IE, after I tried closing the socket from JS Client, I got an error: SCRIPT12002: WebSocket Error: Network Error 12002, The operation timed out

Thanks a lot for your time.

example.zip

mdonahoe commented 8 years ago

It isn't clear from your server.py code how you are actually running the flask server. Are you using the non-blocking gevent-based WSGIServer? I just copied the code from the main flask_sockets example and got non-blocking sockets.

The ws.receive() line isn't going to block the rest of your app, but it will prevent further execution in the start_timing function, as the code executes serially. You need to have a different function that handles the sending of new messages to the client.

johnwheeler commented 8 years ago

I'm butting up against this too although it seems like a gevent-websocket issue. The problem I have is, if I don't ever call receive in the while True loop (i.e. only call send), client disconnects won't notify the socket, and the loop will run indefinitely. Seems like receive is needed with a timeout just to check the client is still connected or not.

FYI: That's running from gunicorn with flask_sockets.worker

johnwheeler commented 8 years ago

FYI digging into this more, I found gevent Timeouts, which might be the answer

http://www.gevent.org/gevent.html#timeouts

danmichaelo commented 6 years ago

Ran into the same problem with this code:

@sockets.route('/status.sock')
def status_sock(socket):
    app.logger.info('Websocket opened')
    with open(log_file, encoding='utf-8') as run_file:
        while not socket.closed:
            app.logger.info('Check for new data')
            new_data = run_file.read()
            if new_data:
                socket.send(new_data)
            gevent.sleep(1)
    app.logger.info('Websocket closed')  # never called

Everything worked fine, execpt a slight problem: No sockets were ever closed!

This is really an issue with the underlying gevent-websocket library. It seems like calling socket.receive() is necessary to detect if the socket is closed, but the same method is blocking.. See https://gitlab.com/noppo/gevent-websocket/issues/1

Here's my current approach:

@sockets.route('/status.sock')
def status_sock(socket):
    app.logger.info('Websocket opened')
    with open(log_file, encoding='utf-8') as run_file:
        while not socket.closed:
            app.logger.info('Check for new data')
            new_data = run_file.read()
            if new_data:
                socket.send(new_data)
            with gevent.Timeout(1.0, False):
                socket.receive()
    app.logger.info('Websocket closed')