首页IT科技spring websocket心跳检测(WebSocket开发(心跳监测)功能)

spring websocket心跳检测(WebSocket开发(心跳监测)功能)

时间2025-04-30 05:55:54分类IT科技浏览5441
导读:前言 在之前的文章中完成了客服对话的Demo功能,但是现在的连接是无限制的长时间连接没有做心跳、失活、超时断连等功能,心跳的实现方法有很多种,并且WebSocket就提供了ping/pong类型的消息。...

前言

在之前的文章中完成了客服对话的Demo功能             ,但是现在的连接是无限制的长时间连接没有做心跳             、失活                  、超时断连等功能                  ,心跳的实现方法有很多种      ,并且WebSocket就提供了ping/pong类型的消息            。

心跳的触发方式也分两种:

客户端触发:如果是前端发送心跳             ,后端需要返回心跳                   ,也就是ping pong的过程会有两次数据传递                   。 服务端触发:后端来发送心跳的话      ,就只需要发送ping      ,前端不需要回应      。

这两种后续的处理方式也有各自优缺点      。

客户端触发: 优点 灵活控制 无需设置主动超时 逻辑清晰 服务端简单 缺点 两次消息传递 消息内容容易篡改 服务端触发: 优点 节省宽带 服务端控制频率 消息体固定 缺点 处理逻辑复杂 需要添加定时任务 考虑稳定性

两种方式各有利弊                   ,看具体的应用场景选择心跳方式是最好的            ,这里使用客户端触发心跳进行Demo实验      ,前端变更比较容易                   ,服务端也不需要写定时等处理复杂的业务            ,只需要在收到固定消息后返回对应消息即可                   。

1. WebSocket心跳

客户端触发心跳的话就是在服务端的OnMessage事件里进行截获处理,如果是接受参数为String                   ,就在之前的逻辑之上加上判断健康检查的逻辑                  ,功能很简单,客户端发送了特点消息直接返回对应的消息即可             。

1.1 字符串消息

WebSocket已经设计了心跳             ,也就是Ping/Pong                  ,这个功能可以到达检测链接是否可用      ,但是如果要携带数据还是需要自己用字符串      、对象的消息类型进行实现      。

代码如下:

@OnMessage public void onMessage(String message, Session session,@PathParam("clientId") String clientId){ /** * 持久化 */ baseWebSocketService.saveClientSendMsg(clientId,message,new Date()); /** * 处理消息 */ UserMessageModel userMessageModel = JSONObject.parseObject(message, UserMessageModel.class); if (userMessageModel == null){ this.sendMessage(BaseResponseMessage.error(null,"传递参数结构异常")); } userMessageModel.setSendId(clientId); /** * 健康检查 */ if ("HEALTH".equals(userMessageModel.getMessage())){ this.sendText(WebSocketHealthEnum.HEALTH.result); return; } /** * 发送消息 */ HashMap<String,WebSocketClient> hashMap = webSocketClientMap.get(WebSocketTypeEnum.getAcceptType(this.type)); if (!CollectionUtils.isEmpty(hashMap)){ if (StringUtils.isEmpty(bindKfClients.get(this.clientId))){ List<UserMessageModel> list = new ArrayList(); list.addAll(baseWebSocketService.queryClientSendMsg(clientId)); list.forEach(model-> { this.toCSucceed(model); }); }else{ this.toCSucceed(userMessageModel); } }else{ baseWebSocketService.saveClientCompensateMsg(userMessageModel.getAcceptId(),message,(byte) 0); log.info("客户端:{} 发送消息到接受端:{} 不在线             ,放置到代发送列表                   ,当前待发送列表:{}条",clientId,userMessageModel.getAcceptId()); this.sendMessage(BaseResponseMessage.error(null,"接收端不在线")); } }

如果客户端发送了内容HEALTH则回复对应消息      ,我这里回复了SUCCESS

但是这样有个问题      ,用户发送了HEALTH这个字符串服务端会将这个消息当作健康检查进行处理                   ,而不是消息            ,这样影响了用户端的使用                  。

还记得之前预留了一个发送类型字段sendType吗      ,这时候这个类型就起作用了                   ,如果要做健康检查的操作就将这个sendType设置为HEALTH            ,服务端根据sendType字段进行判断业务处理,修改一下代码:

/** * 健康检查 */ if (WebSocketHealthEnum.HEALTH.msg.equals(userMessageModel.getSendType())){ this.sendText(WebSocketHealthEnum.HEALTH.result); return; }

1.2 Ping/Pong消息

Ping的协议头是0x9                   ,Pong的协议头是0xA 控制帧最大载荷为125bytes且不能拆分

服务端可以主动发生Ping/Pong消息                  ,之前文章中写过WebSocket发送消息的四种类型,这里将上面发送Text文本类型换成发送Ping类型的消息             ,当然也可以发送Pong类型的消息             。

代码如下:

if (WebSocketHealthEnum.HEALTH.msg.equals(userMessageModel.getSendType())){ try { session.getBasicRemote().sendPing(ByteBuffer.wrap("SUCCESS".getBytes())); } catch (IOException e) { throw new RuntimeException(e); } return; }

Ping消息是不会被我们的OnMessage事件接收的                  ,所以不需要特殊处理      ,如果是Pong消息在服务的接收是可以的。

代码如下:

@OnMessage public void onPong(PongMessage pongMessage) { ByteBuffer byteBuffer = pongMessage.getApplicationData(); }

具体的业务可以二次处理

2. 服务心跳

上面的心跳是对每个客户端的心跳监测             ,服务的心跳也要做                   ,服务的心跳就简单了      ,前端定时请求HTTP/HTTPS协议接口                  。

代码如下:

@Slf4j @RestController public class CheckHealthController { @GetMapping("/health") public ResponeApi health() { log.info("健康检查chatroom-IM --> 检查成功!"); return ResponeApi.success(ResponeCodeEnum.SUCCESS,"SUCCESS"); } }

效果如下:

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
vue element 表格(Element Plus 虚拟化表格组件的使用(排序、筛选、自定义单元格渲染) – 个人使用总结) chattr operation not permitted(已解决chatgpt报错出了些问题。如果此问题仍然存在,请通过我们的帮助中心 help.openai.com 与我们联系。)