ljzsdut
GitHubToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

04 Nginx配置 Web Socket

一、Nginx代理的方式

客户端和代理服务器建立连接并发送请求,代理服务器端接收客户端的请求后与具体的后端服务器建立连接,并把请求分发给后端服务器进行处理,最后再将服务器的响应结果反馈给客户端。

二、Nginx如何支持WebSocket

WebSocket 和HTTP虽然是不同协议,但是两者“握手”方式兼容。通过HTTP升级机制,使用HTTP的Upgrade和Connection协议头的方式可以将连接从HTTP升级为WebSocket。浏览器请求如下图所示:

1654248702720

三、Http升级为WebSocket

因为WebSocket协议是一个hop-by-hop协议(此类头部字段只对单次转发有效,会因为转发给缓存/代理服务器而失效),为了让Nginx代理服务器可以将来自客户端的Upgrade请求发送到后端服务器,要求Upgrade和Connection的头信息必须被显式的设置。

img

代理服务器分别与客户端和服务器建立连接,由于WebSocket连接是长时间保持的,即长连接,所以代理服务器需要允许这些连接处于打开状态,而不是像对待HTTP使用的短连接那样将其关闭。

可以通过修改Nginx的配置文件方式解决此问题,代理请求后端服务器的请求头设置:

#监听websocket
upstream websocket {
    #ip_hash;
    #转发到服务器上相应的ws端口
    server localhost:3344;
    #server localhost:8011;
}
server {
    listen 80;
    server_name schoolsocket.zhuzhida.vip;
    location /ws {
        #转发到http://websocket
        proxy_pass http://websocket;
        proxy_read_timeout 300s;  #设置超时时间
        proxy_send_timeout 300s;
 
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # 以下3行,实现升级到websocket协议  
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

如果某个location的请求中既包含ws请求,也包含普通的http请求,此时需要根据请求类型自行判断是否开启:

nginx官方文档配置如下:可以实现根据不同请求判断是否向upstream server开启websoket协议

http {
    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;
        }
    }

nginx中的map指令:根据客户端请求中$http_upgrade 的值,来构造改变$connection_upgrade的值,即根据变量$http_upgrade的值创建新的变量$connection_upgrade。上例中,如果如果$http_upgrade的值为空字符串,则$connection_upgrade的值为“close”;如果大括号中没有任何规则被匹配到,则使用默认规则default upgrade;。简而言之,上例中 $connection_upgrade 的值会一直是 upgrade,然后如果 $http_upgrade为空字符串的话,那值会是 close。

HTTP的Upgrade协议头机制用于将连接从HTTP连接升级到WebSocket连接,Upgrade机制使用了Upgrade协议头和Connection协议头;为了让Nginx可以将来自客户端的Upgrade请求发送到后端服务器,Upgrade和Connection的头信息必须被显式的设置。

四、总结

通过Http升级机制将Http升级为WebSocket。Nginx代理服务器通过修改配置的方式解决了WebSocket属于hop-by-hop协议的问题,并通过保持分别与客户端和服务端的连接一直处于打开状态从而实现WebSokcet的代理。

原文链接:https://blog.csdn.net/summer_fish/article/details/118960408

默认情况下,如果代理服务器在60秒内未传输任何数据,则将关闭连接。使用proxy_read_timeout指令可以增加此超时 。或者,代理服务器可以配置为定期发送WebSocket ping帧以重置超时并检查连接是否仍然存在。

原文链接:https://www.jianshu.com/p/5d20c1a24cae

其他:https://network.51cto.com/article/704378.html