10

我正在尝试设置一个小型服务器来处理 HTTP 和 socketio 请求——我没有太多设置服务器的经验,但现在 apache2 可以很好地服务于 http。但是,socketio 事务不断失败,错误代码为 400(错误请求),并且我在服务器日志中看到一些奇怪的错误。有时我看到一个 engineio 错误,服务器响应“错误请求”和代码 400,但它总是告诉我需要启动 eventlet 服务器:

[Mon Jan 11 19:02:54.068282 2016] [:error] [pid 4908:tid 140274923673344] [client 100.96.180.39:53473]     return ws(environ, start_response)
[Mon Jan 11 19:02:54.068305 2016] [:error] [pid 4908:tid 140274923673344] [client 100.96.180.39:53473]   File "/var/www/projectENV/lib/python2.7/site-packages/engineio/async_eventlet.py", line 10, in __call__
[Mon Jan 11 19:02:54.068342 2016] [:error] [pid 4908:tid 140274923673344] [client 100.96.180.39:53473]     raise RuntimeError('You need to use the eventlet server.')
[Mon Jan 11 19:02:54.068380 2016] [:error] [pid 4908:tid 140274923673344] [client 100.96.180.39:53473] RuntimeError: You need to use the eventlet server. See the Deployment section of the documentation for more information.
[Mon Jan 11 19:02:54.253124 2016] [:error] [pid 4909:tid 140274940458752] WARNING:engineio:Invalid session cde3f9aadbee4794bf9d7bb98d0b396e

我的服务器代码非常基本:

 from flask import Flask
 import flaskext.couchdb
 from flask.ext.socketio import SocketIO

 # for socketio
 import eventlet
 eventlet.monkey_patch()

 # creation of server & db objects
 app = Flask(__name__)

 # socketio initialization
 socketio =  SocketIO(app, async_mode='eventlet')

 # import views once site properties are set
 from app import views

 if __name__== "__main__":
     socketio.run(app, debug=True)

我的客户端代码,用 python 编写,直接使用文档中的 socketio-client 库:

from socketIO_client import SocketIO, LoggingNamespace
with SocketIO(SERVER_URL, 80, LoggingNamespace) as socketIO:
    socketIO.emit('aaa')
    socketIO.wait(seconds=1)

socketio.run(app)应该为我启动 eventlet 服务器吗?为什么服务器会吐回错误的请求(有时)?

4

1 回答 1

16

要使 WSGI 应用程序在线可用,您需要通过 Web 服务器公开它。当您的应用程序使用 Flask-SocketIO 时,普通的 WSGI Web 服务器是不够的,因为 WSGI 不支持 WebSocket,因此 WSGI 协议需要非官方扩展来支持该协议。

Flask-SocketIO 支持多种支持 WebSocket 的 Web 服务器。看来您在虚拟环境中安装了 eventlet,这就是为什么您收到必须使用 eventlet Web 服务器的错误。

您似乎没有意识到,您正在使用 Apache 的 Web 服务器(我猜是 mod_wsgi?)。这个 web 服务器是一个普通的分叉 web 服务器,它不是一个与 eventlet 兼容的 web 服务器。

socketio.run(app) 不应该为我启动 eventlet 服务器吗?

是的,如果您要通过运行您的应用程序,socketio.run(app)您将获得一个完全启用的 eventlet Web 服务器。但是您没有这样做,而是在 apache 上运行它。Eventlet 有一个 Web 服务器,而 apache 有一个 Web 服务器,它们是两个独立的 Web 服务器,都能够运行 WSGI 应用程序。但是 apache 不支持 WebSocket。

Flask-SocketIO 文档描述了一些有效的部署方案。

于 2016-01-12T15:25:50.747 回答