|
|||||||
Nginx и Websockets
Время создания: 07.05.2018 22:41
Автор: https://habr.com/users/astlock/
Текстовые метки: websocket
Раздел: WebSocket
Запись: Velonski/mytetra-database/master/base/15257148666vfb3a3nmn/text.html на raw.githubusercontent.com
|
|||||||
|
|||||||
В 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; ... } Скорее всего вашему приложению нужны будут другие цифры таймаута, поэтому не копипастите бездумно;) |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|