PeachMode
PeachMode

Reputation: 407

Python and Socket.IO - App hangs after connection

I'm working on a python app. The basic implementation requires a Raspberry Pi to be connected to a main server and to share messages. The server will be running a python app to analyse data and return info to the Raspberry Pi.

I'm implementing this system with python-socketio for the server part and socketio.client for the Raspberry Pi code.

My issue is that I'm able to connect to the server and recieve a response message, but then the program hangs on the client side.

My server's code is:

import socketio
import eventlet
from flask import Flask

# Define Socket.IO server and application wrapper
sio = socketio.Server()
app = Flask(__name__)

@sio.on('connect', namespace = '/test')
def connect(sid, environ):
    print 'New Connection ' + sid
    sio.emit("server_response", sid, room = sid, namespace = '/test' )

@sio.on('message', namespace = '/test')
def message(sid, data):
    print 'message ' + sid + " " + data
    sio.emit("server_reply", data = "Hello", room = sid, namespace = '/test')

@sio.on('disconnect', namespace = '/test')
def disconnect(sid):
    print 'disconnect ' + sid

if __name__ == '__main__':
    # Wrap Flask application with Socket.IO's middleware
    app = socketio.Middleware(sio, app)

    # Deploy as an eventlet WSGI server
    eventlet.wsgi.server(eventlet.listen(('',8000)), app)

As for the client part I'm using this code:

from socketIO_client import SocketIO, BaseNamespace
global sio
global testNamespace
global myId

class testNamespace(BaseNamespace):

    def on_server_response(self, userID):
        myId = userID
        print "Socket connection accepted"
        print "I was assigned the id: " + myId

    def on_server_reply(self, data):
        print "message response: " + data

if __name__ == "__main__":
    # Establish the connection
    sio = SocketIO('localhost', 8000)
    testNamespace = sio.define(testNamespace, '/test')

    print "Going to emit message"
    testNamespace.emit("message", "Hello")

    sio.wait()

For some reason, I get the server response with the assigned ID but then the program never reaches the line

print "Going to emit message"

I initially thought it was something related with the namespace but since print instruction never occurs I don't understand what I'm doing wrong.

EDIT

I've noticed that if on_server_response I try to emit the message Hello with

self.emit("message", "Hello")

I'm able to send the message to the server and get it's reply. What I don't understand now it how is one able to emit events on the main program, outside the class definition.

Upvotes: 1

Views: 2286

Answers (1)

bbrincat
bbrincat

Reputation: 34

I've found the same issue and opened an issue on SocketIO_client.

https://github.com/invisibleroads/socketIO-client/issues/117

Here's a solution which overrides the problematic part in a subclass. Then just use this SocketIOClient instead of SocketIO

from socketIO_client import SocketIO

class SocketIOClient(SocketIO):
    """
    Fix for library bug
    """

    def _should_stop_waiting(self, for_connect=False, for_callbacks=False):
        if for_connect:
            for namespace in self._namespace_by_path.values():
                is_namespace_connected = getattr(
                    namespace, '_connected', False)
                #Added the check and namespace.path
                #because for the root namespaces, which is an empty string
                #the attribute _connected is never set
                #so this was hanging when trying to connect to namespaces
                # this skips the check for root namespace, which is implicitly connected
                if not is_namespace_connected and namespace.path:
                    return False
            return True
        if for_callbacks and not self._has_ack_callback:
            return True
        return super(SocketIO, self)._should_stop_waiting()

Upvotes: 2

Related Questions