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,去测试我的服务器长连接是否正常。

FAQ(88): The HTTP response from the server [404] did not permit the HTTP upgrade to WebSocket?_java

结论是:websocket可以正常创建连接的。

 

 

  • 端口检测是否正常

最后检查端口是不是异常了,指令(因为这边开启的端口是9090):

netstat -aln |grep 9090

FAQ(88): The HTTP response from the server [404] did not permit the HTTP upgrade to WebSocket?_服务器_02

结论是:端口木有问题

 

  • 检查代码是否出错

长连接建立的代码,瞄一眼看看:

  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​