Назад | Перейти на главную страницу

nginx проксирует веб-сокеты, должно быть что-то не хватает

У меня есть базовое приложение для чата, написанное на node.js с использованием express и socket.io; он отлично работает при подключении напрямую к узлу через порт 3000

Но не работает, когда я пытаюсь использовать nginx v1.4.2 в качестве прокси.

Я начинаю использовать карту подключений

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

Затем добавьте местоположения

location /socket.io/ {
   proxy_pass  http://node;
   proxy_redirect off;
   proxy_http_version 1.1;
   proxy_set_header Host $http_host;
   proxy_set_header X-Forwarded-For $remote_addr;
   proxy_set_header X-Request-Id $txid;
   proxy_set_header X-Session-Id $uid_set+$uid_got;
   proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection $connection_upgrade;
   proxy_buffering off;

   proxy_read_timeout 86400;
    keepalive_timeout 90;

    proxy_cache off;

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

location /web-service/ {
   proxy_pass  http://node;
   proxy_redirect off;
   proxy_http_version 1.1;
   proxy_set_header Host $http_host;
   proxy_set_header X-Forwarded-For $remote_addr;
   proxy_set_header X-Request-Id $txid;
   proxy_set_header X-Session-Id $uid_set+$uid_got;
   proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection $connection_upgrade;
   proxy_buffering off;

   proxy_read_timeout 86400;

    keepalive_timeout 90;

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

   rewrite /web-service/(.*) /$1 break;

   proxy_cache off;
}

Они созданы с использованием всех советов, которые я смог найти. Журнал ошибок не показывает ошибок. (кроме случаев, когда я останавливаю узел, чтобы проверить, работает ли регистрация ошибок)

Когда я использую nginx, я вижу соединение с веб-сокетом в инструментах разработчика со статусом 101; но вкладка кадров под результатами пуста. Единственное отличие, которое я вижу в заголовках ответов, - это разница в регистре - «обновление» и «Обновление» - через nginx:

Connection:upgrade
Date:Fri, 08 Nov 2013 11:49:25 GMT
Sec-WebSocket-Accept:LGB+iEBb8Ql9zYfqNfuuXzdzjgg=
Server:nginx/1.4.2
Upgrade:websocket

прямо из узла

Connection:Upgrade
Sec-WebSocket-Accept:8nwPpvg+4wKMOyQBEvxWXutd8YY=
Upgrade:websocket

вывод из узла (при использовании через nginx)

debug - served static content /socket.io.js
debug - client authorized
info  - handshake authorized iaej2VQlsbLFIhachyb1
debug - setting request GET /socket.io/1/websocket/iaej2VQlsbLFIhachyb1
debug - set heartbeat interval for client iaej2VQlsbLFIhachyb1
debug - client authorized for
debug - websocket writing 1::
debug - websocket writing 5:::{"name":"message","args":[{"message":"welcome to the chat"}]}
debug - clearing poll timeout
debug - jsonppolling writing io.j[0]("8::");
debug - set close timeout for client 7My3F4CuvZC0I4Olhybz
debug - jsonppolling closed due to exceeded duration
debug - clearing poll timeout
debug - jsonppolling writing io.j[0]("8::");
debug - set close timeout for client AkCYl0nWNZAHeyUihyb0
debug - jsonppolling closed due to exceeded duration
debug - setting request GET /socket.io/1/xhr-polling/iaej2VQlsbLFIhachyb1?t=1383911206158
debug - setting poll timeout
debug - discarding transport
debug - cleared heartbeat interval for client iaej2VQlsbLFIhachyb1
debug - setting request GET /socket.io/1/jsonp-polling/iaej2VQlsbLFIhachyb1?t=1383911216160&i=0
debug - setting poll timeout
debug - discarding transport
debug - clearing poll timeout
debug - clearing poll timeout
debug - jsonppolling writing io.j[0]("8::");
debug - set close timeout for client iaej2VQlsbLFIhachyb1
debug - jsonppolling closed due to exceeded duration
debug - setting request GET /socket.io/1/jsonp-polling/iaej2VQlsbLFIhachyb1?t=1383911236429&i=0
debug - setting poll timeout
debug - discarding transport
debug - cleared close timeout for client iaej2VQlsbLFIhachyb1

при прямом подключении к узлу клиент не начинает опрос.

Нормальные выходы узла http-материала отлично работают с nginx.

Ясно, что чего-то не вижу, но я застрял, спасибо :)

Вы пробовали минимальную конфигурацию, например:

location /socket.io/ {
      proxy_pass http://node;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
}

Обратите внимание на изменение с $ http_host на $ host, поскольку в некоторых случаях их значения могут отличаться: https://stackoverflow.com/questions/15414810/whats-the-difference-of-host-and-http-host-in-nginx

У меня была такая же проблема, когда я представил nginx для проксирования Web Socket. Проблема заключалась в том, что в nodejs я принудительно установил соединение сразу с Web Socket. При удалении этой силы он сначала согласовывается при опросе, а затем обновляется автоматически:

На стороне клиента я прокомментировал транспорт:

//transports:['websocket', 'polling'] this was not permiting my connection with nginx

io(this.adress, {query: 'auth_cookie='+this.auth_cookie});

Также удаляю конфигурацию транспорта на стороне сервера.

Для полноты это моя конфигурация nginx:

server {
  listen 80;

  server_name demo2.example.com;

  location /socket.io {
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header Host $host;
       proxy_pass http://demo2.example.com:3012/socket.io;
       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "Upgrade";
  }

  location / {
       proxy_pass http://demo2.example.com:81;

  }
}

Надеюсь это поможет