我是靠谱客的博主 昏睡流沙,最近开发中收集的这篇文章主要介绍IM系统第六章 -- 断线重连恢复通信IM系统第六章 – 断线重连恢复通信,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

IM系统第六章 – 断线重连恢复通信

你是如何实现该功能的?

断线重连该机制在通信中是一种很重要的机制,假如没有该机制,无法及时在恢复网络的时候接收到对方发来的消息,需要退出登录重新连接才能接收的到;为了解决这个情况,”断线重连“机制就应运而生了。

那这种机制你如何实现?利用在客户端中 定时检测连接状态的方式,来判断是否保持良好的链接,如果断开就进行重连恢复通信。

下图为实现该逻辑流程图(参考 小傅哥)

img

实现功能所需的处理:

  1. 自定义协议;
  2. 服务端断线重连处理;
  3. 客户端实现心跳机制处理;

自定义协议:ReconnectRequest

// 断线重连请求  协议
public class ReconnectRequest extends Packet {
    private String useId; // 发起重连的用户Id
    public ReconnectRequest(String userId) {
        this.userId = userId;
    }
    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
}

自定义完协议后,客户端的Application中设定 定时检测连接状态 机制;

public class Application extends javafx.application.Application {
    // 默认线程池
    private static final ExecutorService executorService = Executors.newFixedThreadPool(2);
    private final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
    // Channel状态定时巡检,3s后每5s执行一次连接检测
    scheduledExecutorService.scheduleAtFixedRate(() -> {
        while(!nettyClient.isActive()) {
            try{
                System.out.println("通信管道巡检:断线重连[begin]");
                // 重新提交 nettyClient任务到executorService线程池中
                Channel freshChennel = executorService.submit(nettyClient).get();
                // 如果缓存中的userId为空,则跳过
                if(null == CacheUtil.userId) continue;
                // 否则将userId作为 重连请求协议的参数 传送过去
                freshChannel.writeAndFlush(new ReconnectRequest(CacheUtil.userId));
            }catch(Exception e) {
                System.out.println("通信管道巡检:断线重连[error]");
            }
        }
    } 3,5,TimeUnit.SECONDS);
}

服务端的主要任务:发生断线重连后,客户端发来 重连请求协议,利用这个协议的userId 结合SocketUtil 工具类来将原有的用户管道删除,然后增添新的现在参数的channel(添加用户channel的操作);从数据库中查到该用户的 群组的对话框集合,然后进行遍历更新。

public class ReconnectHandler extends MyBizHandler<ReconnectRequest> {
    @Override
    public void channelRead(Channel channel, ReconnectRequest msg) {
        // 添加个人channel[删除原有的channel,增添新的channel与用户id的映射]
        SocketChannelUtil.removeUserChannelByUserId(msg.getUserId());
        SocketChannelUtil.addChannel(msg.getUserId(), channel);
        
        // 添加群组channel[通过查询用户的 对话群组,然后遍历来更新]
        List<String> groupsList = userService.queryTalkBoxGroupsIdList(msg.getUserId());
        for(String groupId : groupsList) {
            SocketChannelUtil.addChannelGroup(groupId,channel);
        }
    }
}

总结

分三步:

  1. 自定义 断线重连协议;
  2. 客户端中Application 要实现 定时检测连接状态 机制,每5s就进行一次心跳机制;如果CacheUtil.userId 不为空,就证明该用户已经断开连接,需要发 重连请求 协议过去给服务端;
  3. 服务端中,主要是对用户 原有的channel进行删除 和 新的channel进行了增添,群组就从数据库中 根据用户的id 查询到群组的对话框集合,然后进行遍历更新即可。

最后

以上就是昏睡流沙为你收集整理的IM系统第六章 -- 断线重连恢复通信IM系统第六章 – 断线重连恢复通信的全部内容,希望文章能够帮你解决IM系统第六章 -- 断线重连恢复通信IM系统第六章 – 断线重连恢复通信所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(38)

评论列表共有 0 条评论

立即
投稿
返回
顶部