miguelgrinberg / flask-sock

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

"Invalid frame header" error in browser #20

Closed ekw closed 2 years ago

ekw commented 2 years ago

First off, the example echo server example works for me. But when I try to modify it for my needs, I get an "Invalid frame header" error in browser at the end of the connection. Instead of a forever loop as in the echo example, I want to make a connection, send data, receive data and end the connection. I can send and receive data fine, but always get an "Invalid frame header" error in the browser at the end of the connection. My websocket endpoint is this:

@sock.route('/ws')
def ws(sock):
    data = sock.receive()  
    app.logger.info(data)   # "HI" from client received fine
    sock.send(1)  
    sock.send(2)
    sock.send(3)
    sock.close(message="BYE") # Error occurs in browser with or without this close()

On the client side:

const socket = new WebSocket('wss://myhost/ws');
socket.addEventListener('message', ev => { console.log(ev); })
socket.onopen = () => socket.send("HI");

I see the "HI" on the server, and I see all the integer data on the client. But the browser gets an error after the integer data is sent. It doesn't matter how many sends I do from the server, all the data is received by the client fine. It's only at the end that I always get an error on the browser.

On Chrome, the error is "Invalid frame header". On Firefox, the error is "The connection to wss://host/ws was interrupted while the page was loading."

I am using: Python 3.8.10 gunicorn 20.1.0 gevent 21.12.0 nginx 1.18.0

gunicorn is being proxied by nginx. (As I'm detailing these versions, I now wonder if it's gunicorn/nginx not closing the connection properly.)

Does anyone know how to prevent the error from occurring?

edit: I took nginx and wss out of the equation and the error still occurs.

miguelgrinberg commented 2 years ago

I'm not sure if this can be fixed. The issue happens because Flask, which does not recognize WebSocket requests, tries to issue a standard HTTP response when the connection ends.

ekw commented 2 years ago

OK, thanks for looking into it. Do the reason and message parameters in socket close function do anything at the moment (accessible by client)?

miguelgrinberg commented 2 years ago

I've made some improvements. Could you please test the main branch of this repo and report back?

Here is a summary:

ekw commented 2 years ago

It works, thank you! I am using gunicorn proxied by nginx.