简体   繁体   English

具有Nginx和Puma的WebSocket(websocket-rails)

[英]WebSockets with nginx and puma (websocket-rails)

Using the websocket-rails gem, I'm able to successfully get a websocket connection straight through puma in development, however, when deployed to production and attempting to access the websocket through nginx (passing off to puma) I have a couple of errors: one in the nginx error log: 使用websocket-rails gem,我可以在开发过程中直接通过puma成功地获得websocket连接,但是,当部署到生产环境并尝试通过nginx访问websocket(传递给puma)时,我会遇到两个错误: Nginx错误日志中的一个:

[info] 14340#0: *7 upstream timed out (110: Connection 
timed out) while proxying upgraded connection, client: 123.45.67.89, server: 
foo.com, request: "GET /websocket HTTP/1.1", upstream: 
"http://unix:///opt/oneconnect/shared/tmp/sockets/puma.sock:/websocket", host: 
"foo.com"

... and one on the javascript console: ...,然后在javascript控制台上:

WebSocket connection to 'ws://foo.com/websocket' failed: Error during WebSocket handshake: Unexpected response code: 301 

I found that nginx (the version I'm using is 1.4.6) is capable of websocket use but requires special configuration , which I've already attemped (getting the errors above). 我发现nginx(我正在使用的版本是1.4.6)可以使用websocket,但需要进行特殊配置 (我已经尝试过了)(获取上面的错误)。 Here's my nginx.conf: 这是我的nginx.conf:

upstream oneconnect {
        server unix:///opt/oneconnect/shared/tmp/sockets/puma.sock;
}

server {
        listen 80;
        listen 443 ssl;

        #ssl on;
        ssl_certificate         /etc/ssl/foo.com.crt;
        ssl_certificate_key     /etc/ssl/foo.com.key;

        root /opt/oneconnect/current/public;
        try_files $uri @oneconnect;

        access_log /opt/oneconnect/current/log/nginx.access.log;
        error_log /opt/oneconnect/current/log/nginx.error.log info;

        server_name foo.com;

        location ~ ^/(assets)/  {
          root /opt/oneconnect/current/public;
          gzip_static on;
          expires max;
          add_header Cache-Control public;
        }

        location /websocket/ {
            proxy_pass http://oneconnect;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }

        location @oneconnect {
            proxy_read_timeout 300;
            proxy_connect_timeout 300;
            proxy_redirect off;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_pass http://oneconnect;
        }
}

I'm assuming that I'm missing something simple, but I'm stumped at this point and have Googled until my eyes started bleeding. 我以为我错过了一些简单的东西,但此时我很迷and,并且一直用Google搜索,直到我的眼睛开始流血为止。 If anyone could help it would be much appreciated, or maybe just point me to how to debug these connections (it seems hard to get debug info from a ws connection). 如果有人可以提供帮助,将不胜感激,或者只是将我指向如何调试这些连接(似乎很难从ws连接中获取调试信息)。 Thanks for your time. 谢谢你的时间。

Assuming u have already initializer for eventmachine 假设您已经为eventmachine初始化了

config/initializers/eventmachine.rb
Thread.new { EventMachine.run } unless EventMachine.reactor_running? && EventMachine.reactor_thread.alive?

nginx site conf: nginx网站conf:

upstream puma_project_production {
  server unix:/var/www/project/shared/tmp/sockets/puma.sock fail_timeout=0;
}

server {
  listen 80;

  client_max_body_size 4G;
  keepalive_timeout 10;

  error_page 500 502 504 /500.html;
  error_page 503 @503;

  server_name localhost project.local;
  root /var/www/project/current/public;
  try_files $uri/index.html $uri @puma_project_production;

  location @puma_project_production {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://puma_project_production;
    # limit_req zone=one;
    access_log /var/www/project/shared/log/nginx.access.log;
    error_log /var/www/project/shared/log/nginx.error.log;
  }

  location ^~ /assets/ {

    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  location = /50x.html {
    root html;
  }

  location = /404.html {
    root html;
  }

  location @503 {
    error_page 405 = /system/maintenance.html;
    if (-f $document_root/system/maintenance.html) {
      rewrite ^(.*)$ /system/maintenance.html break;
    }
    rewrite ^(.*)$ /503.html break;
  }

  if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ ){
    return 405;
  }

  if (-f $document_root/system/maintenance.html) {
    return 503;
  }
location /websocket {
  proxy_pass http://puma_project_production;
           proxy_redirect off;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}
  location ~ \.(php|rb)$ {
    return 405;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM