miguelgrinberg / flask-sock

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

Demo code is returning 404s #49

Closed tshmit closed 1 year ago

tshmit commented 1 year ago

Hello Miguel, First, thank you for your efforts in creating this package!

I had some trouble with my first try at implementation, with the server returning:

(.venv)  ➜  sockets FLASK_APP=main.py flask run`
Serving Flask app 'main.py'`
Debug mode: off`
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
Running on http://127.0.0.1:5000
Press CTRL+C to quit
127.0.0.1 - - [01/Mar/2023 10:05:28] "GET /socket.io/?EIO=4&transport=polling&t=OQTjFdZ HTTP/1.1" 404 -
127.0.0.1 - - [01/Mar/2023 10:05:29] "GET /socket.io/?EIO=4&transport=polling&t=OQTjFrH HTTP/1.1" 404 -
127.0.0.1 - - [01/Mar/2023 10:05:31] "GET /socket.io/?EIO=4&transport=polling&t=OQTjGJu HTTP/1.1" 404 -
127.0.0.1 - - [01/Mar/2023 10:05:33] "GET /socket.io/?EIO=4&transport=polling&t=OQTjGuf HTTP/1.1" 404 -

I then created a new test by cutting and pasting code directly from your blog post https://blog.miguelgrinberg.com/post/add-a-websocket-route-to-your-flask-2-x-application and encountered exactly the same behavior :-/

However, when testing with: wscat --connect ws://127.0.0.1:5000/echo the server connects as expected.

I am testing on a clean environment with only flask and flask_sock being installed:

(.venv) ➜  sockets pip freeze
click==8.1.3
Flask==2.2.3
flask-sock==0.6.0
h11==0.14.0
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.2
simple-websocket==0.9.0
Werkzeug==2.2.3
wsproto==1.2.0

To confirm I didn't somehow copy/paste incorrectly from your demo, here is the code pasted from my editor: Index.html

<!doctype html>
<html>
  <head>
    <title>Flask-Sock Demo</title>
  </head>
  <body>
    <h1>Flask-Sock Demo</h1>
    <div id="log"></div>
    <br>
    <form id="form">
      <label for="text">Input: </label>
      <input type="text" id="text" autofocus>
    </form>
    <script>
      const log = (text, color) => {
        document.getElementById('log').innerHTML += `<span style="color: ${color}">${text}</span><br>`;
      };

      const socket = new WebSocket('ws://' + location.host + '/echo');
      socket.addEventListener('message', ev => {
        log('<<< ' + ev.data, 'blue');
      });
      document.getElementById('form').onsubmit = ev => {
        ev.preventDefault();
        const textField = document.getElementById('text');
        log('>>> ' + textField.value, 'red');
        socket.send(textField.value);
        textField.value = '';
      };
    </script>
  </body>
</html>

And main.py

from flask_sock import Sock

app = Flask(__name__)
sock = Sock(app)

@app.route('/')
def index():
    return render_template('index.html')

@sock.route('/echo')
def echo(sock):
    while True:
        data = sock.receive()
        sock.send(data)

In my app I did also test the client importing from socket.io on as so: const socket = io.connect("ws://127.0.0.1:5000/echo But saw the same result.

I'm stumped. Any thoughts on what might be going wrong? Thank you!

miguelgrinberg commented 1 year ago

The 404s occur because your client is trying to connect via the Socket.IO protocol, not WebSocket. You seem to be mixing the two protocols here. If you want to use Socket.IO then use a Socket.IO client and the Flask-SocketIO extension. If you want to use plain WebSocket, then use a WebSocket client and the Flask-Sock extension.

tshmit commented 1 year ago

Thanks for your reply, Miguel. Sorry, I guess I'm confused. Is this line (# 19 in index.html, above), not using the WebSocket you refer to? const socket = new WebSocket('ws://' + location.host + '/echo');

miguelgrinberg commented 1 year ago

What I mean is that you have some other client running in your computer making requests like these:

127.0.0.1 - - [01/Mar/2023 10:05:28] "GET /socket.io/?EIO=4&transport=polling&t=OQTjFdZ HTTP/1.1" 404 -
tshmit commented 1 year ago

Of course, you are right. I'd been testing in another browser and forgot about it. It's not yet clear to me why that was preventing the above client code from connecting, but now that I have something running (what a relief) I'll figure it out. Thank you so much for your help!