Nginx代理
从WebSocket的通信过程得知,WebSocket通信的第一步是发送一个Http请求,这个请求可以通过Nginx的Http模块代理,但是后面具体的信息交换则是通过WebSocket协议,Nginx的Http模块是否可以继续代理呢

上图的几个步骤分别是
- 浏览器提交受个http请求到nginx
- nginx将http请求转发给服务端
- 服务端返回101响应给nginx
- nginx将服务端的响应返回给浏览器
- 浏览器发送websocket消息给nginx
- nginx将websocket消息转发给服务端
通过上面5、6个步骤可知,nginx确实代理了websocket协议,这是因为nginx通过首次http代理后,就会将两个tcp连接绑定起来,后续websocket协议就可以通过这两个绑定的tcp连接进行通信,这里有个注意的地方,nginx在代理http时,如果没有配置与服务端的长连接,nginx在收到服务端的消息后,会关闭与服务端的tcp连接,但是101状态是个例外,如果nginx收到的服务端的http消息的状态是101,则不会关闭和服务端的tcp连接,但是会受到超时配置的影响,比如proxy_read_timeout。另外一点,如果响应状态为101,虽然nginx不会转发Upgrade请求头,但是客户端请求头必须包括Upgrade,否则nginx收到101响应后不会认为是一个完成的请求,就不会把响应返回给客户端
Nginx配置
nginx在http模块代理websocket协议和代理普通的http请求有一些不同
1 | location /connectWebSocket { |
主要的不同是以下几点
- proxy_set_header Upgrade $http_upgrade:这个配置是因为nginx不会转发Upgrade请求头
- proxy_set_header Connection “upgrade”:这个配置是因为nginx不会转发Connection: Upgrade请求头,如果不配置这个的话,就是变成Connection: close
- proxy_read_timeout 1000:这个配置在普通http的情况下,代表服务端的响应时间,而在代理websocket的情况下,由于tcp连接不是一次性的了,所以这个配置可以理解为最大空闲时间,这个配置是因为如果不配置大一点的话,nginx与服务端的tcp连接会太容易断开