前言
即时通讯的基础功能开发完成后,最终是需要部署到生产环境中的,但是在实际的部署过程后经过测试后是无法进行通讯,通过对问题的分析后发现,原来在生产环境中前后端服务无法进行握手操作。
因为服务端启动的时候配置IP地址为本机的IP地址(服务器的IP地址),而客户端Websocket是IP地址映射后的互联网地址,由于在开发环境测试的时候是在同一个局域网中,不存在影响。
但是部署到线上,会存在前后端服务无法进行握手操作,经过资料的查询得知可以用Nginx进行解决,
经过具体实践操作后解决了上述问题,本篇文章就做一个记录。
解决过程
Websocket握手操作之前的请求是http请求,经过协议升级将http协议升级到websocket协议,根据可以看出来WebSocket是基于Http协议的
1
2
3
4
5
6
7
8
9
10
11
12Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.9
Cache-Control:no-cache
Connection:Upgrade
Host:127.0.0.1:8089
Origin:http://localhost:8085
Pragma:no-cache
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
Sec-WebSocket-Key:x0VGUzvDx0sckOzd7fjdTw==
Sec-WebSocket-Version:13
Upgrade:websocket
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
观察上面的请求头(Request Headers)发现这段类似HTTP协议的握手请求中,多了几个东西。
1 | Upgrade: websocket |
字段名 | 说明 |
---|---|
Upgrade:Upgrade | 协议升级为WebSocket协议 |
Connection:Upgrade | 标识该HTTP请求是一个协议升级请求 |
Sec-WebSocket-Key: x0VGUzvDx0sckOzd7fjdTw== | 客户端采用base64编码的24位随机字符序列
Sec-WebSocket-Protocol: chat, superchat | 协议扩展类型
Sec-WebSocket-Version: 13 | 客户端支持WebSocket的版本
response headers响应头
1 | connection:Upgrade |
sec-websocket-accept:服务器接受客户端HTTP协议升级的证明。
表示已经接受到请求协议切换成功,成功建立Websocket。HTTP已经完成了它的任务,后面就按照Websocket协议进行。
关于HTTP协议和Websocket协议搞清楚后,下面就进入到Nginx的配置中啦。
Nginx配置
对于Nginx的教程网上有很多的,可以自行百度查询,此处我贴出自己的配置
1 |
|
Nginx 代理 WebSocket 的要点是设置Upgrade和Connection响应头
proxy_pass 要代理到的url
proxy_http_version 代理时使用的http版本
proxy_set_header 如果请求头中有Upgrade,就直接设置到响应头中,并把Connection设置为upgrade。
proxy_set_header X-Real-IP 给代理设置原http请求的ip,填写$remote_addr 即可
proxy_set_header Connection 因为代理的ws协议,所以http请求头的Connection设置为Upgrade
至此,Nginx反向代理WebSocket的配置就完成了,重启Nginx,用Websocket连接试试,
如果Websocket成功连接,说明Nginx反向代理Websocket已经成功了。
说明:
客户端的Websocket地址填写上解析后的域名 ws://xxxx/ xxxx为解析后的域名不需要http://
比如连接Websocket的IP地址和端口为8089为xxxx:8089,那么我在使用Sunny-Ngrok做内网穿透的时候的配置如下
dream.xxxxx.com为外网访问的域名也可以看作是解析后的域名。
客户端配置Websocket的配置中直接填写http://后面的就可以。
本机电脑上测试
由于本机电脑为局域网,需要模拟真实的生产环境的话就需要需要内网穿透服务
我使用了两个内网穿透服务
一个绑定的是项目本身,一个绑定Websocket的IP和端口。
Sunny-Ngrok
utools中的提供的内网穿透服务
使用utools工具提供的内网穿透服务绑定项目
截图
Sunny-Ngrok绑定Websocket的IP和端口
截图
内网穿透完成后,启动Nginx服务,域名访问项目,登录账户,进行测试,如果可以收到消息,证明没有问题。
总结
关于即时通讯项目已经完成了,后续如果有修改的会进行更新