了解 WebSocket
可以参考维基百科:https://zh.wikipedia.org/wiki/WebSocket
或知乎网友回答:https://www.zhihu.com/question/20215561/answer/40316953
Nginx 反向代理 WebSocket (需要Nginx 1.3+)
在开发中遇到了,部分生产环境,Nginx
和 WebSocket
不在同一台服务的情况,可以通过 Nginx
做反向代理。
http {
// ...省略
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 2425; #监听2425
server_name localhost;
location / {
proxy_pass http://localhost:xxx; #代理xxx
#proxy_connect_timeout 60;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 这是配置webpysessoin丢失的问题
fastcgi_param SCRIPT_NAME "";
}
}
// ...省略
}
ws
VS wss
WebSocket
使用 ws
或 wss
的统一资源标志符,类似于 HTTP
或 HTTPS
,其中 wss
表示在 TLS 之上的 WebSocket
,相当于 HTTPS
了。
默认情况下,WebSocket
的 ws
协议使用 80
端口;运行在TLS之上时,wss
协议默认使用 443
端口。其实说白了,wss
就是 ws
基于 SSL 的安全传输,与 HTTPS
一样的道理。
如果你的网站是 HTTPS
协议的,那你就不能使用 ws://
了,浏览器会 block 掉连接,和 HTTPS
下不允许 HTTP
请求一样.
Mixed Content: The page at 'https://domain.com/' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://x.x.x.x:xxxx/'. This request has been blocked; this endpoint must be available over WSS.
这种情况,毫无疑问我们就需要使用 wss://
安全协议了,首先把 ws://
改为 wss://
,改好之后尝试会报错:
WebSocket connection to 'wss://IP地址:端口号/websocket' failed: Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR
明显的 SSL
协议错误,说明是证书的问题。
Nginx 配置支持 WSS
在配置 HTTPS
server {} 中(必须是这里,不然ssl无效)加入如下配置:
location /websocket {
proxy_pass http://127.0.0.1:xx;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
再次连接试一下,不出意外会看 101
状态码,至此大功告成。
后记
Nginx
自从 1.3
版本就开始支持 WebSocket
了,并且可以为 WebSocket
应用程序做反向代理和负载均衡。
WebSocket
和 HTTP
协议不同,但是 WebSocket
中的握手和 HTTP
中的握手兼容,它使用 HTTP
中的 Upgrade
协议头将连接从 HTTP
升级到 WebSocket
,当客户端发过来一个 Connection: Upgrade
请求头时,Nginx
是不知道的,所以,当 Nginx
代理服务器拦截到一个客户端发来的 Upgrade
请求时,需要显式来设置 Connection
、Upgrade
头信息,并使用 101
(交换协议)返回响应,在客户端和代理服务器、后端服务器之间建立隧道来支持 WebSocket
。
当然,还需要注意一下,WebSockets
仍然受到 Nginx
缺省为 60 秒的 proxy_read_timeout
的影响。这意味着,如果你有一个程序使用了 WebSockets
,但又可能超过 60 秒不发送任何数据的话,那你要么需要增加超时时间,要么实现一个 ping 的消息以保持联系。使用 ping 的解决方法有额外的好处,可以发现连接是否被意外关闭。
更具体文档详见 Nginx 官方文档:http://nginx.org/en/docs/http/websocket.html
本文转载自CSDN博文,在开发中也遇到了类似问题,有少许改动,记录下。
评论区