美文网首页
nginx-8 WebSocket代理

nginx-8 WebSocket代理

作者: 苍老的小孩_a1fe | 来源:发表于2019-03-27 00:33 被阅读0次

    使用HTTP/1.1协议中的protocol_switch机制,可以将客户端与服务器的连接协议由HTTP/1.1升级为WebSocket。

    HTTP协议中的 hop-by-hop 头部

    • Connection
    • Keep-Alive
    • Proxy-Authenticate
    • Proxy-Authorization
    • TE
    • Trailers
    • Transfer-Encoding
    • Upgrade

    只对单个传输级连接有效,不存储于缓存,可以由代理服务器转发。

    HTTP method 之 CONNECT

    CONNECT https://www.baidu.com HTTP/1.1
    客户端告诉代理服务器,替我访问https://www.baidu.com,并将结果返回给我。


    因为Upgrade是一个hop-by-hop头部,所以不能直接从客户端传递给被代理的服务器。使用正向代理时,客户端可以CONNECT方法回避这个问题。对于反向代理却回避不了,因为客户端并不知道代理服务器的存在,更不知道请求需要在代理服务器上特殊处理。

    版本1.3.13之后,nginx实现了一种特殊操作模式:如果被代理的服务器返回带有101状态码的响应,并且客户端通过请求中的Upgrade请求protocol_switch,则允许在客户机和被代理的服务器之间设置隧道。

    正如上面所说,作为hop-by-hop头部,UpgradeConnection不能从客户端直接传递给被代理的服务器。为了让被代理的服务器可以接收到这两个头部,知道客户端想要切换到WebSocket协议,必须由代理服务器显示地转发。

    location /chat/ {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    

    在一个更复杂的例子中,向代理服务器发出的请求中Connection头字段的值取决于客户端请求报头中是否存在Upgrade字段:

    http {
        # 若http_upgrade存在,Connection值为upgrade,升级协议
        # 若http_upgrade不存在,Connection值为close,关闭连接
        map $http_upgrade $connection_upgrade {
            default upgrade;
            ''      close;
        }
    
        server {
            ...
    
            location /chat/ {
                proxy_pass http://backend;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $connection_upgrade;
            }
        }
    

    默认情况下,如果被代理的服务器在60s内未传输任何数据,连接就会被关闭。这个时间可由proxy_read_timeout指令修改。或者,可以配置被代理的服务器定期发送 WebSocket ping帧 来重置超时并检查连接是否仍然有效。

    相关文章

      网友评论

          本文标题:nginx-8 WebSocket代理

          本文链接:https://www.haomeiwen.com/subject/zqaovqtx.html