| | |
| | | package com.ard.tianyu.netty; |
| | | |
| | | import com.ard.tianyu.config.TyConfiguration; |
| | | import com.ard.tianyu.domain.cache.TyTcpServerCache; |
| | | import com.ard.tianyu.netty.handler.ClientHandler; |
| | | import com.ard.tianyu.netty.handler.MessageProtocolDecoder; |
| | | import com.ard.tianyu.netty.handler.MessageProtocolEncoder; |
| | |
| | | import io.netty.handler.timeout.IdleStateHandler; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | import javax.annotation.PostConstruct; |
| | | import javax.annotation.Resource; |
| | | import java.net.InetSocketAddress; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | |
| | | EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); |
| | | |
| | | @Resource |
| | | private TyConfiguration tyConfiguration; |
| | | @Resource |
| | | ClientHandler clientHandler; |
| | | |
| | | /** |
| | | * 初始化Bootstrap |
| | | */ |
| | | public Bootstrap getBootstrap(EventLoopGroup group) { |
| | | if (null == group) { |
| | | group = eventLoopGroup; |
| | | } |
| | | private Bootstrap getBootstrap() { |
| | | Bootstrap bootstrap = new Bootstrap(); |
| | | bootstrap.group(group) |
| | | bootstrap.group(eventLoopGroup) |
| | | .channel(NioSocketChannel.class) |
| | | .option(ChannelOption.TCP_NODELAY, true) |
| | | .option(ChannelOption.SO_KEEPALIVE, true) |
| | |
| | | @Override |
| | | protected void initChannel(SocketChannel socketChannel) throws Exception { |
| | | ChannelPipeline pipeline = socketChannel.pipeline(); |
| | | pipeline.addLast("heart",new IdleStateHandler(0, 3, 0, TimeUnit.SECONDS)); |
| | | pipeline.addLast("encoder",new MessageProtocolEncoder()); |
| | | pipeline.addLast("decoder",new MessageProtocolDecoder()); |
| | | pipeline.addLast("handler",clientHandler); |
| | | pipeline.addLast("heart", new IdleStateHandler(0, 3, 0, TimeUnit.SECONDS)); |
| | | pipeline.addLast("encoder", new MessageProtocolEncoder()); |
| | | pipeline.addLast("decoder", new MessageProtocolDecoder()); |
| | | pipeline.addLast("handler", clientHandler); |
| | | } |
| | | }); |
| | | return bootstrap; |
| | | } |
| | | |
| | | // 获取所有连接 |
| | | public void initAllChannel(List<Map<String,Object>> portHosts) { |
| | | for (Map<String, Object> map : portHosts) { |
| | | String host = (String) map.get("IP"); |
| | | Integer port = (Integer) map.get("PORT"); |
| | | initOneConnection(host,port); |
| | | } |
| | | } |
| | | /** |
| | | * 初始化连接 |
| | | */ |
| | | public void initConnection(String host, Integer port) { |
| | | |
| | | public void initOneConnection(String host,Integer port){ |
| | | |
| | | log.info("调用一次{}:{}",host,port); |
| | | //判断该账号下,是否有盒子被控制 |
| | | //当前正在被控制的盒子 |
| | | log.info("初始化连接天宇tcp服务器【{}:{}】", host, port); |
| | | String currentBoxSn = ""; |
| | | if(channels.containsKey(host+"/"+port)) |
| | | { |
| | | currentBoxSn = channels.get(host+"/"+port).getSubBoxSn(); |
| | | channels.get(host+"/"+port).getFuture().channel().close(); |
| | | //判断是否已经存在连接,如果存在则关闭之前的连接 |
| | | if (channels.containsKey(host + ":" + port)) { |
| | | currentBoxSn = channels.get(host + ":" + port).getSubBoxSn(); |
| | | channels.get(host + ":" + port).getChannelFuture().channel().close(); |
| | | } |
| | | |
| | | //异步连接tcp服务端 |
| | | Bootstrap bootstrap = getBootstrap(null); |
| | | ChannelFuture future = bootstrap.connect(host,port).addListener((ChannelFuture futureListener) -> { |
| | | Bootstrap bootstrap = getBootstrap(); |
| | | ChannelFuture future = bootstrap.connect(host, port).addListener((ChannelFuture futureListener) -> { |
| | | if (futureListener.isSuccess()) { |
| | | log.info("连接天宇TCP服务端成功:"+host+":"+port); |
| | | log.info("连接天宇TCP服务器成功【{}:{}】", host, port); |
| | | TyTcpServerCache.putTcpServerCache(host + ":" + port, true); |
| | | } else { |
| | | final EventLoop eventLoop = futureListener.channel().eventLoop(); |
| | | eventLoop.schedule(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | log.info("连接天宇TCP服务端失败ip:{},port:{},正尝试重连...",host,port); |
| | | try { |
| | | initOneConnection(host,port); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | eventLoop.schedule(() -> { |
| | | log.info("连接天宇TCP服务器失败【{}:{}】,正尝试重连...", host, port); |
| | | TyTcpServerCache.putTcpServerCache(host + ":" + port, false); |
| | | try { |
| | | initConnection(host, port); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | }, 5, TimeUnit.SECONDS); |
| | | }, 10, TimeUnit.SECONDS); |
| | | } |
| | | }); |
| | | |
| | | //判断是否有盒子被订阅 |
| | | channels.put(host+"/"+port, TyBoxSession.builder().subBoxSn(currentBoxSn).future(future) |
| | | .isReConnect(!currentBoxSn.equals("")).build()); |
| | | //将连接存入集合 |
| | | channels.put(host + ":" + port, TyBoxSession.builder().subBoxSn(currentBoxSn).channelFuture(future).isReConnect(!currentBoxSn.equals("")).build()); |
| | | } |
| | | } |
| | | |
| | | //创建天宇连接 |
| | | @PostConstruct |
| | | public void createTyConnect() { |
| | | try { |
| | | initConnection(tyConfiguration.getTcpserver(), tyConfiguration.getTcpport()); |
| | | } catch (Exception e) { |
| | | log.error("创建TCP连接异常:{}", e.getMessage()); |
| | | } |
| | | } |
| | | } |