invisibleroads / socketIO-client

A socket.io client library for Python
http://pypi.python.org/pypi/socketIO-client
MIT License
447 stars 205 forks source link

Initialize the socketIO too slow #118

Open HoarseBox opened 8 years ago

HoarseBox commented 8 years ago

I have a simple client as shown below. It spends 1 min to run the following line, which is too slow. socketIO = SocketIO('localhost',3003) I wonder how to solve this problem?

I use eventlet and didn't install socketIO-client in virtual environment. Would it cause this problem?

from socketIO_client import SocketIO, BaseNamespace
from datetime import datetime

Devices = {}

temp_time = datetime.now()

class Namespace(BaseNamespace):
    def on_connect(self):
        print('[Connected]')
        for device in Devices:
            self.emit('register', device)
            time.sleep(1)

def funcA():
    do something

def funcB():
    do something

print '1:', datetime.now()-temp_time
socketIO = SocketIO('localhost', 3003)
print '2:', datetime.now()-temp_time
socketIO.define(Namespace)

socketIO.on('eventA', funcA)
socketIO.on('eventB', funcB)
socketIO.wait()

The output of the client part:

1: 0:00:00.000074
DEBUG:root:localhost:3003/socket.io [transport selected] xhr-polling
DEBUG:root:localhost:3003/socket.io [heartbeat reset]
2: 0:01:00.019828
DEBUG:root:localhost:3003/socket.io [socket.io packet received] 0
[Connected]

KeineLimonade commented 7 years ago

+1

MikeyC3040 commented 7 years ago

Also having the same issue. Runs just fine, but starts really slow

burnedikt commented 7 years ago

I had the same issue today and wasted a few hours before realizing that the problem is not with the websocket client but the websocket server.

In my case, my server using flask-socketio was lying behind an nginx proxy. The configuration of my nginx was not optimized for incoming websocket connections and changing the configuration as described here helped speeding up the startup process a lot.

The problem appears to be the buffering in a default nginx configuration. Shamelessly copied sample configuration for nginx that works great in conjunction with socket.io:

server {
    listen 80;
    server_name localhost;
    access_log /var/log/nginx/example.log;

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_redirect off;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /socket.io {
        proxy_pass http://127.0.0.1:5000/socket.io;
        proxy_redirect off;
        proxy_buffering off;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}
invisibleroads commented 7 years ago

@burnedikt @salah93 Cool, I didn't know about proxy_buffering

burnedikt commented 7 years ago

@invisibleroads However, I still noticed the problem of slow connects with the following setup - independently of nginx:

When connecting with the socketIO-Client to a python-socketio-server and if a message / event is emitted in the on-connect handler on the server side to the client, then the connection attempt will timeout and the above behaviour can be noticed.

Specifically, this appears to happen since the server emits the message / event before finalizing the upgrade to websocket with the correct packet. The server then appears to send both packets at the same time, i.e. first the custom event and secondly the Connect package. However, on the client side, the parser seems to only return the first packet and disregard the second (CONNECT). Thus, the websocket-connection is never finalized and will timeout and then fallback to XHR.

The weird part is that this issue occurs only with the combination of python-socketio and socketIO-client. If using the combination of socketIO-client and the nodejs socketio or vice versa if using a nodejs socketio-client together with the python-socketio-server, everything works correctly. Consequently, I am not really sure whether the problem is on the client- or server-side right now, but it appears that the packages are correctly sent by the server but not correctly parsed on the client-side.

Tested Combinations with Server emitting event on client connection:

socketio-client + nodejs-socketio = ✅ nodejs-socketio-client + python-socketio = ✅ nodejs-socketio-client + nodejs-socketio = ✅ socketio-client + python-socketio = ❌

Also, I think the description "Initialize the socketIO too slow" does not really match the problem. I'll open a separate issue if you think it's worthy.

bundabrg commented 7 years ago

I can confirm the issue outlined by burnedikt. I actually think its the fact the socket-io server adds emits to its packet queue before the connect event has completed and thus the bug lies there, however node seems to cope with the out of order packets.

Interestingly I have had endless issues with the python socketio server implementation and a dotnet socketio client to the point that I now have a bit of a monkey_patch that fixes it (python socketio server does not handle b64 or binary correctly).