Nginx 和 Flask-socketio Websockets:存在但没有消息传递?

2024-05-26

我在让 Nginx 与 Python Flask-socketio 库(基于 gevent)很好地配合时遇到了一些麻烦。目前,由于我们正在积极开发,我正在尝试让 Nginx 充当代理。对于发送页面,我可以通过直接运行flask-socketio应用程序或通过gunicorn运行来使其工作。一个问题是:websocket 消息传递似乎不起作用。页面已成功托管并显示。但是,当我尝试使用网络套接字时,它们不起作用。它们足够活跃,以至于 websocket 认为它们已连接,但它们不会发送消息。如果我删除 Nginx 代理,它们就可以工作。当我尝试发送消息时,Firefox 出现此错误:

Firefox 无法与位于 ws:///socket.io/1/websocket/ 的服务器建立连接。

其中网址是服务器所在的位置,唯一 ID 只是一堆随机数字。它似乎已经做了足够的事情来保持连接有效(例如,客户端认为它已连接),但无法通过 websocket 发送消息。我必须认为这个问题与代理的某些部分有关,但是我在调​​试问题可能是什么时遇到了很大的麻烦(部分原因是这是我第一次使用 Flask-socketIO 和 nginx)。我用于 nginx 的配置文件是:

user       <user name>;  ## This is set to the user name for the remote SSH session
worker_processes  5;

events {
  worker_connections  1024;  ## Default: 1024
}

