MyTetra Share
Делитесь знаниями!
Время создания: 07.05.2018 22:41
Автор: https://habr.com/users/astlock/
Текстовые метки: websocket
Раздел: WebSocket

В Nginx наконец добавили долгожданную функциональность по проксированию Websockets.

В связи с этим спешу поделиться конфигами и небольшими подробностями.


Для тех кто не знал, ранее проксирование было возможно через сторонний модуль, с ограничениями которые многих не устраивали. Ну, да мы не об этом.



Теперь на одном порту можно проксировать http и ws траффик, более того, например под одним SSL сертификатом, и все это с родным знакомым синтаксисом.


Ws доступны начиная с версии 1.3.13, а буквально сегодня добавили поддержку еще в модули ngx_http_uwsgi_module и ngx_http_scgi_module для 1.3.14


Вот, что говорит документация на счет используемого механизма.


Для превращения соединения между клиентом и сервером из HTTP/1.1 в WebSocket используется доступный в HTTP/1.1 механизм смены протокола.


Но есть сложность: поскольку “Upgrade” является hop-by-hop заголовком, то он не передаётся от клиента к проксируемому серверу. При прямом проксировании клиенты могут использовать метод CONNECT, чтобы обойти эту проблему. Однако при обратном проксировании такой подход не работает, так как клиент ничего о проксирующем сервере не знает, и требуется специальная обработка на проксирующем сервере.


Начиная с версии 1.3.13, в nginx предусмотрен особый режим работы, который позволяет установить туннель между клиентом и проксируемым сервером, если проксируемый сервер вернул ответ с кодом 101 (Switching Protocols), и клиент попросил сменить протокол с помощью заголовка “Upgrade” в запросе.


Как уже отмечалось выше, hop-by-hop заголовки, включая “Upgrade” и “Connection”, не передаются от клиента к проксируемому серверу, поэтому, для того чтобы проксируемый сервер узнал о намерении клиента сменить протокол на WebSocket, эти заголовки следует передать явно:


Конфиг.


Простой пример:


location /ws/ {

proxy_pass http://localhost:8080;

proxy_http_version 1.1;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection "upgrade";


}



Более сложный пример, в котором значение поля “Connection” в заголовке запроса к проксируемому серверу зависит от наличия поля “Upgrade” в заголовке запроса клиента:


http {

map $http_upgrade $connection_upgrade {

default upgrade;

'' close;

}


server {

...


location /ws/ {

proxy_pass http://localhost:8080;

proxy_http_version 1.1;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection $connection_upgrade;

}

}



И немного неочевидный, но важный параметр это proxy_read_timeout, который стоит по дефолту в значении 60s, по истечении которых коннект обрывается, чего в случае ws обычно совсем не нужно.


Поэтому, мы добавили:


http {

...

proxy_read_timeout 950s;

...

}



Скорее всего вашему приложению нужны будут другие цифры таймаута, поэтому не копипастите бездумно;)

Так же в этом разделе:
 
MyTetra Share v.0.53
Яндекс индекс цитирования