В связи с этим спешу поделиться конфигами и небольшими подробностями.
Для тех кто не знал, ранее проксирование было возможно через сторонний модуль, с ограничениями которые многих не устраивали. Ну, да мы не об этом.
Теперь на одном порту можно проксировать http и ws траффик, более того, например под одним SSL сертификатом, и все это с родным знакомым синтаксисом.
Ws доступны начиная с версии 1.3.13, а буквально сегодня добавили поддержку еще в модули ngx_http_uwsgi_module и ngx_http_scgi_module для 1.3.14
Для описания механизма ws в Nginx оставлю здесь цитату Максима Дунина.
Short version:
Устанавливает тоннель между клиентом и бекендом.
Long version, чтобы два раза не вставать:
Вообще протокол WebSocket работает с помощью механизма Upgrade,
присутствующего в HTTP/1.1, превращая соединение между клиентом и
сервером из HTTP/1.1 в WebSocket.Есть, однако, нюанс: этот hop-by-hop механизм, он в нормальных
условиях не может проходить через proxy-сервера. Для forward
proxy в стандарте WebSocket есть затычка: клиентам предлагается
использовать CONNECT, чтобы пройти через proxy-сервер без потерь
(тот же CONNECT используется для того, чтобы через forward proxy
можно было ходить на https-ресурсы). Но с reverse proxy такой
подход не работает, т.к. клиент о proxy вообще не знает, и
требуется специальная обработка.В вышеупомянтом коммите — добавлен специальный режим работы,
который позволяет nginx’у установить тунель между клиентом и
бекендом, если бекенд прислал ответ 101 Switching Protocols (и
если клиент действительно хотел upgrade’ить соединение).Следует иметь ввиду, что по умолчанию nginx убирает из запроса на
бекенд hop-by-hop заголовки Upgrade и Connection, так что для
того, чтобы бекенд узнал, что клиент хотел upgrade’ить соединение,
эти заголовки надо явно пробросить.
Конфиг.
Простой пример, как теперь можно заставить работать ws:
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; ... }
Скорее всего вашему приложению нужны будут другие цифры таймаута, поэтому не копипастите бездумно;)
ссылка на оригинал статьи http://habrahabr.ru/post/171757/
Добавить комментарий