|
@@ -0,0 +1,127 @@
|
|
|
+package com.wdkl.ncs.android.lib.tcp;
|
|
|
+
|
|
|
+import io.netty.bootstrap.Bootstrap;
|
|
|
+import io.netty.channel.*;
|
|
|
+import io.netty.channel.nio.NioEventLoopGroup;
|
|
|
+import io.netty.channel.socket.SocketChannel;
|
|
|
+import io.netty.channel.socket.nio.NioSocketChannel;
|
|
|
+import io.netty.handler.codec.string.StringDecoder;
|
|
|
+import io.netty.handler.codec.string.StringEncoder;
|
|
|
+import io.netty.handler.timeout.IdleStateHandler;
|
|
|
+import io.netty.util.CharsetUtil;
|
|
|
+
|
|
|
+import java.util.Scanner;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+//单例
|
|
|
+public class TcpClient {
|
|
|
+ private NioEventLoopGroup workGroup = new NioEventLoopGroup(2);
|
|
|
+ private Bootstrap bootstrap;
|
|
|
+
|
|
|
+ //数据处理
|
|
|
+ TcpClientHandler tcpClientHandler = new TcpClientHandler();
|
|
|
+ //是否运行中
|
|
|
+ public boolean isRunning = false;
|
|
|
+ //重试间隔
|
|
|
+ private Integer retrySeconds = 5;
|
|
|
+ //重试计数
|
|
|
+ private Integer retryTimes = 1;
|
|
|
+
|
|
|
+
|
|
|
+ //单例
|
|
|
+ private static class TcpClientHolder{
|
|
|
+ private static TcpClient instance = new TcpClient();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static TcpClient getInstance(){
|
|
|
+ return TcpClientHolder.instance;
|
|
|
+ }
|
|
|
+
|
|
|
+ //初始化Netty Tcp Client 并连接
|
|
|
+ public void init(String serverIP, Integer serverPort, Integer heartBeatSeconds){
|
|
|
+ final Integer hbSeconds = heartBeatSeconds;
|
|
|
+ bootstrap = new Bootstrap();
|
|
|
+ bootstrap.group(workGroup)
|
|
|
+ .channel(NioSocketChannel.class)
|
|
|
+ .option(ChannelOption.SO_KEEPALIVE,true)
|
|
|
+ .handler(new ChannelInitializer<SocketChannel>() {
|
|
|
+ @Override
|
|
|
+ protected void initChannel(SocketChannel socketChannel) throws Exception {
|
|
|
+ //心跳包应当小于服务器间隔
|
|
|
+ socketChannel.pipeline().addLast(new IdleStateHandler(0, hbSeconds,0, TimeUnit.SECONDS));
|
|
|
+ socketChannel.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8));
|
|
|
+ socketChannel.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
|
|
|
+ socketChannel.pipeline().addLast(tcpClientHandler);
|
|
|
+ }
|
|
|
+ }).remoteAddress(serverIP,serverPort);
|
|
|
+ doConnect();
|
|
|
+ }
|
|
|
+
|
|
|
+ //独立连接方法,用于重新连接
|
|
|
+ public synchronized void doConnect(){
|
|
|
+ System.out.println("connect start");
|
|
|
+ ChannelFuture future = bootstrap.connect().addListener(new ChannelFutureListener() {
|
|
|
+ @Override
|
|
|
+ public void operationComplete(ChannelFuture channelFuture) throws Exception {
|
|
|
+ if (channelFuture.isSuccess()){
|
|
|
+ isRunning = true;
|
|
|
+ System.out.println("connect success");
|
|
|
+ } else {
|
|
|
+ //连接失败时的处理
|
|
|
+ isRunning = false;
|
|
|
+ System.out.println("connect retry : " + retryTimes);
|
|
|
+ channelFuture.channel().eventLoop().schedule(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ retryTimes++;
|
|
|
+ if (retryTimes>3){
|
|
|
+ System.out.println("重试"+(retryTimes-1)+"次,结束");
|
|
|
+ workGroup.shutdownGracefully();
|
|
|
+ //todo: 从API获取新的serverIP和serverPort,全新连接
|
|
|
+ //TcpClient.getInstance().init();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ doConnect();
|
|
|
+ }
|
|
|
+ },retrySeconds * retryTimes, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ try {
|
|
|
+ future.sync();
|
|
|
+ future.channel().closeFuture().sync();
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+ //重试之前不关
|
|
|
+// try {
|
|
|
+// Thread.sleep(retrySeconds * retryTimes*1000 + 1000);
|
|
|
+// } catch (InterruptedException e) {
|
|
|
+// }
|
|
|
+// workGroup.shutdownGracefully();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //发送消息,线程安全
|
|
|
+ public synchronized void sendMsg(String content){
|
|
|
+ tcpClientHandler.sendMsg(content);
|
|
|
+ }
|
|
|
+
|
|
|
+ //测试
|
|
|
+ public static void main(String[] args) {
|
|
|
+
|
|
|
+ new Thread(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ TcpClient.getInstance().init("192.168.1.188",5080, 9);
|
|
|
+ }
|
|
|
+ }).start();
|
|
|
+
|
|
|
+ Scanner scanner = new Scanner(System.in);
|
|
|
+ while (true){
|
|
|
+ System.out.println("please type : ");
|
|
|
+ String line = scanner.nextLine();
|
|
|
+ TcpClient.getInstance().sendMsg(line);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|