ithewei / libhv

🔥 比libevent/libuv/asio更易用的网络库。A c/c++ network library for developing TCP/UDP/SSL/HTTP/WebSocket/MQTT client/server.
https://github.com/ithewei/libhv/wiki
BSD 3-Clause "New" or "Revised" License
6.83k stars 1.24k forks source link

websocket client重连持续几个小时后,不发起重连操作 #386

Closed zhouxiaojun2008 closed 1 year ago

zhouxiaojun2008 commented 1 year ago

大佬,你好! 我调用libhv的websocket client接口,整体调用基本是参考websocket_client_test.cpp来的,只不过重连设置是固定的15s。重连设置如下代码所示: ` reconn_setting_t reconn; reconn_setting_init(&reconn); reconn.min_delay = 15000; reconn.max_delay = 15000; reconn.delay_policy = 0; setReconnect(&reconn);

    open(m_serverUrl.c_str());

`

我用的环境网络是属于海上的卫星网,受卫星信号以及天气等各种因素影响,属于比较极端的弱网。 我实际测试发现,程序启动后,经常重连了好几个小时就停住没有重新动作了,这点从libhv自己的日志可以看到。 我先前用的版本是 去年11月16的源码https://github.com/ithewei/libhv/commit/cac4e7a8ba59411673fe3942eb9c55fb2d429512。 发现问题后,我查看了新的issue以及代码修复的变动,发现

359 貌似和这个问题相关,所以我更新了源码到截止发帖的最新版本,也就是V1.3.1 582f599d0e067d2f09b1403b88c5d5ef62fceefa

实际现场测试还是遇到重连了好几个小时,没有发起重新操作,另外websocket服务端是java的springboot websocket stomp,支持pingpong协议。 libhv.20230526.log, 这份日志可以看到我调用libhv监听了一个websocket服务,开启了2个线程。 同时也用websocketclient链接了一个公网服务器,一直重新持续到 2023-05-26 07:44:58.541 INFO reconnect... cnt=5, delay=15000 [TcpClient.h:165:startReconnect] 再也没有重连日志输出了。

ithewei commented 1 year ago

你可以在TcpClient::startConnectchannel->onconnectchannel->onclose第一行都加下日志打印,判断具体是定时器、连接成功、失败哪一步没有触发

zhouxiaojun2008 commented 1 year ago

好的,我加下日志再跑下

xs-411 commented 1 year ago

海上的卫星网,你是在海上的船员吗?船上也需要开发人员吗?

zhouxiaojun2008 commented 1 year ago

海上的卫星网,你是在海上的船员吗?船上也需要开发人员吗?

不是,我是个码农,程序部署在船上。

zhouxiaojun2008 commented 1 year ago

每当连不上的时候,我用netstat看websocket链接的时候,居然可以看到他是connect状态。

zhouxiaojun2008 commented 1 year ago

大佬有空指导一下! 我在V1.3.1的版本上在startConnect,channel->onconnect,channel->onclose 添加了如下日志: image。 ,我是2023-05-31 15:03:55重启程序的,最终停在了2023-06-01 00:48:29.187,没有继续发起重连, 这是最终的日志 2023-06-01 00:48:13.225 INFO reconnect... cnt=3, delay=15000 [TcpClient.h:170:startReconnect] 2023-06-01 00:48:28.223 INFO startConnect channel 47.101.61.127:7475 status:0, connect_timeout:10000 [TcpClient.h:111:startConnect] 2023-06-01 00:48:29.187 INFO onconnect channel 47.101.61.127:7475 status:2 [TcpClient.h:131:operator()]。 对照前面的日志应该过一段时间打印 2023-06-01 00:47:23.224 ERROR websocket no pong! [WebSocketClient.cpp:175:operator()],但是没有,随后一直没用重连。 附件是日志

libhv.20230531.log libhv.20230601.log

zhouxiaojun2008 commented 1 year ago

大致分析了下,会不会下面这种情况, 从日志看已经onconnect说明connect成功了也就是完成了tcp的三次握手,接下来是要发送WebSocket 握手请求,代码在websocketclient的onConnection发送http get,但是没有收到回复,也就导致进入不到后面的onMessage函数,就开启不了pingpong定时器了,而之前的pingpong定时器由于close已经清理掉了,造成了上面日志出现的情况

ithewei commented 1 year ago

一般服务端是有keepalive机制的,多长时间没收到一下个请求就主动断开连接,这样客户端也就可以感知到连接断了,如果没法修改服务端,你可以在WebSocketClient的onConnection里发送握手请求后调用channel->setReadTimeout设置读超时,然后在onMessage里握手结束后channel->setReadTimeout(0)关闭这个读超时定时器

zhouxiaojun2008 commented 1 year ago

嗯嗯,我已经在onconnection加了个channel->setKeepaliveTimeout(10000);是一样的效果,从周五下午升级后一直到现在,都可以链接上了