Replacing Nodejs Socket.io server with a python se

2019-07-23 15:09发布

问题:

I have been trying to replace node.js socket.io server with flask-socketio server in python3. However, after numerous attempts including different approaches yield no good results. Could someone please point where I'm going wrong ?

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

io.on('connection', function(socket){
    socket.on('event', function(msg){
        io.emit('event', msg);
        console.log(msg);
    });
});
http.listen(3000, function () {
    console.log('Socket.io Running');
});

My attempt in python3 using Flask-socketio and referring it's docs is here below:

from flask import Flask, render_template
from flask_socketio import SocketIO, emit

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!' # is this the default or does this have no effect ?
socketio = SocketIO(app)

@socketio.on('connect')
def test_connect():
    print('Connected!! ')

@socketio.on('disconnect')
def test_connect():
    print('Disconnected!! ')

@socketio.on('message')
def test_connect():
    print('Msg came!! ')

@socketio.on('json')
def test_connect():
    print('JSON is here!! ')

@socketio.on('event')
def test_event(msg):
    print('In test_event function.')
    emit('event', msg)

if __name__ == '__main__':
    socketio.run(app, port = 3000)

The node.js version works perfectly. However, I can't say the same for the python one.

  • The connect & disconnect print lines do occur.
  • But the event function (or the print function in it) is never called. Neither are the message nor the json events are called.
  • The client-side uses AngularJS and does basic Socket.io event emits.
  • Removing the 'SECRET_KEY' conifg has no effect. The server does connect and disconnect.

The client side should have no effect as the node.js server does work perfectly. But just in case, one needs it, it's right here.

Client-side code:

function copy(data) {
    return JSON.parse(JSON.stringify(data));
}

function addUUID(data) {
    if (Array.isArray(data)) {
        return data.concat([UUID]);
    } else {
        var temp = copy(data);
        temp.UUID = UUID;
        return temp;
    }   
}
socket.emit('event', addUUID(data))

回答1:

So, I was able to achieve a working socket.io server in python using python-socketio (docs) instead of Flask-SocketIO for some reason am I still not able to find out why. Anyway, here's the implementation:

import socketio
import eventlet
from flask import Flask, render_template

sio = socketio.Server()
app = Flask(__name__)

@sio.on('connect')
def connect(sid, environ):
    print('connect ', sid)

@sio.on('event')
def message(sid, data):
    print('msg ', data)

@sio.on('disconnect')
def disconnect(sid):
    print('disconnect ', sid)

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

    # deploy as an eventlet WSGI server
    eventlet.wsgi.server(eventlet.listen(('', 3000)), app)


回答2:

Please check the official docs here, its by the creator of the library, seems you are missing or passing string 'data' part

a section taken from the link

@socketio.on('my event', namespace='/test')
def test_message(message):
    emit('my response', {'data': message['data']})

It is good to use a namespace as above for further development lifecycle