简体   繁体   English

Websocket导轨(Faye-websocket)握手错误代码200-AWS ElasticBeanstalk,nginx,puma

[英]Websocket rails (Faye-websocket) handshake error code 200 - AWS ElasticBeanstalk, nginx, puma

I'm trying to get a websockets enabled app working, but I'm running into an error when trying to connect: 我正在尝试启用启用了websockets的应用程序,但是尝试连接时遇到了错误:

WebSocket connection to 'ws://[domain.com]/' failed: Error during WebSocket handshake: Unexpected response code: 200

I'm following the tutorial here ( https://devcenter.heroku.com/articles/ruby-websockets ) which uses the gem faye-websocket. 我在这里关注使用gem faye-websocket的教程( https://devcenter.heroku.com/articles/ruby-websockets )。 It works fine locally (with puma), but when I try to deploy it to AWS ElasticBeanstalk that's running nginx + puma the websocket request can't connect. 它在本地(与puma一起)运行良好,但是当我尝试将其部署到运行nginx + puma的AWS ElasticBeanstalk时,websocket请求无法连接。

I'm creating a new WebSocket connection with the following javascript (with my own domain): 我正在使用以下JavaScript(使用我自己的域)创建新的WebSocket连接:

var ws = new WebSocket("ws://[domain.com]/");


Following the tutorial, I created a middleware class that checks incoming requests for websocket, and handles it accordingly. 在学习完本教程之后,我创建了一个中间件类,该类检查传入的Websocket请求,并进行相应的处理。 On my local server, the request environment hash looks like this: 在我的本地服务器上,请求环境哈希看起来像这样:

"rack.errors"=>#>, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "SCRIPT_NAME"=>"", "CONTENT_TYPE"=>"text/plain", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"2.11.1", "GATEWAY_INTERFACE"=>"CGI/1.2", "REQUEST_METHOD"=>"GET", "REQUEST_PATH"=>"/", "REQUEST_URI"=>"/", "HTTP_VERSION"=>"HTTP/1.1", "HTTP_HOST"=>"localhost:3000", "HTTP_CONNECTION"=>"Upgrade", "HTTP_PRAGMA"=>"no-cache", "HTTP_CACHE_CONTROL"=>"no-cache", "HTTP_UPGRADE"=>"websocket", "HTTP_ORIGIN"=>" http://localhost:3000 ", "HTTP_SEC_WEBSOCKET_VERSION"=>"13", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36", "HTTP_ACCEPT_ENCODING"=>"gzip, deflate, sdch", "HTTP_ACCEPT_LANGUAGE"=>"en-US,en;q=0.8", “ rack.errors” =>#>,“ rack.multithread” => true,“ rack.multiprocess” => false,“ rack.run_once” => false,“ SCRIPT_NAME” =>“”,“ CONTENT_TYPE” => “文本/纯文本”,“ QUERY_STRING” =>“”,“ SERVER_PROTOCOL” =>“ HTTP / 1.1”,“ SERVER_SOFTWARE” =>“ 2.11.1”,“ GATEWAY_INTERFACE” =>“ CGI / 1.2”,“ REQUEST_METHOD” =>“ GET”,“ REQUEST_PATH” =>“ /”,“ REQUEST_URI” =>“ /”,“ HTTP_VERSION” =>“ HTTP / 1.1”,“ HTTP_HOST” =>“ localhost:3000”,“ HTTP_CONNECTION” = >“升级”,“ HTTP_PRAGMA” =>“无缓存”,“ HTTP_CACHE_CONTROL” =>“无缓存”,“ HTTP_UPGRADE” =>“ websocket”,“ HTTP_ORIGIN” =>“ http:// localhost:3000 ” ,“ HTTP_SEC_WEBSOCKET_VERSION” =>“ 13”,“ HTTP_USER_AGENT” =>“ Mozilla / 5.0(Macintosh; Intel Mac OS X 10_10_5)AppleWebKit / 537.36(KHTML,例如Gecko)Chrome / 50.0.2661.102 Safari / 537.36”,“ HTTP_ACCEPT_ENCODING” =>“ gzip,deflate,sdch”,“ HTTP_ACCEPT_LANGUAGE” =>“ zh-CN,en; q = 0.8”,

Whereas on AWS it looks like this : 在AWS上看起来像这样:

