Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask-SocketIO server using polling instead of websockets

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?

like image 796
RPiAwesomeness Avatar asked Feb 13 '16 19:02

RPiAwesomeness


People also ask

Does Socket.IO use WebSockets?

Socket.IO is NOT a WebSocket implementation. Although Socket.IO indeed uses WebSocket for transport when possible, it adds additional metadata to each packet.

What protocol does Socket.IO use?

Socket.IO primarily uses the WebSocket protocol with polling as a fallback option, while providing the same interface.

Does flask use WebSockets?

Flask-Sock is designed to be a simple extension to implement WebSocket communication between a client and the server.

What is the difference between Socket.IO and WebSocket?

socket.io allowed me to send/emit messages by specifying an event name. In the case of socket.io a message from server will reach on all clients, but for the same in websockets I was forced to keep an array of all connections and loop through it to send messages to all clients.


1 Answers

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.

like image 114
jacob Avatar answered Sep 20 '22 01:09

jacob