当前位置:   article > 正文

spring boot netty 即时通讯系统之心跳机制(七)_usereventtriggered

usereventtriggered

  netty心跳机制,通过userEventTriggered方法进行心跳检测,用户超时长时间未操作时则会触发,通过发送ping/pong的指令来保持客户端与服务端之间的连接不中断,推荐从前面的章节开始看。

  1. HeartBeatReqHandler.java
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.fyrt.fyrtim.util.*;
  4. import io.netty.channel.ChannelHandlerContext;
  5. import io.netty.channel.SimpleChannelInboundHandler;
  6. import io.netty.handler.timeout.IdleState;
  7. import io.netty.handler.timeout.IdleStateEvent;
  8. import lombok.extern.slf4j.Slf4j;
  9. /**
  10. * 心跳检测 客户端
  11. */
  12. @Slf4j
  13. public class HeartBeatReqHandler extends SimpleChannelInboundHandler {
  14. @Override
  15. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  16. NettyMessage nettyMessage= (NettyMessage) JsonUtil.parseNettyMessage(msg);
  17. if (LoginUtil.hasLogin(ctx.channel())) {
  18. if (TransportType.HEARTBEAT.getValue().equals(nettyMessage.getTransportType())) {
  19. if (nettyMessage.getMsg().equals("pong")) {
  20. log.info("收到pong请求");
  21. log.info("发送ping请求");
  22. ctx.writeAndFlush(JSONObject.toJSONString(new NettyMessage(TransportType.HEARTBEAT.getValue(), "ping", ctx.channel())));
  23. } else if (nettyMessage.getMsg().equals("ok")) {
  24. log.info("心跳续约:" + nettyMessage.getMsg());
  25. }
  26. }else{
  27. //直接跳转到下个handler请求
  28. ctx.fireChannelRead(msg);
  29. }
  30. } else {
  31. //直接跳转到下个handler请求
  32. ctx.fireChannelRead(msg);
  33. }
  34. }
  35. @Override
  36. protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
  37. }
  38. @Override
  39. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  40. //直接跳转到下个handler请求
  41. ctx.fireChannelActive();
  42. }
  43. @Override
  44. public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  45. //退出登录
  46. UserChannelUtil.unBindUser(ctx.channel());
  47. LoginUtil.logoOut(ctx.channel());
  48. System.out.println("客户端已关闭");
  49. }
  50. @Override
  51. public void userEventTriggered(ChannelHandlerContext ctx, Object obj) throws Exception {
  52. if (obj instanceof IdleStateEvent){
  53. IdleStateEvent event = (IdleStateEvent)obj;
  54. if (event.state()== IdleState.READER_IDLE){
  55. log.info("客户端读超时");
  56. }else if (event.state()== IdleState.WRITER_IDLE){
  57. log.info("客户端写超时");
  58. }else if (event.state()==IdleState.ALL_IDLE){
  59. log.info("客户端所有操作超时");
  60. }
  61. ctx.writeAndFlush(JSONObject.toJSONString(new NettyMessage(TransportType.HEARTBEAT.getValue(),"ping",ctx.channel())));
  62. }
  63. }
  64. }

 

  1. HeartBeatRespHandler.java
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.fyrt.fyrtim.util.JsonUtil;
  4. import com.fyrt.fyrtim.util.NettyMessage;
  5. import com.fyrt.fyrtim.util.TransportType;
  6. import io.netty.channel.ChannelHandlerContext;
  7. import io.netty.channel.SimpleChannelInboundHandler;
  8. import io.netty.handler.timeout.IdleState;
  9. import io.netty.handler.timeout.IdleStateEvent;
  10. import lombok.extern.slf4j.Slf4j;
  11. /**
  12. * 心跳检测 服务端
  13. */
  14. @Slf4j
  15. public class HeartBeatRespHandler extends SimpleChannelInboundHandler {
  16. @Override
  17. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  18. cause.printStackTrace();
  19. ctx.close();
  20. }
  21. @Override
  22. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  23. NettyMessage nettyMessage = (NettyMessage) JsonUtil.parseNettyMessage(msg);
  24. if (nettyMessage.isLogin()){
  25. if (TransportType.HEARTBEAT.getValue().equals(nettyMessage.getTransportType())) {
  26. log.info("收到客户端pong请求");
  27. log.info("发送ping请求");
  28. ctx.writeAndFlush(JSONObject.toJSONString(new NettyMessage(TransportType.HEARTBEAT.getValue(), "ok", ctx.channel())));
  29. }else{
  30. ctx.fireChannelRead(msg);
  31. }
  32. }else{
  33. ctx.fireChannelRead(msg);
  34. }
  35. }
  36. @Override
  37. protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
  38. }
  39. @Override
  40. public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  41. //退出登录
  42. System.out.println("服务端已关闭");
  43. }
  44. @Override
  45. public void userEventTriggered(ChannelHandlerContext ctx, Object obj) throws Exception {
  46. if (obj instanceof IdleStateEvent){
  47. IdleStateEvent event = (IdleStateEvent)obj;
  48. if (event.state()== IdleState.READER_IDLE){
  49. log.info("客户端读超时");
  50. }else if (event.state()== IdleState.WRITER_IDLE){
  51. log.info("客户端写超时");
  52. }else if (event.state()==IdleState.ALL_IDLE){
  53. log.info("客户端所有操作超时");
  54. }
  55. }
  56. }
  57. }

 实现效果:

代码已上传至github:https://github.com/beibeirenzhe/netty-im/tree/master/fyrtim

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/242156
推荐阅读
相关标签
  

闽ICP备14008679号