2019年9月10日
这天部署服务器后,发现websocket 出现连接异常,这里摘取部分重要log。
log:
java.util.concurrent.ExecutionException: javax.websocket.DeploymentException: The HTTP response from the server [404] did not permit the HTTP upgrade to WebSocket
Caused by: javax.websocket.DeploymentException: The HTTP response from the server [404] did not permit the HTTP upgrade to WebSocket
原理:
客户端与服务器端建立长连接之前,需要先通过HTTP建立连接,然后才将协议升级为websocket(本质上还是TCP协议)。
定位手段:
- 写个python脚本测试长连接
import websocket
url = 'wss://host:port/' #websocket连接地址
ws = websocket.create_connection(url)
data = 'ping'
ws.send(data)
print(ws.recv()) #服务器响应数据
ws.close() #关闭连接
上面是一段python脚本,但是我后来发现单元环境很多py依赖的包都没有安装,重新去搭环境又费事费劲,所以决定另谋他路了。
- cURL指令检测
curl -i http://localhost:9090/interserver
curl是一个命令行工具,通过指定的URL来上传或下载数据,并将数据展示出来。这里我利用工具模拟了我这边的长连接建立url,去测试我的服务器长连接是否正常。
结论是:websocket可以正常创建连接的。
- 端口检测是否正常
最后检查端口是不是异常了,指令(因为这边开启的端口是9090):
netstat -aln |grep 9090
结论是:端口木有问题
- 检查代码是否出错
长连接建立的代码,瞄一眼看看:
URI uri = new URI(String.format("ws://%s:%d/", border.getPrivateAddress(), border.getPrivatePort()));
结论是:果然代码有改动,导致连接创建失败!!
应该修改为:
URI uri = new URI(String.format("ws://%s:%d/interserver", border.getPrivateAddress(), border.getPrivatePort()));
教训:
对于代码的审核要严谨,专注去思考逻辑,否则就会给自己带来额外的工作量。
参考:
https://github.com/eclipse/jetty.project/issues/3903