使用netty进行客户端网络编程及断线重连功能实现
2017-01-09 21:42
961 查看
不管做哪个方向开发,都会有那么一两个牛B闪闪的库,可以极大的方便开发,比如java网络编程中的netty库。无论客户端还是服务端网络编程,netty基本都是首选网络库,健壮、高效、稳定,并且已经得到很多商业项目验证。
当用netty进行客户端网络编程时,与服务端建立连接并完成数据编码、解码、通信是最基础功能,考虑程序的健壮性,则断线重连是必不可少的一个功能点。netty源码的example文件夹中uptime目录中有相关示例demo,但是总觉得该样例代码封装的不够好,于是决定自己动手重新写一个,如果有更优雅的断线重连实现方法,希望大家将链接留言发我。下面是主体代码,Handler部分就不分享了。
当用netty进行客户端网络编程时,与服务端建立连接并完成数据编码、解码、通信是最基础功能,考虑程序的健壮性,则断线重连是必不可少的一个功能点。netty源码的example文件夹中uptime目录中有相关示例demo,但是总觉得该样例代码封装的不够好,于是决定自己动手重新写一个,如果有更优雅的断线重连实现方法,希望大家将链接留言发我。下面是主体代码,Handler部分就不分享了。
public class BaseClient implements Runnable { private static Logger LOGGER = LoggerTools.getInstance(BaseClient.class); private String host_; private int port_; private int reConnectCount_ = 0; private ClientHandler clientHandler_; private OnMessageListener messageListener_; private OnStartupListener startupListener_; private volatile boolean isChannelPrepared_; private final static int MAX_MESSAGE_LENGTH = 8192; public BaseClient(String host, int port, OnMessageListener messageListener, OnStartupListener startupListener) { host_ = host; port_ = port; messageListener_ = messageListener; startupListener_ = startupListener; } @Override public void run() { connect(host_, port_); } // 发送消息 public void sendMessage(String msg, ResultListener<String> listener) { if (isChannelPrepared_) { clientHandler_.sendMessage(msg, listener); } else { listener.onFailure(msg); LOGGER.error("连接还未建立, 无法发送数据..."); } } // 建立连接 private void connect(String host, int port) { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group); b.channel(NioSocketChannel.class); b.option(ChannelOption.TCP_NODELAY, true); b.handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast(new LengthFieldBasedFrameDecoder(MAX_MESSAGE_LENGTH, 0, 4, 0 ,4)); p.addLast(new LengthFieldPrepender(4)); p.addLast(new StringDecoder(CharsetUtil.UTF_8)); p.addLast(new StringEncoder(CharsetUtil.UTF_8)); clientHandler_ = new ClientHandler(messageListener_); p.addLast(clientHandler_); } }); ChannelFuture f = b.connect(host, port).sync(); f.addListener(new GenericFutureListener<Future<? super Void>>() { @Override public void operationComplete(Future<? super Void> future) throws Exception { if (future.isSuccess()) { reConnectCount_ = 0; isChannelPrepared_ = true; startupListener_.onCompletion(true); LOGGER.info("与服务器{}:{}连接建立成功...", host_, port_); } else { isChannelPrepared_ = false; startupListener_.onCompletion(false); LOGGER.info("与服务器{}:{}连接建立失败...", host_, port_); } } }); f.channel().closeFuture().sync(); } catch (Exception e) { isChannelPrepared_ = false; LOGGER.error("与服务器{}:{}连接出现异常...", host_, port_); } finally { isChannelPrepared_ = false; group.shutdownGracefully(); reConnect(host, port); } } // 断线重连 private void reConnect(String host, int port) { // fixme: 重连显式退出? try { isChannelPrepared_ = false; int delay = ++reConnectCount_ * 5; reConnectCount_ = reConnectCount_ > 23 ? 23 : reConnectCount_; LOGGER.error("与服务器{}:{}连接已断开, {}秒后重连...", host, port, delay); Thread.sleep(delay * 1000); connect(host, port); } catch (Exception e) { e.printStackTrace(); } } }
相关文章推荐
- 使用netty进行客户端网络编程及实现断线重连功能
- 使用netty进行服务端网络编程及数据高效分发功能实现
- Android 通过WebService进行网络编程,使用工具类轻松实现------客户端编程
- Android网络编程之一个Android下菜单系统模块的实现(客户端—结算功能)
- Android网络编程之一个Android下菜单系统模块的实现(开桌功能))(Android客户端+服务器端Servlet+Mysql)
- linux网络编程:使用单进程实现多客户端通信
- Android 通过WebService进行网络编程,使用工具类轻松实现
- Linux网络编程--多线程实现echo服务器与客户端“一对多”功能,网络编程的“Hello World!” - 壮壮熊
- Android 通过WebService进行网络编程,使用工具类轻松实现
- Android 通过WebService进行网络编程,使用工具类轻松实现
- 一个使用监听器模式实现的J2ME网络编程框架,包括一个简单的登录功能实现(含源代码)
- android使用JSON进行网络数据交换(服务端、客户端)的实现
- android使用JSON进行网络数据交换(服务端、客户端)的实现
- Linux网络编程--多线程实现echo服务器与客户端“一对多”功能,是网络编程的“Hello World!”
- 使用 Netty 进行 UDP 网络编程
- Android网络编程之一个Android下菜单系统模块的实现(客户端—添单功能(上部))
- android通过webservice进行网络编程,使用工具类实现
- Android 通过WebService进行网络编程,使用工具类轻松实现
- 一个使用监听器模式实现的J2ME网络编程框架,包括一个简单的登录功能实现(含源代码)
- Android 通过WebService进行网络编程,使用工具类轻松实现