{"rack.version"=>[1, 3], "rack.errors"=>#, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "SCRIPT_NAME"=>"", "CONTENT_TYPE"=>"text/plain", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"2.11.1", "GATEWAY_INTERFACE"=>"CGI/1.2", "REMOTE_ADDR"=>"127.0.0.1", "REQUEST_METHOD"=>"GET", "REQUEST_PATH"=>"/", "REQUEST_URI"=>"/", "HTTP_VERSION"=>"HTTP/1.0", "HTTP_HOST"=>"[domain.com]", "HTTP_X_FORWARDED_FOR"=>"194.80.196.162", "HTTP_CONNECTION"=>"close", "HTTP_PRAGMA"=>"no-cache", "HTTP_CACHE_CONTROL"=>"no-cache", "HTTP_ORIGIN"=>" http://[domain.com] ", "HTTP_SEC_WEBSOCKET_VERSION"=>"13", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36", "HTTP_ACCEPT_ENCODING"=>"gzip, deflate, sdch", "HTTP_ACCEPT_LANGUAGE"=>"en-US,en;q=0.8", {“ rack.version” => [1,3],“ rack.errors” =>#,“ rack.multithread” => true,“ rack.multiprocess” => false,“ rack.run_once” => false, “ SCRIPT_NAME” =>“”,“ CONTENT_TYPE” =>“文本/纯文本”,“ QUERY_STRING” =>“”,“ SERVER_PROTOCOL” =>“ HTTP / 1.1”,“ SERVER_SOFTWARE” =>“ 2.11.1”,“ GATEWAY_INTERFACE“ =>” CGI / 1.2“,” REMOTE_ADDR“ =>” 127.0.0.1“,” REQUEST_METHOD“ =>” GET“,” REQUEST_PATH“ =>” /“,” REQUEST_URI“ =>” /“,” HTTP_VERSION “ =>” HTTP / 1.0“,” HTTP_HOST“ =>” [domain.com]“,” HTTP_X_FORWARDED_FOR“ =>” 194.80.196.162“,” HTTP_CONNECTION“ =>”关闭“,” HTTP_PRAGMA“ =>”否-缓存”,“ HTTP_CACHE_CONTROL” =>“无缓存”,“ HTTP_ORIGIN” =>“ http:// [domain.com] ”,“ HTTP_SEC_WEBSOCKET_VERSION” =>“ 13”,“ HTTP_USER_AGENT” =>“ Mozilla / 5.0( Macintosh; Intel Mac OS X 10_10_5)AppleWebKit / 537.36(KHTML,例如Gecko)Chrome / 50.0.2661.102 Safari / 537.36“,” HTTP_ACCEPT_ENCODING“ =>” gzip,deflate,sdch“,” HTTP_ACCEPT_LANGUAGE“ =>” en-US, en; q = 0.8“,

So I can see that on AWS, the request headers HTTP_CONNECTION and HTTP_UPGRADE aren't being switched over to websockets. 因此,我可以看到在AWS上,请求标头HTTP_CONNECTION和HTTP_UPGRADE并未切换到websockets。

However, I've tried setting my nginx configuration but I can't figure out how it works (eg https://gist.github.com/KeithP/f8534c04d20c2b4e4b1d ) 但是,我试图设置我的nginx配置,但是我不知道它是如何工作的(例如https://gist.github.com/KeithP/f8534c04d20c2b4e4b1d

files:
  "/etc/nginx/conf.d/websockets.conf" :
    content: |
      upstream backend {
          server unix:///var/run/puma/my_app.sock;
      }

      server {
          listen 80;

          access_log /var/log/nginx/access.log;
          error_log /var/log/nginx/error.log;

          server_name env1.t3tiiauce6.us-west-2.elasticbeanstalk.com

          # prevents 502 bad gateway error
          large_client_header_buffers 8 32k;

          location / {
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header Host $http_host;
              proxy_set_header X-NginX-Proxy true;

              # prevents 502 bad gateway error
              proxy_buffers 8 32k;
              proxy_buffer_size 64k;

              proxy_pass http://backend;
              proxy_redirect off;

              location /assets {
                root /var/app/current/public;
              }

              # enables WS support
              location /cable {
                proxy_pass http://backend;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
              }
          }
      }


From what I understand, this routes requests going towards /cable to the backend rails app and upgrades the connection to websockets. 据我了解,这会将请求发送到/ cable到后端rails应用程序,并将连接升级到websockets。 However when I try /cable I get a 404 error (as there is no matching route). 但是,当我尝试/ cable时,出现404错误(因为没有匹配的路由)。

So how can I get my rails app handshaking with websockets correctly? 那么,如何正确使用websockets实现Rails应用程序握手? Any help would be much appreciated!! 任何帮助将非常感激!! I've also tried using the websocket-rails gem and got handshake error code 500 我也尝试过使用websocket-rails gem并得到握手错误代码500

Finally managed to get it to work! 终于设法使其正常工作! In the end, the following file put in the .ebextensions folder got it going: 最后,将以下文件放在.ebextensions文件夹中可以正常运行:

server {
  listen 80;
  server_name localhost; # need to listen to localhost for worker tier

  location / {
    proxy_pass http://my_app; # match the name of upstream directive which is defined in another file
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }

  location /websocket {
    proxy_pass http://my_app/websocket;
    proxy_set_header Host $host;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection Upgrade;
  }

  location /assets {
    alias /var/app/current/public/assets;
    gzip_static on;
    gzip on;
    expires max;
    add_header Cache-Control public;
  }

  location /public {
    alias /var/app/current/public;
    gzip_static on;
    gzip on;
    expires max;
    add_header Cache-Control public;
  }
}

And my Javascript changed to: 我的Javascript更改为:

var ws = new WebSocket("ws://[domain.com]/websocket");

Hope it helps anyone who comes across similar issues! 希望它对遇到类似问题的任何人有所帮助!

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

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