java webSocket wss踩坑总结

一、前言

之前项目中有一套http环境下的webSocket前后台项目(ws协议);
突然测试环境要切换成https,导致webSocket通信遇到了问题(wss协议)。

以下是遇到的问题与解决方法个人总结。

二、问题与解决方法

1.问题概述:vconsole中只报错WebSocket Open Error,但是没有具体错误原因。

问题详情:前端项目是vue移动端app项目,其中有vconsole可以查看debug时控制台打印的信息;
切换为https后,前端代码执行建立webSocket连接的代码时,建立失败,报错WebSocket Open Error(这个错误是自己定义的),但是没有错误原因;
此时后台没有任何日志打印。

解决方法:想办法把app访问的网页url获取到,使用chrome浏览器访问,在F12中,找到了错误信息:

SecurityError: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.

翻译为, 可能无法从通过HTTPS加载的页面启动不安全的WebSocket连接

终于找到了报错语句,进入下一步。

2.问题描述:An insecure WebSocket connection may not be initiated from a page loaded over HTTPS

问题详情:之前在http环境,前端建立webSocket连接使用的url是没有问题的,样例为:

ws://123.123.123.123:20000/webSocket

而现在,由于是 https环境,因此再使用 ws协议,就会报这个错。

解决方法:把ws改为 wss即可,样例如下:

wss://123.123.123.123:20000/webSocket

3.问题描述:修改为wss后,依然无法建立webSocket连接,依然无法从vconsole中找到错误详情;使用chrome进行测试,才发现新的错误信息。

问题详情:新的错误如下:

im.js:1993 WebSocket connection to 'wss://123.123.123.123:20000/webSocket' failed: Error in connection establishment: net::ERR_CERT_COMMON_NAME_INVALID

其中,im.js是前端项目中的一个js文件;
错误信息是: net::ERR_CERT_COMMON_NAME_INVALID

解决方法:这个错误大概意思是说,用一个错误的域名访问了某个节点的https资源(可能是Host错误导致)。

(1)分析发现,chrome打开的前端测试页面的 url为域名形式的,样例如下:

https://xxx.xxx.com/result.html

(2)而在这个result.html页面中,引入了im.js文件;在im.js文件中,执行了建立webSocket连接的前端代码;建立连接代码中,访问后台webSocket的 url为IP形式的:

wss://123.123.123.123:20000/webSocket

(3)虽然服务器的ip就是123.123.123.123,域名就是xxx.xxx.com,但是由于服务器是https的,https证书中配置的是*.xxx.com(证书中配置的域名应该是不能自己修改的);
chrome中访问https://xxx.xxx.com,会提示连接是 安全的;
chrome中访问https://123.123.123.123,会提示连接是 不安全的。

(4)应该是,由于chrome测试时,当前页面url为https://xxx.xxx.com,因此发送报文的Host参数也为xxx.xxx.com;
而此时发送wss://123.123.123.123:20000/webSocket的请求,就会因为Host与请求资源的url不一致导致报错(123.123.123.123 != xxx.xxx.com),即使服务器的ip与域名就是123.123.123.123 与xxx.xxx.com也不行。

(5)所以,把 wss的url从ip改为域名,才解决了 net::ERR_CERT_COMMON_NAME_INVALID问题。样例如下:

//这个不行
//wss://123.123.123.123:20000/webSocket
//这个可以
wss://xxx.xxx.com:20000/webSocket

三、其它笔记

1.本次服务器从http变为https遇到的问题中(ws变为wss)大部分是前端需要修改的
Java后台WebSocket服务端的代码不需要修改,还是用的ws连接时的代码(Java后台WebSocket服务端代码不区分ws与wss)**

Java后台WebSocket代码主要语句如下:

//这个配置webSocket连接用的url
@ServerEndpoint("/webSocket")

//连接建立,这个方法会被调用
@OnOpen
public void onOpen(WsSession session, EndpointConfig config){//自己写处理逻辑}

//连接关闭,这个方法会被调用
@OnClose
public void onClose(){/*自己写处理逻辑*/}

//前端给后台发来byte数组格式的消息,这个方法会被调用
@OnMessage
public void onMessage(byte[] message){/*自己写处理逻辑*/}

//前端给后台发来String格式的消息,这个方法会被调用
@OnMessage
public void onMessage(String message){/*自己写处理逻辑*/}

//前端给后台发来String格式的消息,这个方法会被调用
@OnError
public void onError(WsSession session, Throwable error){/*自己写处理逻辑*/}

2.从http变为https遇到的问题中(ws变为wss)nginx的配置也不用专门为https修改,使用之前http(ws)时的即可

nginx可用样例如下:

upstream websocket_cluster {
  server 10.1.2.3:20000;
}

server {
  listen 20000;
  server_name 123.123.123.123;

#因为是测试服务器,虽然是https,但是不用专门配置ssl等参数也可以使用
#ssl on;  
  access_log /home/user/nginx/logs/websocket.log main;
  error_log /home/user/nginx/logs/websocket.error.log;
  
  location /webSocket {
    expires -1;
    proxy_set_header Host $http_host;
    
    proxxy_pass http://websocket_cluster/webSocket;
    proxy_redirect off;
    proxy_read_timeout 18000;
    proxy_connect_timeout 18000;
    proxy_send_timeout 18000;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size 2g;
    
    proxy_http_bersion 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    
  }
  
}

说明:
(1)前端访问wss://xxx.xxx.com:20000/webSocket时,dns服务器会把xxx.xxx.com转为123.123.123.123,然后就会访问到这个nginx

(2)根据nginx的配置,20000端口的请求,访问的后缀为/webSocket,可以转发到http://websocket_cluster/webSocket,即http://10.1.2.3:20000/webSocket

(3)Java的WebSocket后台部署在10.1.2.3服务器上,开启的端口是20000,使用了注解@ServerEndpoint("/webSocket"),然后收到前端建立webSocket连接的请求后,@OnOpen注解标注的方法就会被执行了

(4)Java后台后续收到前端发来的消息后,@OnMessage注解标注的方法就会被执行了。

(5)Java后台可以获取到WsSession对象,用来主动给前端发送消息。(这也是webSocket的主要功能,后台主动给前端发消息)

(6)nginx日志中,发现,建立webSocket连接时,日志中并不会打印信息;只有关闭webSocket连接时,日志中才会增加一行记录

(7)nginx中,webSocket主要的配置就是这两个:

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐梦想永不停

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值