我有一个设置,我想在一台服务器上运行多个WSGI应用程序,并使用Flask-SocketIO socketio-server在其中一个应用程序中进行通信。
我已经通过带有eventlet的gunicorn提供了我的WSGI应用程序,正如Flask-SocketIO手册中建议的那样:
gunicorn --worker-class eventlet -w 1 myapp:application
这为应用提供了所有权利,设置的内部代码如下所示(__init__.py
):
from flask import Flask
from werkzeug.wsgi import DispatcherMiddleware
from Pyro4.utils.httpgateway import pyro_app as gateway
from myapp.extensions import socketio
from myapp.views.vue_js import vue
from config import PYRO_REGEX
def configure_blueprints(app):
app.register_blueprint(vue)
def register_extensions(app):
socketio.init_app(app)
app = Flask(__name__, instance_relative_config=True, template_folder='static', static_url_path='')
app.config.from_object('config')
configure_blueprints(app)
register_extensions(app)
# Set up WSGI application middleware to serve both the pyro httpgateway and this application
# through the same server
application = DispatcherMiddleware(gateway, {
'/app': app
})
这样可以正常工作,但我的应用程序现在已经没有websocket连接了。如何在此配置中使Flask-SocketIO工作?
问题是当尝试连接到/ socketio时,与socketio服务器的javascript连接收到404错误。
我是否需要将Javascript端交给我的应用程序的子域?
如果是这种情况,连接字符串将如何查看?
现在我的连接字符串如下所示:Javascript端的'http://' + document.domain + ':' + location.port + '/'
PS: 我这样做的原因是我需要从与应用程序其余部分相同的域提供Pyro4网关,否则浏览器会对我对REST调用pyro4应用同源策略限制。因此,如果这太复杂,并且有更简单的方法来达到我的最终目标,那么我也是开放的。
答案 0 :(得分:1)
我用DispatchMiddleware做了一些实验,其中一个安装是使用socket.io的Flask应用程序
self.app.wsgi_app = DispatcherMiddleware(self.app.wsgi_app,{'/aaa/bbb':sockioapp,
'/ccc/ddd':normalapp})
这里,sockioapp
是启用了SocketIO的Flask对象,normalapp
不是。
因此sockioapp
的URL将是http://localhost:3000/aaa/bbb
,而socket.io端点是/socket.io
,并且它无法建立连接(如预期的那样)-我想更改/aaa/bbb/socket.io
为此,我将路径添加到Socket.IO客户端。
socket = io.connect({transports: ["websocket"], path:"/aaa/bbb/socket.io" });
现在,SocketIO服务器。我不确定是否必须这样做。我希望DispatcherMiddleware
可以将/aaa/bbb
路径神奇地添加到/socket.io
中,事实确实如此。因此,服务器保持原状,无需添加路径。
socketio = SocketIO(socketioapp, host="0.0.0.0")
足够了。服务器端的所有内容都得到了神奇的处理,无需更改调度程序中间件。
如果您有多个使用socket.io的应用程序,那么我认为最好有单独的命名空间。
答案 1 :(得分:0)
Socket.IO端点默认为/socket.io
。由于您应用的第一个入口点是DispatcherMiddleware
,因此不会映射到应用程序。
我没试过这个,但是如果你在/socket.io
前缀下的调度程序中间件上为你的应用添加一个重复条目,那么Socket.IO请求将被路由到正确的位置。
答案 2 :(得分:0)
我解决了我的问题,但遗憾的是,这不是一个真正的修复,而是更多的解决方法。
我的应用程序不在默认路由上的原因是另一个wsgi-app(pyro httpgateway)正在进行一些重定向,当我尝试将它放在/pyro
时导致无限重定向路由。
我现在修改了部分代码,并将pyro应用程序放在上面提到的路径上,同时将我的应用程序保留在主路径/
上。
这允许SocketIO适用于我的主应用程序,尽管如上所述更多的是解决方法而不是完整修复。