文档章节

基于NIO的消息路由的实现(七)客户端的一些实现,维持链路,断线重连

皮鞋铮亮
 皮鞋铮亮
发布于 2015/08/28 14:26
字数 617
阅读 210
收藏 7

一、客户端代码存在的必要性以及我认为需要解决的问题

就NIO通讯本身而言完全没必要分开,其实客户端代码和服务端代码可以放到一起。但是在业务上是分开的。我在做nio的时候思考了许多我自己认为应该解决的问题;主要的如下:

1、链路维护(心跳);

定期的向服务端发送维持链路报文,获得服务端的响应,以证明其仍然在存活状态;同时服务端会记录客户端每次维持链路的时间,用于服务端对通道的超时 判断;

2、断线重连:

一种情况是正常断线,目前我利用对channel的read返回来进行判断;

另一种是非正常短线,我利用维持链路的心跳回应来进行判断,也就是说,当连续发送固定次数的维持链路指令,没有收到服务端的回应的时候,主动断线,启动重连;

二、具体实现:

  1、链路维护代码:

  •     定时发送维持链路指令;

  •     判断维持链路指令缓冲区(此缓冲区在每次发送维持链路指令的时候会将指令记录到缓冲区,每次收到链路维护回应报文的时候,会将其所对应的指令清除,如果连续多次收不到回应,那么缓冲区的大小就会达到设置的阈值)的大小,如果达到预设值,就设置客户端连接状态为false;重连线程会依据这个标记做是否重连的判断。

public class KeepChannelThread extends Thread {

    private static Logger logger = LogManager.getLogger(KeepChannelThread.class.getName());
    private int reconnectTag = 0;

    public void run(){
        while(true){

            //构建链路维护指令对象
            ClientKeepOrder keepOrder = (ClientKeepOrder)Client.getOrderInstance(ClientKeepOrder.HEADER);
            keepOrder.initClientKeepOrder();
            if (StringUtils.isBlank(keepOrder.getToken())){
                logger.info("未收到服务端分配的身份标识,暂不发送链路维护报文!");
                reconnectTag++;
                if (reconnectTag>Client.getKeepTimeoutCount()){
                    Client.clearToken4Disconnect();
                }
            }else {
                reconnectTag = 0;
                try {
                    //触发重连机制
                    if (Client.KEEP_ORDER_MAP.size()>=Client.getKeepTimeoutCount()){
                        Client.clearToken4Disconnect();
                        logger.info("维持链路发现服务端未响应数量达到阈值,进行重连操作!");
                        continue;
                    }
                    //发送链路维持报文
                    Client.write2Channel(keepOrder);
                    //保存链路维持报文到缓冲区,等待服务端回应清除。
                    ClientKeepOrder keepOrderValue = new ClientKeepOrder();
                    keepOrderValue = keepOrder;
                    Client.KEEP_ORDER_MAP.put(keepOrder.getRid(), keepOrderValue);
                } catch (IOException e) {
                    e.printStackTrace();
                    continue;
                }
            }
            try {
                Thread.sleep(Client.getKeepAliveCycle()*1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


© 著作权归作者所有

共有 人打赏支持
皮鞋铮亮
粉丝 36
博文 12
码字总数 11603
作品 0
沈阳
私信 提问
基于NIO的消息路由的实现(一) 前言

一、前言: 已经很久没有碰编码了,大概有9年的时间,日新月异的框架和新东西让我眼花缭乱。之前一直在做web相关的应用。由于项目不大,分布式开发在我编码的那个年代里没有做过,后来走上管...

皮鞋铮亮
2015/08/17
0
16
京东的Netty实践,京麦TCP网关长连接容器架构

京麦从 2014 年构建网关,从 HTTP 网关发展到 TCP 网关。在 2016 年重构完成基于 Netty4.x+Protobuf3.x 实现对接 PC 和 App 上下行通信的高可用、高性能、高稳定的 TCP 长连接网关。本文重点...

张松然
01/03
0
0
基于NIO的消息路由的实现(三)服务端与客户端结构

一、服务器端结构: 如图所示: 指令类和报文类:对下行的指令和上行的报文进行了类的封装,分别实现IOrder和IPacket接口,继承Order,Packet基类; 服务主线程:接受客户端连接,将客户端发...

皮鞋铮亮
2015/08/18
0
3
netty学习之Reactor线程模型以及在netty中的应用

1.Reactor单线程模型 Reactor单线程模型就是指所有的IO操作都在同一个NIO线程上面完成的,也就是IO处理线程是单线程的。NIO线程的职责是: (1)作为NIO服务端,接收客户端的TCP连接; (2)...

harries
05/11
0
0
基于XMPP协议的Android即时通信系

以前做过一个基于XMPP协议的聊天社交软件,总结了一下。发出来。 设计基于开源的XMPP即时通信协议,采用C/S体系结构,通过GPRS无线网络用TCP协议连接到服务器,以架设开源的Openfn'e服务器作...

丁佳辉
2016/06/14
43
0

没有更多内容

加载失败,请刷新页面

加载更多

SpringBoot整合Mybatis扫描不到Mapper的问题

参考资料 1、SpringBoot整合Mybatis扫描不到Mapper的问题

哎小艾
5分钟前
0
0
网络相关.md

https://github.com/acBool/Blogs/blob/master/%E7%BD%91%E7%BB%9C%E7%9B%B8%E5%85%B3/%E7%BD%91%E7%BB%9C%E7%9B%B8%E5%85%B3.md URL URL: 全称Uniform Resource Location,统一资源定位符,......

壹峰
5分钟前
0
0
Ubuntu虚拟机无法连接到网络

查看本机中控制面板---管理工具---服务 找到服务(本地) 确保 VMware DHCP Service 和VMware NAT Service 服务已经启动 查看Ubuntu的ip地址 显示ip则连接成功...

唐十三郎
11分钟前
0
0
MyEclipse开发教程:REST Web Service(二)

MyEclipse 在线订购年终抄底促销!火爆开抢>> MyEclipse最新版下载 使用MyEclipse开发RESTWeb服务来放大您的Web应用程序。在本教程示例中,您将创建一个简单的Web服务来维护客户列表。你将学...

电池盒
12分钟前
0
0
线程sleep和yield的区别

1.sleep()方法暂停当前线程后,会给其他线程执行机会,线程优先级对此没有影响。yield()方法会给优先级相同或更高的线程更高的执行机会。 2.sleep()方法会将线程转入阻塞状态,直到阻塞时间结...

勇敢的飞石
12分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部