5

I have used the following example code from http://blog.miguelgrinberg.com/post/easy-websockets-with-flask-and-gevent/page/4 and this works fine when I run it using the test server e.g. python myapp.py I can connect to it and send messages

from flask import Flask, render_template
from flask.ext.socketio import SocketIO, emit

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

@app.route('/')
def index():
    return render_template('index.html')

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

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

@socketio.on('connect', namespace='/test')
def test_connect():
    emit('my response', {'data': 'Connected'})

@socketio.on('disconnect', namespace='/test')
def test_disconnect():
    print('Client disconnected')

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

The problem is when I move this same code to a server that is using Apache to serve Flask I get errors.

RuntimeError: You need to use a gevent-socketio server.

Config file for Apache host is:

 WSGIApplicationGroup %{GLOBAL}
 WSGIScriptAlias / /var/www/public/flaskApp/flaskApp.wsgi

 <Location /var/www/public/flaskApp/flaskApp/>
    Order allow,deny
    Allow from all
</Location>

Is it possible to run SocketIO/Flask and have it work through Apache?

user4143585
  • 105
  • 1
  • 2
  • 6

1 Answers1

2

Your /var/www/public/flaskApp/flaskApp.wsgi file that Apache is running your app through doesn't use a socketio-capable server.

The tutorial you're reading states

The extension is initialized in the usual way, but to simplify the start up of the server a custom run() method is provided by the extension. This method starts gevent, the only supported web server. Using gunicorn with a gevent worker should also work.

The uWSGI documentation has a section on running in gevent mode, but Miguel commented:

uwsgi does not work with this extension either, because it does not allow a custom gevent loop to be used. Gunicorn does work, the command is in the documentation.

So, Gunicorn. From the docs:

An alternative is to use gunicorn as web server, using the worker class provided by gevent-socketio. The command line that starts the server in this way is shown below:

gunicorn --worker-class socketio.sgunicorn.GeventSocketIOWorker module:app

In short, ensure that you're running with something that provides the gevent worker.

Community
  • 1
  • 1
Celeo
  • 5,583
  • 8
  • 39
  • 41
  • 1
    uwsgi does not work with this extension either, because it does not allow a custom gevent loop to be used. Gunicorn does work, the command is in the documentation. – Miguel Grinberg Apr 28 '15 at 18:48
  • 1
    Thanks for the info. Gunicorn is what I use myself. – Celeo Apr 28 '15 at 18:56
  • @Miguel I thought that might be the case. I did read the documentation but it just seemed odd that their was no way to somehow proxy through Apache to Flask to handle the socketio. – user4143585 Apr 29 '15 at 08:46
  • 1
    @user4143585 yes, but the problem is that this is outside of the wsgi spec, which is what apache/uwsgi implement. – Miguel Grinberg Apr 29 '15 at 14:14
  • Were you able to find a solution? I am also running into the same problem. – ApplePie Nov 11 '22 at 18:18