websocket自带心跳包吗(如何判断websocket断开)

本文目录
- 如何判断websocket断开
- Tomcat的WebSocketServlet为什么用不了,不是说自带的吗为什么我都找不到对应jar包如图,大神请指教
- websocket client怎样维持心跳,有没有具体的栗子
- websocket 怎么判断断开
如何判断websocket断开
法一:
当recv()返回值小于等于0时,socket连接断开。但是还需要判断
errno是否等于
EINTR,如果errno
==
EINTR
则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。
法二:
struct
tcp_info
info;
int
len=sizeof(info);
getsockopt(sock,
IPPROTO_TCP,
TCP_INFO,
&info,
(socklen_t
*)&len);
if((info.tcpi_state==TCP_ESTABLISHED))
则说明未断开
else
断开
法三:
若使用了select等系统函数,若远端断开,则select返回1,recv返回0则断开。其他注意事项同法一。
法四:
int
keepAlive
=
1;
//
开启keepalive属性
int
keepIdle
=
60;
//
如该连接在60秒内没有任何数据往来,则进行探测
int
keepInterval
=
5;
//
探测时发包的时间间隔为5
秒
int
keepCount
=
3;
//
探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.
setsockopt(rs,
SOL_SOCKET,
SO_KEEPALIVE,
(void
*)&keepAlive,
sizeof(keepAlive));
setsockopt(rs,
SOL_TCP,
TCP_KEEPIDLE,
(void*)&keepIdle,
sizeof(keepIdle));
setsockopt(rs,
SOL_TCP,
TCP_KEEPINTVL,
(void
*)&keepInterval,
sizeof(keepInterval));
setsockopt(rs,
SOL_TCP,
TCP_KEEPCNT,
(void
*)&keepCount,
sizeof(keepCount));
设置后,若断开,则在使用该socket读写时立即失败,并返回ETIMEDOUT错误
法五:
自己实现一个心跳检测,一定时间内未收到自定义的心跳包则标记为已断开。
Tomcat的WebSocketServlet为什么用不了,不是说自带的吗为什么我都找不到对应jar包如图,大神请指教
网站上说,某个东西会在 tomcat8 上删除,刚好你的 Tomcat 是8.0, 可能就是这个原因。
所以,要么你使用 tomcat 7 来开发测试,要么放弃这个不标准化的类库,换成标准化的那个 JSR356 WebSocket 1.0 规范来开发,在 JSR 规范出来前可能业界有不少尝试性的 API,但我们已经尽量使用 JSR 标准规范里面的东西。
JSR 规范站点:jcp.org
在里面输入 JSR 编号(比如 356) 能找到它,会有下载规范 PDF 文档和 API 的地方,我们应该尽量按 API 编程,这样能运行在所有的厂商的服务器上。
http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/websocket/WebSocketServlet.html
org.apache.catalina.websocket
Class WebSocketServlet
java.lang.Object
javax.servlet.http.HttpServlet
org.apache.catalina.websocket.WebSocketServlet
javax.servlet.GenericServlet
Deprecated.
Replaced by the JSR356 WebSocket 1.0 implementation and will be removed in Tomcat 8.0.x.
@Deprecated
public abstract class WebSocketServlet
extends HttpServlet
All Implemented Interfaces:
Serializable, Servlet, ServletConfig
websocket client怎样维持心跳,有没有具体的栗子
websocket是个很优秀的工具,网络上很多例子不适合,也不合乎逻辑,是发送心跳包不错,但是如何通过发送心跳包判断是否断开,这个大家说法不一样,99%的言论说是判断有没有接收到客户端反馈,有没有接收到服务端反馈。如果你这么想,你的程序就会不间断的掉线,实际上他没掉线。
自己下载一个360流量监测工具,或者用调试窗口看流量消息,程序就让timer一直发数据包。你会发现他发送有规律,接收数据是没有时间规律,有时候反应快点就很快 接收了,有时候反应慢了(很多未知因素可能来自操作系统)那就迟点接收咯。你如果规律型的去判断有没有接收到数据,那就很有可能误判,而且这个可能性是100%。最后你会发现你的逻辑不间断性掉线,甚至你会怀疑是websocket的问题。
其实websocket通信就像打电话,我打对方接才算通,对方挂断我自然在手机上看到断开了,都没办法把话说出去,心跳包就是保持通话,你不说话了不代表就断开了,你说了对方没回应也不代表就挂断了。webScocket有个事件叫OnError,都不知道用来干嘛的,我看很少有人使用过,这个就是挂断了话都说不出去触发的。
前段时间看网络上说腾讯应提问socket服务端会及时感知客户端断开吗?都是说不行,其实可以,服务端在每秒发送心跳包,发送报错就表示断开了。触发了OnError事件就让用户列表下线,客户端也能立即感知,timer判断socket.state,他一直是open就是在线的,不是就断开了。怎样维持心跳的思路我说清楚了,大概实现就是这样:
onOpen客户端接入,在这个事件发送一个命令,通知他服务端已经接通,让他汇报自己的信息包括用户称呼之类的,客户端接到通知,发送消息汇报自己,服务端onMessage接收到汇报更新用户列表。onClose也是要客户端关闭socket,服务端触发才能下线。还有一个onError事件怎么用?服务端timer定时发送一个数据,发送不出去自然就触发了onError,T用户下线。
客户端就计时器一直判断socket.state咯。
websocket 怎么判断断开
法一:
当recv()返回值小于等于0时,socket连接断开。但是还需要判断 errno是否等于 EINTR,如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。
法二:
struct tcp_info info;
int len=sizeof(info);
getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);
if((info.tcpi_state==TCP_ESTABLISHED)) 则说明未断开 else 断开
法三:
若使用了select等系统函数,若远端断开,则select返回1,recv返回0则断开。其他注意事项同法一。
法四:
int keepAlive = 1; // 开启keepalive属性
int keepIdle = 60; // 如该连接在60秒内没有任何数据往来,则进行探测
int keepInterval = 5; // 探测时发包的时间间隔为5 秒
int keepCount = 3; // 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.
setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
设置后,若断开,则在使用该socket读写时立即失败,并返回ETIMEDOUT错误
法五:
自己实现一个心跳检测,一定时间内未收到自定义的心跳包则标记为已断开。

更多文章:
another time(another time和other time的区别)
2026年10月11日 05:00







