带有 NGINX 和 http 2 的 Socket.io

Posted

技术标签:

【中文标题】带有 NGINX 和 http 2 的 Socket.io【英文标题】:Socket.io with NGINX and https2 【发布时间】:2017-10-30 15:26:24 【问题描述】:

我有node.js 应用程序,由nginx 提供服务。我无法连接 socket.io 并不断收到 404 POST 请求以建立连接。

它在本地工作,所以它一定是NGINX 问题。

  # HTTP - redirect all requests to HTTPS:
  server 
     listen 80;
     listen [::]:80;
     return 301 https://$host$request_uri;
  
  # HTTPS - proxy requests on to local Node.js app:
  server 
     listen 443 ssl http2;
     server_name example.com;
     ssl on;
     ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
     ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
     ssl_session_timeout 5m;
     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
     ssl_prefer_server_ciphers on;
     ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
     location / 
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header X-Forwarded-Proto https;
        proxy_pass http://127.0.0.1:8080;
        proxy_ssl_session_reuse off;
        proxy_set_header Host $http_host;
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;
     

感谢您的帮助。

【问题讨论】:

您使用的是哪个 nginx 版本?它可能还不支持 HTTP2。 最新版本。 HTTP2 工作正常,这是用于 socekts 的 NGINX 配置的问题。 你有没有初始化 socket.io 并设置为这样监听: var io = app.io; io.listen(服务器); ? @iubema 这正是我所拥有的。 【参考方案1】:

由于 Websockets 使用 HTTP 1.1 中引入的 Upgrade 标头,因此您需要在路由中专门使用此协议并将 Connection 标头设置为 upgrade

您还需要指定一个具有唯一名称的 proxy_pass 指令。

你的配置应该是这样的:

upstream sockets 
  server localhost:8080;


# HTTP - redirect all requests to HTTPS:
server 
  listen 80;
  listen [::]:80;
  return 301 https://$host$request_uri;


# HTTPS - proxy requests on to local Node.js app:
server 
     listen 443 ssl http2;
     server_name example.com;
     ssl on;
     ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
     ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
     ssl_session_timeout 5m;
     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
     ssl_prefer_server_ciphers on;
     ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

     location / 

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header Host $host;

        proxy_pass http://sockets;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;

        proxy_http_version 1.1;
        proxy_ssl_session_reuse off;
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;
     


【讨论】:

感谢您的努力。我会尽快尝试并给您反馈。 我的其他不是套接字的 API 调用应该在 proxy_passhttp://127.0.0.1:8080,所以可以有多个位置吗?一个位置处理套接字和一个正常请求? 就像套接字一样,您可以将上游重命名为不同于sockets 的名称为website 之类的名称,以便更加连贯。这也是我使用的;)【参考方案2】:

查看 NGINX 文档。

https://www.nginx.com/blog/websocket-nginx/

enter chttp 
map $http_upgrade $connection_upgrade 
    default upgrade;
    '' close;


upstream websocket 
    server 192.168.100.10:8010;


server 
    listen 8020;
    location / 
        proxy_pass http://websocket;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    

【讨论】:

您能否详细说明一下,我是 NGINX 的新手。谢谢

以上是关于带有 NGINX 和 http 2 的 Socket.io的主要内容,如果未能解决你的问题,请参考以下文章

带有可选参数的nginx和htaccess重写规则

Angular 2 “实时”更新对象。

使用nginx配置带有权限验证的反向代理

在带有协议升级的 nginx 反向代理后面运行 daphne 总是路由到 http 而不是 websocket

带有 Express 和 nginx 反向代理的 Vue Router 历史模式

带有tomcat的nginx反向代理不起作用