miguelgrinberg / flask-sock

Modern WebSocket support for Flask.
MIT License
274 stars 24 forks source link

closed connection raises ConnectionError #25

Closed meinradr closed 2 years ago

meinradr commented 2 years ago

A ConnectionError is raised when the client closes the connection.

flask-sock example 1
@sock.route('/status-socket')
def status_socket(ws):
    while ws.connected:
        if status:
            ws.send('test')
        time.sleep(.5)
flask-sock example 2
@sock.route('/status-socket')
def status_socket(ws: 'WS_Server'):
    while True:
        ws.send('test')
        time.sleep(.5)
simple-websocket

If I do the same thing with simple-websocket, everything works as expected.

@app.route('/status-socket', websocket=True)
def status_socket():
    ws = simple_websocket.Server(request.environ)
    try:
        while ws.connected:
            if status:
                ws.send('test')
            time.sleep(.5)
    except simple_websocket.ConnectionClosed:
        pass
    return ''
versions

python 3.10.0 flask 2.0.2 simple-websocket 0.5.1 flask-sock 0.5.2

update

This only happens when I run the app with 'debug=True'.

miguelgrinberg commented 2 years ago

See https://github.com/miguelgrinberg/flask-sock/issues/21.

meinradr commented 2 years ago

I finally understand where this issue is coming from and why it's hard to get a workaround. The following hack reduces the exception message to a bare minimum:

import sys

class FlaskSockConnectionError(BaseException):
    def __init__(self, *args):
        self.default_tracebacklimit = getattr(sys, 'tracebacklimit', 100)
        sys.tracebacklimit = 0
        super().__init__(*args)

    def __del__(self):
        sys.tracebacklimit = self.default_tracebacklimit
elif ws.mode == 'werkzeug':
    if current_app.debug:
        raise FlaskSockConnectionError()
    else:
        raise ConnectionError()

In case you're interested, i created a pull request #26.

miguelgrinberg commented 2 years ago

I don't believe the fix for this issue belongs here, even more so when it is so hacky/obscure. This issue should be fixed in Werkzeug. The stack trace is a small annoyance in my opinion, so I prefer to live with it until someone (maybe myself if/when I find some time) addresses the problem on the Werkzeug side.

allsey87 commented 2 years ago

Has there already been an issue opened on the Werkzeug side?

miguelgrinberg commented 2 years ago

@allsey87 I haven't had time to investigate this to be able to provide sufficient information on what is broken in Werkzeug, so I have not filed an issue. As I said above, this is an annoyance more than anything since Werkzeug is a development web server. I don't see it as a blocker since all the production web servers supported by Flask-Sock handle the WebSocket closures correctly.