Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rejecting connection seems to be broken with latest javascript socket.io.client #590

Closed
stufisher opened this issue Dec 17, 2020 · 3 comments
Assignees
Labels

Comments

@stufisher
Copy link

stufisher commented Dec 17, 2020

From digging around, it looks like rejecting connections in the latest python-socketio is not compatible with the latest javascript socket.io.client.

In this change:
socketio/socket.io-client@0939395#diff-f0e64910289a49966c99ceadaa5637404e3439ec0812a4bdb7003fe1e5a33d1cR253

the javascript client now expects the rejected connection to provide a data.message in the returned packed. From python-socketio this would appear to be None, which raises the following error in the browser:

Cannot read property 'message' of undefined at Socket.onpacket (socket.js:258)

The python-socketio client doesnt seem to have this problem.

You can quickly reproduce this with a couple of snippets:

Server:

from flask import Flask
from flask_socketio import SocketIO

app = Flask(__name__)
app.config["SECRET_KEY"] = "secret!"
socketio = SocketIO(app, cors_allowed_origins="*")


@socketio.on("connect")
def connect(*args, **kwargs):
    # reject all connections to test
    return False


if __name__ == "__main__":
    socketio.run(app, host="0.0.0.0", port=8080)

python client works -> connection failed message:

import socketio

sio = socketio.Client()


@sio.event
def connect(*args, **kwargs):
    print("I'm connected!", args)


@sio.event
def connect_error(*args):
    print("The connection failed!", args)


@sio.event
def disconnect():
    print("I'm disconnected!")


sio.connect("http://localhost:8080")

simple js client -> throws Cannot read property 'message' of undefined:

const socket = require('socket.io-client')('http://localhost:8080');

socket.on('connect_error', (err) => {
  console.log(`connect error ${socket.id}`, err);
});

socket.on('connect', () => {
  console.log(`connect ${socket.id}`);
});

socket.on('disconnect', () => {
  console.log(`disconnect ${socket.id}`);
});

Versions:

$ conda list | grep 'socket\|engine'
flask-socketio            5.0.0                    pypi_0    pypi
python-engineio           4.0.0                    pypi_0    pypi
python-socketio           5.0.3                    pypi_0    pypi

and socket.io.client = 3.0.4

@miguelgrinberg
Copy link
Owner

Yes, it looks like I missed this. The new CONNECT_ERROR package is not freeform, it has to have the message and data fields in its payload. Instead of returning False, you can raise an exception as follows to make everything work:

@socketio.on("connect")
def connect(*args, **kwargs):
    # reject all connections to test
    raise ConnectionRefusedError({'message': 'error message here'})

You can also add a data member to the dict including optional arguments that are passed in the error object in the client side.

I will figure out a way to map all the possible ways the server can reject a connection into valid CONNECT_ERROR packets.

@miguelgrinberg
Copy link
Owner

@stufisher I have pushed an update with a fix for this problem. Can I ask you to install the master branch of the repo and verify if this fixes the problem for you?

@stufisher
Copy link
Author

Hi @miguelgrinberg, thanks for your quick reply and fix. That looks to be working for me, i can now see your Connection rejected by server in the client.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants