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

Handling ConnectionRefusedError from python-socketio[client] #344

Closed
Soreepeong opened this issue Aug 30, 2019 · 13 comments
Closed

Handling ConnectionRefusedError from python-socketio[client] #344

Soreepeong opened this issue Aug 30, 2019 · 13 comments
Assignees
Labels

Comments

@Soreepeong
Copy link

Soreepeong commented Aug 30, 2019

I found that there is no way to have notified when the server rejects connection (or at least joining a namespace.) Am I missing something, or will this have to be implemented in some way?

From socketio.client.Client._handle_eio_message, when the packet_type is packet.ERROR, it will call _handle_error without pkt.data.

elif pkt.packet_type == packet.ERROR:
self._handle_error(pkt.namespace)

Moreover, it does not let the user know if an error has gone through the handler.

def _handle_error(self, namespace):
namespace = namespace or '/'
self.logger.info('Connection to namespace {} was rejected'.format(
namespace))
if namespace in self.namespaces:
self.namespaces.remove(namespace)
if namespace == '/':
self.namespaces = []
self.connected = False

Workarounds

  1. Hooking _handle_error: pkt.data is missing, so the details won't be available.
  2. Hooking _handle_eio_message: Introduces double decoding of packets, thus giving performance impacts.
  3. Sleep, check number of namespaces, and then wait: refusal details are still unavailable.
sio.sleep(2)
if sio.namespaces:
    sio.wait()
else:
    some_custom_error_handling()

Example server namespace code

class TestNamespace(Namespace):
    def on_connect(self):
        raise ConnectionRefusedError("Testing")

Client log output:

Attempting WebSocket connection to ws://127.0.0.1:11100/socket.io/?transport=websocket&EIO=3
WebSocket connection accepted with {'sid': '<snip>', 'upgrades': [], 'pingTimeout': 60000, 'pingInterval': 25000}
Sending packet PING data None
Received packet MESSAGE data 0
Received packet PONG data None
Sending packet MESSAGE data 0/realtime
Received packet MESSAGE data 4/realtime,"Testing"
@miguelgrinberg miguelgrinberg self-assigned this Aug 30, 2019
@harmon
Copy link

harmon commented Oct 25, 2019

I also just ran across this. I don't see an easy way to get notified about this.

@miguelgrinberg
Copy link
Owner

miguelgrinberg commented Nov 24, 2019

You can now define a connect_error handler in your client and it will be invoked when the server rejects the connection. If the server rejects by returning False, then the connect_error handler is invoked without arguments. If the server rejects by raising ConnectionRefusedError, then any arguments included in the exception are passed as arguments to the connect_error handler.

@sio.event
def connect_error(message):
    print('Connection was rejected due to ' + message)

@YuqiaoS
Copy link

YuqiaoS commented Nov 29, 2019

I'm using this with flask-socketio, and the connection stays alive. I'm only getting error, not connect_error on the client-side for the ConnectionRefusedError event.

@miguelgrinberg
Copy link
Owner

@YuqiaoS I don't understand. There is no error event, unless it is a custom one defined by your application.

@YuqiaoS
Copy link

YuqiaoS commented Nov 29, 2019

@miguelgrinberg Well I'm using flask-socketio and what I'm seeing, as I have verified again, is that on 4.3.1 python-socketio, I get the connect_error event back, but on the latest master I'm receiving back error event and the connection doesn't terminate when I raise ConnectionRefusedError. Could you verify this?

@miguelgrinberg
Copy link
Owner

@YuqiaoS What you are claiming cannot really be true. On the 4.3.1 release there is no connect_error event. This was added in the 4.4.0 release. There never was an error event. Do you have some code that demonstrates your problem please?

@YuqiaoS
Copy link

YuqiaoS commented Nov 30, 2019

@miguelgrinberg Wanna bet :) Switched to mac. I assert the above. You could easily verify with the socketio js client.

@miguelgrinberg
Copy link
Owner

@YuqiaoS there's nothing to bet. In 4.3.1 the connect_error event name is just a custom event name. If you are getting that, then the other side is sending an event with that name. Only in 4.4.0 connect_error became a reserved event for the client that is automatically sent when the server rejects a connection.

I don't understand what you want me to try. I asked for a code example, you haven't provided any.

@YuqiaoS
Copy link

YuqiaoS commented Dec 1, 2019

You will get a connect_error event from the js side if you simply disconnect the server. That's not a custom event. Here's a list of native client events:
https://socket.io/docs/client-api/

            'connect',
            'error',
            'disconnect',
            'reconnect',
            'reconnect_attempt',
            'reconnecting',
            'reconnect_error',
            'reconnect_failed',
            'connect_error',
            'connect_timeout',
            'connecting',
            'ping',
            'pong'

As for code, I've already said to use js client and verify. I've verified 3 times already, each with 3 versions.

@miguelgrinberg
Copy link
Owner

miguelgrinberg commented Dec 1, 2019

@YuqiaoS you realize you are asking in the Python project, right? If you say "I get the connect_error event on the client" on this issue tracker the assumption is that you are talking about the Python client. How am I supposed to know that you are talking about someone else's client? I have nothing to offer if you are having problems with the JS client, not my project.

I've also asked several times that you provide sample code, which would have settled this misunderstanding and so far you have not done so.

@YuqiaoS
Copy link

YuqiaoS commented Dec 1, 2019

Well I thought flask-socketio is normally used with the web. Your site says:
The client-side application can use any of the SocketIO official clients libraries in Javascript, C++, Java and Swift

The 4.4.0 python-socketio release has problems I mentioned above when you raise ConnectionRefusedError on the server side. And I think this is a dependency used by flask-socketio package. I think I've given enough the information. The code is literally just catching these events using js. or simply output each packet, however you like. Most critical issue is that the connection establishes and doesn't terminate.

@miguelgrinberg
Copy link
Owner

Well I thought flask-socketio...

This is the issue tracker for python-socketio. Flask-SocketIO is a Socket.IO server. This repository has a server and a client, both written in Python.

I think I've given enough the information.

You have provided no code for me to use to verify and debug the problem you reported, even though I asked several times already. I don't think it is fair of you to expect I will sit down and write a test server and a test client based just on your written description, on the chance that it will match yours and hit the same issue. If you want me to look at your issue you have to save me some time.

@YuqiaoS
Copy link

YuqiaoS commented Dec 2, 2019

Open browser inspector tool, go to network->ws, and you will see a websocket connection even when you raise the error like below. This may be causing some issues mentioned in miguelgrinberg/Flask-SocketIO#1113. On trying to connect using the client socket again after I login through http (flask-session server side setup), the client socket cannot be used to connect as it is still connected.

python

@socketio.on('connect')
def connect():
    # if not current_user.is_authenticated:
    raise ConnectionRefusedError()

js

import io from 'socket.io-client';
socket = io()

// this used to be hit when on python-socketio 4.3.1
socket.on('connect_error', function(error){
  console.log(error)
}
// this is now hit on 4.4.1
socket.on('error', function(error){
  console.log(error)
}

// on connect, disconnect ...

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

4 participants