Hi, I have this sample server and client.
from flask import Flask, render_template, jsonify
from flask_socketio import SocketIO, emit, send, join_room
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode='gevent')
@app.route('/')
def index():
return jsonify(), 200
@socketio.on('connect')
def connected():
print('new client')
socketio.send('connection started')
@socketio.on('subscribe')
def subscribe(data):
room = data['room']
join_room(room)
socketio.send('New member in room: ' + room, room=room)
print('New member in room: ' + room)
if __name__=='__main__':
socketio.run(app, host='0.0.0.0', port=8000)
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
</head>
<body>
<script>
var server_address = 'http://0.0.0.0:8000';
var socket = io(server_address);
socket.on('connect', function(){
console.log("connected");
});
socket.on('connect_error', function(err){
console.log(err);
});
socket.on('message', function(msg){
console.log(msg);
});
socket.on('record', function(data){
// new record json
console.log(data);
});
socket.emit('subscribe', {'room':'test'});
</script>
</body>
</html>
When i run the server with socketio.run(app) everything is fine.
But when I try to run the server with uwsgi like this:
uwsgi --http 0.0.0.0:8000 --gevent 1000 --http-websockets --master --wsgi-file app.py --callable app
and open the client with a browser, I get this error in browesr:
Firefox can鈥檛 establish a connection to the server at ws://0.0.0.0:8000/socket.io/?EIO=3&transport=websocket&sid=250c9d90ab3f4aa2a84bf828d829ba25.
and this one in uwsgi:
RuntimeError: You need to use the gevent-websocket server. See the Deployment section of the documentation for more information.
You are setting the gevent async mode explicitly. That requires the gevent web server. Remove the async_mode argument so that the extension can select the best async mode on its own.
I removed the async_mode argument as you said. The only thing that changed is the error I get with uWSGI:
RuntimeError: You need to use the eventlet server. See the Deployment section of the documentation for more information.
This is explained in the documentation. The extension picks the best async mode based on what you have installed in your virtualenv. It seems you have more stuff than you need there. If you want to use uWSGI, then you need to install uWSGI and gevent. If eventlet is found installed, then it is going to be preferred over uwsgi+gevent.
You were right. With uninstalling eventlet package the problem is solved. But I have to say, it is difficult to get this from the documentation. That is kind of irrational when I use uWSGI with gevent async mode, the extension picks eventlet.
Well, this started because you explicitly selected the gevent web server by passing async_mode='gevent', while using uWSGI, which is also irrational.
The documentation covers the order in which the different async modes are tried until one works. If you want to disable the auto-detection you can, but then you need to pass the correct async_mode value.
Not really sure how you expect the extension to figure out what you want to do, either you tell it the way you want things to work, or you don't tell anything and the extension tries to determine what to do based on what tools you installed. If you have any improvements to suggest to the documentation please let me know, or send them in a pull request.
Most helpful comment
This is explained in the documentation. The extension picks the best async mode based on what you have installed in your virtualenv. It seems you have more stuff than you need there. If you want to use uWSGI, then you need to install uWSGI and gevent. If eventlet is found installed, then it is going to be preferred over uwsgi+gevent.