Background
I am trying to create a simple REST API using the Flask-RESTful extension. This API will be working primarily to manage the CRUD and authentication of users for a simple service.
I am also trying to create a few web sockets using the Flask-SocketIO extension that these users will be able to connect to and see real-time updates for some data related to other people using the service. As such, I need to know that these users are authenticated and authorized to connect to certain sockets.
Problem
However, I'm having a bit of trouble getting set up. It seems like I am not able to have these two components (the REST API and SocketIO server) work together on the same Flask instance. The reason I say this is because when I run the following, either the REST API or the SocketIO server will work, but not both:
from flask import Flask
from flask_restful import Api
from flask.ext.socketio import SocketIO
app = Flask(__name__)
api = Api(app)
socketio = SocketIO(app)
# some test resources for the API and
# a test emitter statement for the SocketIO server
# are added here
if __name__ == '__main__':
app.run(port=5000)
socketio.run(app, port=5005)
Question
Is the typical solution for this type of setup to have two distinct instances of Flask going at the same time? For instance, would my SocketIO server have to make requests to my REST API in order to check to see that a specific user is authenticated/authorized to connect to a specific socket?
Flask-SocketIO gives Flask applications access to low latency bi-directional communications between the clients and the server.
Flask, being a minimalist web framework, does not have WebSocket support built-in. The old Flask-Sockets extension, which has not been maintained in the last few years, provided support for this protocol.
The socketio. run() function encapsulates the start up of the web server and replaces the app. run() standard Flask development server start up. When the application is in debug mode the Werkzeug development server is still used and configured properly inside socketio.
Socket.IO is a library that enables real-time, bidirectional and event-based communication between the browser and the server.
You just want to run socketio.run(app, port=5005)
and hit the REST API on port 5005.
The reason this works is because under the hood, Flask-SocketIO is running an evented webserver based on gevent (or with the 1.0 release, also eventlet) - this server handling the websocket requests directly (using the handlers you register via the socketio.on
decorator) and is passing on the non-websocket requests to Flask.
The reason your code wasn't working is because both app.run
and socketio.run
are blocking operations. Whichever one ran first was looping, waiting for connections, never allowing the second to kick off. If you really needed to run your websocket connections on a different port you'd need to spawn either the socketio or the app run
call on a different process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With