运行 WebFaction 上的 Flask-SocketIO 通过 mod_wsgi

Running Flask-SocketIO on WebFaction through mod_wsgi

我已经使用 mod_wsgi 在 Webfaction 上部署了一个 Flask 应用程序。我的应用程序非常简单,但确实实现了给我带来麻烦的 Flask-SocketIO。我的代码在我的本地主机上运行良好,但现在它在我的 Webfaction 服务器上是 运行,客户端无法连接到我的套接字。我不太确定我的问题是从哪里来的——我假设我没有正确设置我的 apache 配置文件,但这可能不是真的。

在客户端,我在对 websocket 的 GET 和 POST 调用中收到 400(错误请求)错误。我间歇性地看到一条警告,通知我套接字在建立连接之前已关闭。我偶尔也会收到一个错误,指出在 WebSocket 握手期间出现错误。

我的apachehttpd.conf文件如下:

ServerRoot "/home/< user >/webapps/< my_app >/apache2"

LoadModule authz_core_module modules/mod_authz_core.so
LoadModule dir_module        modules/mod_dir.so
LoadModule env_module        modules/mod_env.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule mime_module       modules/mod_mime.so
LoadModule rewrite_module    modules/mod_rewrite.so
LoadModule setenvif_module   modules/mod_setenvif.so
LoadModule wsgi_module       modules/mod_wsgi.so
LoadModule unixd_module      modules/mod_unixd.so

Listen 18161
KeepAlive On
SetEnvIf X-Forwarded-SSL on HTTPS=1
ServerLimit 1
StartServers 1
MaxRequestWorkers 5
MinSpareThreads 1
MaxSpareThreads 3
ThreadsPerChild 5

WSGIDaemonProcess < my_app > processes=2 threads=12 python-path=/home/< user >/webapps/< my_app >:/home/< user >/webapps/< my_app >/lib/python2.7
WSGIProcessGroup < my_app >
WSGIRestrictEmbedded On
WSGILazyInitialization On

WSGIScriptAlias / /home/< user >/webapps/< my_app >/wsgi.py

我看过一些关于 proxy_module 和 proxy_http_module 的帖子,但我不太确定我是否需要它,如果需要,该如何配置它。非常感谢有关此问题的任何指导!

关于 proxy_moduleproxy_http_module 的内容是使用 Apache 作为后端 websockets 应用程序的前端代理。它不适用于您要执行的操作。

mod_wsgi 不太适合服务于 websocket 应用程序。不要使用它 - 相反,请使用 Deployment section of the Flask-SocketIO docs.

中推荐的部署选项之一

例如,要在WebFaction 上使用第一个推荐选项(即嵌入式服务器),首先安装eventlet 模块。我假设您此时已经安装了 Flask 和 Flask-SocketIO。

接下来,通过 WebFaction 控制面板安装 'custom websockets app listening on port' 应用程序。记下应用程序的分配端口,然后在控制面板中将应用程序分配给网站。您不需要打开应用程序的端口。

接下来,将您的 Flask-SocketIO 应用程序配置为 运行 在分配给您的 websockets 应用程序的端口上。最简单的方法是将端口传递给socketio.run,例如:

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

在您的 javascript 中,像这样连接:

var socket = io.connect('http://' + document.domain + ':' + location.port + namespace);

最后,只有 运行 应用程序:

python2.7 whatever.py

到那时,您的应用程序将启动并运行在您分配给您设置的网站的任何域上。

当您加载站点时,JS 将整理来自 document.domainlocation.port 的连接信息。如果您打开浏览器的开发工具(Chrome 检查器或其他工具),您将看到与 ws://yourdomain.com/ 建立的 websockets 连接。

希望对您有所帮助!