Reputation: 5159
I'm working on a Flask-SocketIO server that works just fine.
However, I'm getting lots of requests like this in my server log:
"GET /socket.io/?EIO=3&transport=polling&t=LBS1TQt HTTP/1.1"
Here's the code I'm working with:
from flask import Flask, render_template, redirect, url_for
from flask_socketio import SocketIO, emit
import json
def load_config():
# configuration
return json.load(open('/etc/geekdj/config.json'))
config = load_config()
geekdj = Flask(__name__)
geekdj.config["DEBUG"] = config["debug"]
geekdj.config["SECRET_KEY"] = config["secret_key"]
geekdj.config.from_envvar("FLASKR_SETTINGS", silent=True)
socketio = SocketIO(geekdj)
@geekdj.route('/')
def index():
return render_template('index.html')
# SocketIO functions
@socketio.on('connect')
def chat_connect():
print ('connected')
@socketio.on('disconnect')
def chat_disconnect():
print ("Client disconnected")
@socketio.on('broadcast')
def chat_broadcast(message):
print ("test")
emit("chat", {'data': message['data']})
if __name__ == "__main__":
socketio.run(geekdj, port=8000)
and the JS in index.html
:
<script src="//cdn.socket.io/socket.io-1.4.5.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
// the socket.io documentation recommends sending an explicit package upon connection
// this is specially important when using the global namespace
var socket = io.connect('http://localhost:8000');
socket.on('connection', function(socket) {
socket.emit('foo', {foo: "bar"});
socket.join("test");
});
socket.on('joined', function(data) {
console.log('Joined room!');
console.log(data["room"]);
});
});
I'd prefer to be using actual Websockets if possible, does anyone know why SocketIO is falling back on polling?
Upvotes: 7
Views: 11460
Reputation: 1097
Did the first answer work? If so, you should accept it. If not, post your requirements.txt please.
I had the same problem and found the resolution by fully absorbing the documentation page:
The asynchronous services that this package relies on can be selected among three choices:
- eventlet is the best performant option, with support for long-polling and WebSocket transports.
- gevent is supported in a number of different configurations. The long-polling transport is fully supported with the gevent package,
but unlike eventlet, gevent does not have native WebSocket support.
To add support for WebSocket there are currently two options.
Installing the gevent-websocket package adds WebSocket support to
gevent or one can use the uWSGI web server, which comes with
WebSocket functionality. The use of gevent is also a performant
option, but slightly lower than eventlet.- The Flask development server based on Werkzeug can be used as well, with the caveat that it lacks the performance of the other two
options, so it should only be used to simplify the development
workflow. This option only supports the long-polling transport.
Basically, I didn't have evenlet nor gevent-websocket in my virtual environment. I installed eventlet, and transport upgrade to websocket was near instantaneous! Hope this helps.
Upvotes: 10
Reputation: 5159
I found the solution in this other Q/A.
It turns out that SocketIO sets a cookie with the most recent connection type that worked. In my case, it was polling.
So, I changed the SocketIO connect statement in my JS from
var socket = io.connect('http://localhost:8000');
to
var socket = io.connect(null, {port: 8000, rememberTransport: false});
and now there is activity in the websockets type under the Network tab in the Chrome developer tools (which there wasn't previously):
Upvotes: 7