http {
  default_type application/octet-stream;
  log_format   main '$remote_addr - $remote_user [$time_local]  $status '
    '"$request" $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for"';
  sendfile     on;
  server_names_hash_bucket_size 128; # this seems to be required for some vhosts

  server {
    listen 80;
    server_name _;
    location / {
        proxy_pass http://localhost:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }
  } 
}

我将配置文件作为一般示例和 websocket 特定示例的混合体,但尝试摆弄它并没有解决问题。另外,当我在 wsgi 模式下使用 Flask app.wsgi_app 时,我正在使用 werkzeug Proxy_Fix 调用。我已经尝试过使用和不使用它,但都无济于事。如果有人有一些见解,我会洗耳恭听。


我设法解决了这个问题。这些问题并不是 Flask-socketio 特有的,而是 Ubuntu、NginX 和 gevent-socketio 特有的。存在两个重要问题:

  1. Ubuntu 12.04 有一个真正古老的 nginx 版本(稳定版本为 1.1.19 与 1.6.x)。为什么?谁知道。我们所知道的是,这个版本不以任何有用的方式支持 websockets,因为 1.3.13 是关于最早的 https://github.com/LearnBoost/socket.io/wiki/Nginx-and-Socket.io你应该使用。
  2. 默认情况下,gevent-socketio 希望您的套接字位于 /socket.io 位置。您可以升级整个 HTTP 连接,但我在使其正常工作时遇到了一些麻烦(尤其是在我将 SSL 加入其中之后)。
  3. 我修复了 #1,但在摆弄它时,我通过 nginx 进行了清除,并安装了 apt-get...Ubuntu 上 nginx 的默认版本。然后,我对为什么事情比以前更糟糕感到困惑。许多.conf 文件在这场战斗中勇敢地献出了生命。

如果尝试在此配置中调试 Websocket,我建议执行以下步骤:

  1. 通过“nginx -v”检查您的 nginx 版本。如果低于 1.4,请升级。
  2. 检查您的 nginx.conf 设置。您需要确保连接升级。
  3. 检查您的服务器 IP 和端口是否与您的 nginx.conf 反向代理匹配。
  4. 检查您的客户端(即套接字 io.js)是否使用正确的协议连接到正确的位置和端口。
  5. 检查您被阻止的端口。我在 EC2 上,所以你必须手动打开 80 (HTTP) 和 443 (SSL/HTTPS)。

刚刚检查了所有这些事情后,有一些要点。

  1. 在 Ubuntu 上升级到最新的稳定 nginx 版本(full ref https://www.digitalocean.com/community/articles/how-to-install-the-latest-version-of-nginx-on-ubuntu-12-10)可以通过以下方式完成:

    sudo apt-get install python-software-properties
    sudo apt-get install software-properties-common
    sudo add-apt-repository ppa:nginx/stable
    sudo apt-get update
    sudo apt-get install nginx
    

    在 Windows 等系统中,您可以使用安装人员 http://nginx.org/en/download.html并且不太可能得到不好的版本。

  2. 许多配置文件可能会令人困惑,因为 nginx 在 2013 年左右正式添加了套接字,使得早期的解决方法配置变得过时。现有的配置文件往往不会涵盖 nginx、gevent-socketio 和 SSL 的所有基础,而是将它们分开(Nginx 教程 https://chrislea.com/2013/02/23/proxying-websockets-with-nginx/, Gevent-socketio http://gevent-socketio.readthedocs.org/en/latest/server_integration.html, Node.js 与 SSL https://www.exratione.com/2013/06/websockets-over-ssl-with-nodejs-and-nginx/)。带有flask-socketio(包装gevent-socketio)和SSL的nginx 1.6的配置文件是:

    user <user account, probably optional>;
    worker_processes  2;
    error_log  /var/log/nginx/error.log;
    pid        /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include mime.types;
        default_type       application/octet-stream;
        access_log         /var/log/nginx/access.log;
        sendfile           on;
    #   tcp_nopush         on;
        keepalive_timeout  3;
    #   tcp_nodelay        on;
    #   gzip               on;
        client_max_body_size 20m;
        index              index.html;
    
        map $http_upgrade $connection_upgrade {
                default upgrade;
                ''      close;
        }
    
        server {
          # Listen on 80 and 443
          listen 80 default;
          listen 443 ssl;  (only needed if you want SSL/HTTPS)
          server_name <your server name here, optional unless you use SSL>;
    
          # SSL Certificate (only needed if you want SSL/HTTPS)
          ssl_certificate <file location for your unified .crt file>;
          ssl_certificate_key <file location for your .key file>;
    
          # Optional: Redirect all non-SSL traffic to SSL. (if you want ONLY SSL/HTTPS)
          # if ($ssl_protocol = "") {
          #   rewrite ^ https://$host$request_uri? permanent;
          # }
    
          # Split off basic traffic to backends
          location / {
            proxy_pass http://localhost:8081; # 127.0.0.1 is preferred, actually.
            proxy_redirect off;
          }
    
          location /socket.io {
            proxy_pass          http://127.0.0.1:8081/socket.io; # 127.0.0.1 is preferred, actually.
            proxy_redirect off;
            proxy_buffering off; # Optional
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
          }
        }
     }
    
  3. 检查 Flask-socketio 是否使用正确的端口很容易。这足以与上述内容一起使用:

    from flask import Flask, render_template, session, request, abort
    import flask.ext.socketio
    FLASK_CORE_APP = Flask(__name__)
    FLASK_CORE_APP.config['SECRET_KEY'] = '12345' # Luggage combination
    SOCKET_IO_CORE = flask.ext.socketio.SocketIO(FLASK_CORE_APP)
    
    @FLASK_CORE_APP.route('/')
    def index():
        return render_template('index.html')
    
    @SOCKET_IO_CORE.on('message')
    def receive_message(message):
        return "Echo: %s"%(message,)
    
    SOCKET_IO_CORE.run(FLASK_CORE_APP, host=127.0.0.1, port=8081)
    
  4. 对于像 socketio.js 这样的客户端,连接应该很容易。例如:

    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js"></script>
    <script type="text/javascript">
        var url = window.location.protocol + document.domain + ':' + location.port,
            socket = io.connect(url);
        socket.on('message', alert);
        io.emit("message", "Test")
    </script>
    
  5. 开放端口实际上更多的是服务器故障 https://serverfault.com/search?q=unblock%20port or a 超级用户 https://superuser.com/search?q=unblock%20port问题,因为这在很大程度上取决于您的防火墙。对于 Amazon EC2,请参阅here http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html.

  6. 如果尝试所有这些都不起作用,那就哭吧。然后返回到列表顶部。因为您可能只是不小心重新安装了旧版本的 nginx。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Nginx 和 Flask-socketio Websockets:存在但没有消息传递? 的相关文章

  • 在模块之间传递 Socket.IO 套接字的正确方法是什么?

    目前我有一个 getter setter 套接字模块 如下所示 var socket module exports getSocket getSocket module exports setSocket setSocket functio
  • 使用 Django 管理界面的 Node.js 应用程序

    我想使用 node js 构建一个新应用程序 但它需要相当多的后端管理 而我宁愿不必构建 我在 django 中有一些现有代码 并且非常喜欢用于处理后端管理的内置管理界面 我是否可以使用 nginx 之类的东西将所有流量定向到我的 node
  • 如何在部署应用程序 Elastic beanstalk 上修改 NGINX 配置

    我需要向 nginx conf 添加一些位置 以便环境 URL 指向 app php 我已经使用 vi 修改了该文件 重启 NGINX 就可以了 但我需要在使用时自动加载此配置电子部署 我已阅读并尝试过 https docs aws ama
  • 使用 nginx 将 PATCH 请求代理为 POST

    我尝试使用 nginx 将 HTTP PATCH 请求重定向到 HTTP POST 请求 我还尝试了以下配置 但它不起作用 我收到 400 错误请求 http map request method my method default req
  • nginx 代理重定向,带有来自 uri 的端口

    我正在尝试使用 nginx 进行重定向 这个想法是将某些端口的 uri id 1234 重定向到 localhost 1234 固定端口的重定向 location id 1234 rewrite id 1234 1 break proxy
  • Squid 可以在 nginx 后面运行吗?

    我正在尝试在 nginx 后面运行一个鱿鱼服务器 我这样配置 nginx server listen 8080 location proxy pass http localhost 3128 proxy set header Host ho
  • PHP Socket Java 消息交换

    我正在尝试在 PHP 页面和正在运行的 Java 服务器之间进行通信 只是通过套接字进行简单的字符串交换 这是我处理连接的线程的 Java 代码 InputStream in clientSocket getInputStream Buff
  • 如何使用 HTML5 与 UDP 套接字通信?

    我拥有的 正在运行的 C 应用程序服务器 准备将数据发送到应该发送到 HTML5 页面或应用程序的客户端 我想要的是 考虑到 c 服务器和 HTML5 应用程序都是系统本地的 有没有办法使用 udp 端口 与 HTML5 进行通信 我知道的
  • lua-socket:unix 域套接字?

    我使用的是 lua socket 3 0rc1 3 Ubuntu Trusty 附带的 和 lua 5 1 我正在尝试监听 unix 域套接字 我能找到的唯一示例代码是this http lua users org lists lua l
  • Java 客户端到服务器未知来源

    我有一个简单的乒乓球游戏 需要通过网络工作 服务器将创建一个带有球和 2 个球棒位置的游戏 当客户端连接到服务器时 服务器将创建一个名为 PongPlayerThread 的新类 它将处理客户端到服务器的输入和输出流 我的服务器工作100
  • 有人在node/socket.io 中成功实现了动态命名空间吗?

    含义 用户对应用程序进行身份验证 gt 应用程序设置socket io连接的命名空间 http www socketioserver com NAMESPACE 并且节点服务器相应地响应无需针对特定名称空间进行硬编码 到那个特定的命名空间
  • socket.io 作为客户端

    有什么方法可以将socketio作为客户端运行 不是浏览器 而是nodejs脚本 我需要将数据从服务器广播到一些客户端 浏览器 和另一台linux机器 仅运行nodejs来获取变量 没有浏览器 欢迎任何想法 Regards github上有
  • Flask APScheduler + Gunicorn 工作人员 - 在套接字修复后仍在运行任务两次

    我有一个 Flask 应用程序 我使用 Flask APScheduler 在我的数据库上运行计划查询并通过 cron 作业发送电子邮件 我通过 Gunicorn 使用以下配置运行我的应用程序并通过主管进行控制 program myapp
  • 如何在Windows上模拟socket.socketpair

    标准Python函数套接字 套接字对 https docs python org 3 library socket html socket socketpair不幸的是 它在 Windows 上不可用 从 Python 3 4 1 开始 我
  • 使用 PM2 将节点作为服务运行 - 连接被拒绝

    我正在关注this https www digitalocean com community tutorials how to set up a node js application for production on ubuntu 16
  • 使用 Flask 和 SQLAlchemy 在 Celery 任务中未更新数据库

    我正在使用 Flask 和 SQLAlchemy 编写 Web 应用程序 我的程序需要在后台处理一些内容 然后将这些内容标记为在数据库中已处理 使用标准 Flask Celery 示例 http flask pocoo org docs 0
  • Android socket.io应用程序无法连接到node.js服务器

    我的应用程序使用socket io 无法连接到node js 服务器 服务器节点 js var app require http createServer var io require socket io app app listen 10
  • 如何在flask中使用g.user全局

    据我了解 Flask 中的 g 变量 它应该为我提供一个全局位置来存储数据 例如登录后保存当前用户 它是否正确 我希望我的导航在登录后在整个网站上显示我的用户名 我的观点包含 from Flask import g among other
  • socket.io 的良好初学者教程? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 从 Flask 访问 Heroku 变量

    我已经使用以下命令在 Heroku 配置中设置了数据库变量 heroku config add server xxx xxx xxx xxx heroku config add user userName heroku config add

随机推荐

  • 在 BeautifulSoap 输出中将
    替换为空格

    我正在用 BeautifulSoap 抓取一些链接 但是它似乎完全忽略了 br tags 这是我所在的 URL 的源代码的相关部分scraping h1 class para title A quick brown fox jumps ov
  • plpgsql 中的伪加密() 函数采用 bigint

    我正在开发一个生成随机 ID 的系统 如答案 2 所示here https stackoverflow com questions 12575022 generating an instagram or youtube like ungue
  • 将 Valo 主题的间距和小部件大小缩小到 Reindeer 主题的间距和小部件大小

    The new 勇敢主题 https vaadin com valo现在是 Vaadin 7 3 应用程序中的默认设置 该主题通过小部件 按钮 字段等 进行视觉渲染 这些小部件比之前的默认主题要大得多 更宽和更高 Reindeer http
  • 在重定向文件 (>output.txt) 中显示带重音符号的字符

    example mode con cp gt tmp output tmp notepad tmp output tmp show Statut du p riph rique CON Page de codes 850 代替 Statut
  • 将事件绑定到动态添加的元素

    我正在尝试使用 jquery 将函数绑定到新添加的元素 我已经尝试了很多在线示例 但不知怎的 没有任何效果对我有用 我创建了一个带有 id 和一个按钮的表单 在提交 ajax 时从另一个页面加载元素并在当前网站上插入 html 一切似乎都工
  • 如何按比例缩放 SVG

    我已从 Illustrator 导出 SVG 并希望设置 SVG 的高度并按比例设置宽度比例 这是 SVG 示例
  • 使用 JMS + CCDT 文件连接到 IBM MQ 时出现负载平衡问题

    我们正在尝试使用 CCDT 文件和 JMS 配置连接到 IBMMQ 我们能够连接到它 但这里有一个问题 由于我们使用 spring 使用 CCDT 文件设置连接工厂 因此它在应用程序启动时初始化一次 但不幸的是它一次只选择一个队列管理器 即
  • 如何检查深层 lambda 表达式中的 null 值? [复制]

    这个问题在这里已经有答案了 如何检查深层 lambda 表达式中的 null 值 举例来说 我有一个嵌套了几层的类结构 我想执行以下 lambda x gt x Two Three Four Foo 我希望它在 二 三 或 四 为 null
  • MATLAB 子图标题和轴标签

    我有以下脚本来最终绘制 4 x 2 子图 files getAllFiles preliminaries n size files cases cell 1 n m cell 1 n for i 1 1 n S load files i c
  • Mac 终端错误:-bash: /Users/tim/.profile: 没有这样的文件或目录

    每次我打开新的终端窗口时 我都会看到以下内容 bash Users tim profile No such file or directory 我不知道为什么会发生这种情况 也不知道到哪里去解决它 我的个人资料位于 Users tim ba
  • 如何根据内容从 numpy 数组中提取行?

    作为标题 例如 我有一个 2d numpy 数组 如下所示 33 21 1 33 21 2 32 22 0 33 21 3 34 34 1 我想根据第一列和第二列中的内容顺序提取这些行 在这种情况下 我想获得3个不同的2d numpy数组
  • 为什么 JLabel 实例只显示 8 行?

    这是代码片段 import java awt BorderLayout import java awt HeadlessException import java awt event ActionEvent import java awt
  • Aurelia 验证规则:无法解析访问器函数

    看来其他地方也存在各种问题aurelia validation模块 但我还没有看到任何可以解决我遇到的具体问题的内容 我有一个模型类 其定义和验证规则如下 我的模型 js my model name full short Validatio
  • 将 3D 场景导入babylonJS

    所以我今天读到巴比伦JS http blogs msdn com b eternalcoding archive 2013 06 27 babylon js a complete javascript framework for build
  • Django ORM:检索帖子和最新评论而不执行 N+1 查询

    我有一个非常标准的基本社交应用程序 具有状态更新 即帖子 和每个帖子的多个评论 给定以下简化模型 是否可以使用 Django 的 ORM 高效检索所有帖子以及最新两条评论与每个帖子关联 而不执行 N 1 查询 也就是说 无需执行单独的查询来
  • 设备锁定时扫描外围设备

    我的中央管理器可以在前台和后台检测新的外围设备 我知道这一点是因为当它发现新的外围设备时我会触发 UNNotification 但是 当设备锁定时 它似乎不会继续扫描新的外围设备 在我的能力范围内 我启用了使用 LE 配件的后台模式以及远程
  • 使用管道将文件夹从 Bitbucket 存储库推送到公共服务器

    我在 Bitbucket 存储库中启用了管道 并且需要在每次构建后在我的服务器中运行 Angular 2 构建并部署 dist 文件夹 在执行构建命令后创建 我的 bitbucket pipelines yml 文件中有以下内容 image
  • 简单的 svg css 进度圈

    我正在尝试寻找一种方法来实现没有动画的简单进度圈 静态 我发现的示例具有非常不同的百分比偏移量 如下例所示 如何以这样的方式制作进度圈 如果我提供偏移量为 50 那么它恰好是 50 半填充 u absoluteCenter position
  • 设计涟漪

    我正在尝试使用以 riak 作为数据库的设备创建身份验证 我找到了同样的 ORM 策略https github com frank06 devise ripple https github com frank06 devise ripple
  • Nginx 和 Flask-socketio Websockets:存在但没有消息传递?

    我在让 Nginx 与 Python Flask socketio 库 基于 gevent 很好地配合时遇到了一些麻烦 目前 由于我们正在积极开发 我正在尝试让 Nginx 充当代理 对于发送页面 我可以通过直接运行flask socket