zhangqiankun il y a 2 ans
Parent
commit
56a01d9c9c

+ 9 - 0
src/main/java/com/persagy/cameractl/init/SystemInit.java

@@ -11,6 +11,7 @@ import org.springframework.stereotype.Component;
 import com.persagy.cameractl.conf.CameraApiConfig;
 import com.persagy.cameractl.conf.ServerConfig;
 import com.persagy.cameractl.utils.TimerInterval;
+import com.persagy.socket.IotSocketClient;
 
 import cn.hutool.core.util.StrUtil;
 
@@ -33,6 +34,14 @@ public class SystemInit implements ApplicationRunner {
 		AllStaticConfig.projectId=cameraApiConfig.getProjectId();
 		AllStaticConfig.toupIp=cameraApiConfig.getToupIp();
 		AllStaticConfig.toupPort=StrUtil.isBlank(cameraApiConfig.getToupPort()) ? -1 : Integer.valueOf(cameraApiConfig.getToupPort());
+		if (StrUtil.isNotBlank(cameraApiConfig.getToupIp())) {
+			try {
+				IotSocketClient.connect();
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+		
 		AllStaticConfig.dahuaMesHost=cameraApiConfig.getDahuaMesHost();
 		AllStaticConfig.dahuaApiIp=cameraApiConfig.getDahuaApiIp();
 		AllStaticConfig.dahuaApiPort=cameraApiConfig.getDahuaApiPort();

+ 17 - 6
src/main/java/com/persagy/cameractl/service/DahCameraExecuteApi.java

@@ -18,7 +18,6 @@ import com.persagy.cameractl.utils.ResultClass;
 import com.persagy.cameractl.utils.SdkClient;
 import com.persagy.socket.IotSocketClient;
 
-import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
 
 public class DahCameraExecuteApi {
@@ -287,7 +286,7 @@ public class DahCameraExecuteApi {
             long endMillSeconds = endDate.getTime();
             long endSeconds = endMillSeconds / 1000;
             // 两者之间相差的秒数
-            long between = DateUtil.between(startDate, endDate, DateUnit.SECOND, true);
+            //long between = DateUtil.between(startDate, endDate, DateUnit.SECOND, true);
 
             // 取得设备编号和通道序号
             String[] arrCode = dahCamera.cameraIndexCode.split("\\$");
@@ -443,8 +442,14 @@ public class DahCameraExecuteApi {
     /*投屏*/
     public ResultClass touP(Camera dahCamera) {
     	if ("Pj3101150010".equals(AllStaticConfig.projectId)) {
-			IotSocketClient.connectAndSend(AllStaticConfig.toupIp, AllStaticConfig.toupPort, "C6 11 43 20 02 BB");
-    		return OtherTools.executeSuccess("投屏成功");
+    		try {
+    			IotSocketClient.sendMessage("C6 11 43 20 02 BB");
+    			IotSocketClient.sendMessage("C6 11 43 20 11 BB");
+    			return OtherTools.executeSuccess("投屏成功");
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+    		return OtherTools.executeErr("投屏失败");
 		}
         DpsdkMainWindows dpsdkMainWindows = new DpsdkMainWindows(dahCamera);
         int tvWallId = Integer.parseInt(AllStaticConfig.dahuaTvWallId);
@@ -456,8 +461,14 @@ public class DahCameraExecuteApi {
     /*退出投屏*/
     public ResultClass exitTouP(Camera dahCamera) {
     	if ("Pj3101150010".equals(AllStaticConfig.projectId)) {
-			IotSocketClient.connectAndSend(AllStaticConfig.toupIp, AllStaticConfig.toupPort, "C6 11 43 20 03 BB");
-			return OtherTools.executeSuccess("退出大屏成功");
+    		try {
+    			IotSocketClient.sendMessage("C6 11 43 20 03 BB");
+    			IotSocketClient.sendMessage("C6 11 43 20 11 BB");
+    			return OtherTools.executeSuccess("退出大屏成功");
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+    		return OtherTools.executeErr("退出大屏失败");
 		}
     	
         DpsdkMainWindows dpsdkMainWindows = new DpsdkMainWindows(dahCamera);

+ 18 - 15
src/main/java/com/persagy/socket/IotClientHandler.java

@@ -1,5 +1,9 @@
 package com.persagy.socket;
 
+import java.util.concurrent.TimeUnit;
+
+import com.persagy.cameractl.conf.AllStaticConfig;
+
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.SimpleChannelInboundHandler;
 import lombok.extern.slf4j.Slf4j;
@@ -14,20 +18,12 @@ import lombok.extern.slf4j.Slf4j;
 @Slf4j
 public class IotClientHandler extends SimpleChannelInboundHandler<String> {
 
-	/** 需要调用的指令信息,后缀需携带 短路与 & */
-	private final String command;
-	
-    public IotClientHandler(String command) {
-    	this.command = command;
-	}
-
 	/**
      * 向服务端发送数据
      */
     @Override
     public void channelActive(ChannelHandlerContext ctx) throws Exception {
-    	log.info("发送至服务端的消息: {}", command);
-        ctx.writeAndFlush(command);
+    	log.info("Connected to: {}", ctx.channel().remoteAddress());
     }
 
     /**
@@ -36,10 +32,6 @@ public class IotClientHandler extends SimpleChannelInboundHandler<String> {
     @Override
     protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
         log.info("客户端接收到的服务端信息:" + msg);
-        ctx.writeAndFlush("C6 11 43 20 11 BB");
-        log.info("客户端接回执服务端的信息: C6 11 43 20 11 BB");
-        Thread.sleep(1000);
-        ctx.close();
     }
 	
     /**
@@ -47,15 +39,26 @@ public class IotClientHandler extends SimpleChannelInboundHandler<String> {
      *
      * 当客户端主动断开服务端的链接后,这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
      */
+    @Override
     public void channelInactive(ChannelHandlerContext ctx) throws Exception {
         log.info("客户端与服务端通道关闭:" + ctx.channel().remoteAddress());
-        ctx.close();
     }
 
     @Override
+    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
+    	log.info("channelUnregistered and reconnecting to: {}:{} ", AllStaticConfig.toupIp, AllStaticConfig.toupPort);
+        ctx.channel().eventLoop().schedule(new Runnable() {
+            @Override
+            public void run() {
+                IotSocketClient.reConnect();
+            }
+        }, 5, TimeUnit.SECONDS);
+    }
+    
+    @Override
     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
     	log.warn("通道异常退出", cause);
         ctx.close();
     }
     
-}
+}

+ 64 - 27
src/main/java/com/persagy/socket/IotSocketClient.java

@@ -2,8 +2,12 @@ package com.persagy.socket;
 
 import java.net.InetSocketAddress;
 
+import com.persagy.cameractl.conf.AllStaticConfig;
+
 import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
 import io.netty.channel.ChannelInitializer;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
@@ -23,53 +27,86 @@ import lombok.extern.slf4j.Slf4j;
  */
 @Slf4j
 public class IotSocketClient {
+
+	public static final EventLoopGroup GROUP = new NioEventLoopGroup(1);
+
+	public static final Bootstrap BS = new Bootstrap();
 	
-	public static boolean connectAndSend(String host, int port, String command) {
-		EventLoopGroup group = new NioEventLoopGroup(1);
-		Bootstrap bs = new Bootstrap();
+	public static Channel channel = null;
+
+	static {
 		// 注册线程池、使用NioSocketChannel来作为连接用的channel类
-		bs.group(group).channel(NioSocketChannel.class);
-		
-		boolean result = false;
-		ChannelFuture cf = null;
+		BS.group(GROUP).channel(NioSocketChannel.class);
+	}
+	
+	/**
+	 * 连接
+	 * 
+	 * @date 2022年8月17日 下午12:00:49
+	 */
+	public static void connect() {
 		try {
-			bs.remoteAddress(new InetSocketAddress(host, port)) // 绑定连接端口和host信息
+			BS.remoteAddress(new InetSocketAddress(AllStaticConfig.toupIp, AllStaticConfig.toupPort)) // 绑定连接端口和host信息
 				.handler(new ChannelInitializer<SocketChannel>() { // 绑定连接初始化器
 					@Override
 					protected void initChannel(SocketChannel ch) throws Exception {
 						log.info("正在连接中...");
 						ch.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
 						ch.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8));
-						ch.pipeline().addLast(new IotClientHandler(command));
+						ch.pipeline().addLast(new IotClientHandler());
 					}
 				});
 
-			cf = bs.connect().sync(); // 异步连接服务器
+			ChannelFuture cf = BS.connect().sync(); // 异步连接服务器
+			channel = cf.channel();
 			log.info("服务端连接成功...");
-			
-			result = true;
 		} catch (Exception e) {
 			log.error("与服务端建立连接失败", e);
 		} finally {
-			if (cf != null) {
-				try {
-					cf.channel().closeFuture().sync();
-					log.info("连接已关闭..");
-				} catch (Exception e2) {
-					log.error("未知异常", e2);
-				}
-			}
-			if (group != null) {
-				group.shutdownGracefully();
-				log.info("线程池已关闭..");
-			}
+			
 		}
-		
-		return result;
 	}
+	
+	/**
+	 * 断线重连
+	 * 
+	 * @date 2022年8月16日 下午6:28:24
+	 */
+    public static void reConnect() {
+        // 加入断线后自动重连监听器
+        channel = BS.connect(AllStaticConfig.toupIp, AllStaticConfig.toupPort).addListener(new ChannelFutureListener() {
+            @Override
+            public void operationComplete(ChannelFuture future) throws Exception {
+                if (future.cause() != null) {
+                    log.info("Failed to connect: {}", future.cause());
+                }
+            }
+        }).channel();
+    }
+    
+    /**
+     * 消息发送
+     * @param message
+     * @throws Exception
+     * @date 2022年8月16日 下午6:28:18
+     */
+    public static void sendMessage(String message) throws Exception {
+        if (channel.isActive() && channel.isWritable()) {
+        	log.info("发送数据至服务端: [{}]", message);
+        	
+        	try {
+                channel.writeAndFlush(message);
+            } catch (Exception e) {
+                log.error("发送数据异常", e);
+                channel.close();
+            }
+		}
+    }
 
 	public static void main(String[] args) throws Exception {
-		IotSocketClient.connectAndSend("192.168.100.102", 30054, "(5001120003;1;report;20220617100000;17107;ZD1060;1;902;155)");
+		// 192.168.100.102 30054 (5001120003;1;report;20220717100000;17107;ZD1060;1;902;152)
+		IotSocketClient.connect();
+		IotSocketClient.sendMessage("(5001120003;1;report;20220717100000;17107;ZD1060;1;902;152)");
 	}
 	
 }