简体   繁体   English

Flask:一个RESTful API和SocketIO服务器

[英]Flask: A RESTful API and SocketIO Server

Background 背景

I am trying to create a simple REST API using the Flask-RESTful extension. 我正在尝试使用Flask-RESTful扩展创建一个简单的REST API。 This API will be working primarily to manage the CRUD and authentication of users for a simple service. 该API将主要用于管理CRUD和用户认证以提供简单服务。

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. 我还尝试使用Flask-SocketIO扩展创建一些Web套接字,这些用户将能够连接到这些套接字,并查看与使用该服务的其他人相关的某些数据的实时更新。 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. 看来我无法在同一Flask实例上使这两个组件(REST API和SocketIO服务器)一起工作。 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: 我之所以这样说,是因为当我运行以下命令时,REST API或SocketIO服务器都可以工作,但不能同时工作:

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? 这种设置的典型解决方案是同时具有两个不同的Flask实例吗? 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? 例如,我的SocketIO服务器是否必须向我的REST API发出请求,以检查特定用户是否已通过身份验证/授权连接到特定套接字?

You just want to run socketio.run(app, port=5005) and hit the REST API on port 5005. 您只想运行socketio.run(app, port=5005)并点击端口5005上的REST API。

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. 之所以可行,是因为Flask-SocketIO在后台运行了基于gevent(或带有1.0版本,还有eventlet)的事件化Web服务器-该服务器直接处理websocket请求(使用您通过socketio.on注册的处理程序)装饰器),并将非websocket请求传递给Flask。

The reason your code wasn't working is because both app.run and socketio.run are blocking operations. 您的代码无法正常运行的原因是因为app.runsocketio.run阻止了操作。 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. 如果确实需要在其他端口上运行Websocket连接,则需要在其他进程上生成socketio或应用程序run调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM