通过前面 Apache Mina 入门 (二)—— 异步通信机制
我们可以实现一个长连接的客户端。但会发现一个问题,就是当网络、服务器、应用程序出现问题而导致连接断开后,我们的客户端不能自动重连服务器。导致客户端程序瘫痪,不能使用。这个时候,通过增加一个监听器,就能实现重连。
在我们实际生产环境中,断线的原因可能更复杂:网络不稳定、延时、服务器负载高、服务器或者应用程序的发送或者接收缓冲区满等等问题都可能导致数据传输过程出现类似于断线的情况,这个时候,光检测Session关闭是远远不够的,这个时候就需要一种重连机制,比如读写空闲超过30秒,就进行重连。对于数据不间断、实时性高、数据量大的应用场景,更是实用。
具体实现代码如下:
/**
* 添加重连监听
*
* @author liuc
* @date 2017-12-20
*
*/
public class ClientReconnectTest {
public static IoSession session = null;
public static NioSocketConnector connector = null;
public static void main(String[] args) {
connector = new NioSocketConnector();
connector.setConnectTimeoutMillis(30000); // 设置连接超时
connector.getSessionConfig().setReceiveBufferSize(10240); // 设置接收缓冲区的大小
connector.getSessionConfig().setSendBufferSize(10240);// 设置输出缓冲区的大小
connector.getFilterChain().addLast("logger", new LoggingFilter());
connector.getFilterChain().addLast("codec",
new ProtocolCodecFilter(new ByteArrayCodecFactory()));// 设置编码过滤器
connector.setHandler(new ClientHandler());// 设置事件处理器
connector.setDefaultRemoteAddress(new InetSocketAddress("127.0.0.1",
8888));// 设置默认访问地址
// 添加重连监听---实现自动重连
connector.addListener(new IoListener() {
@Override
public void sessionDestroyed(IoSession arg0) throws Exception {
//重连10次
for (int i= 0 ;i <= 10; i++) {
try {
Thread.sleep(3000);
ConnectFuture future = connector.connect();
future.awaitUninterruptibly();// 等待连接创建成功
session = future.getSession();// 获取会话
if (session.isConnected()) {
System.out.println("断线重连["
+ connector.getDefaultRemoteAddress()
.getHostName()
+ ":"
+ connector.getDefaultRemoteAddress()
.getPort() + "]成功");
break;
}
} catch (Exception ex) {
System.out.println("重连服务器登录失败,3秒再连接一次:" + ex.getMessage());
}
}
}
});
//确保连接成功,连接n次,
for (int i= 0 ;i <= 5; i++) {
try {
ConnectFuture future = connector.connect();
future.awaitUninterruptibly(); // 等待连接创建成功
session = future.getSession(); // 获取会话
if(session.isConnected()){
System.out.println("连接服务端"
+ connector.getDefaultRemoteAddress()
.getHostName()
+ ":"
+ connector.getDefaultRemoteAddress()
.getPort()
+ "[成功]"
+ ",,时间:"
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date()));
break;
}
} catch (RuntimeIoException e) {
System.out.println(
"连接服务端"
+ connector.getDefaultRemoteAddress()
.getHostName()
+ ":"
+ connector.getDefaultRemoteAddress()
.getPort()
+ "失败"
+ ",,时间:"
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date())
+ ", 连接SOCKET服务异常,请检查SOCKET端口、IP是否正确,MSG服务是否启动,异常内容:"
+ e.getMessage());
try {
Thread.sleep(5000);// 连接失败后,重连间隔5s
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
BaseMessageForServer message = new BaseMessageForServer();
String content = "hello world!";
CRC32 crc = new CRC32();
try {
crc.update(content.getBytes("GBK"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
message.setFuncid(5);
message.setPacketIdCode(10000);
message.setContent(content);
message.setCheckCode(crc.getValue());
message.setLength(content.getBytes().length);
session.write(message);
}
}
参考文章:http://blog.csdn.net/chwshuang/article/details/51023647