package com.ycl.api.DH.utils; import com.sun.jna.Pointer; import com.ycl.api.DH.lib.NetSDKLib; import com.ycl.api.DH.lib.ToolKits; import com.ycl.api.DH.module.LoginModule; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import org.springframework.beans.factory.annotation.Value; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.nio.ByteBuffer; /** * 初始化 * * @author Yan Xu * @version 1.0 * @date 2021/8/6 * Copyright © goodits */ @Component @Slf4j public class InitUtils { @Value("${spring.profiles.active}") private String activeEnv; /** * // 设备断线回调: 通过 CLIENT_Init 设置该回调函数,当设备出现断线时,SDK会调用该函数 */ private static class DisConnect implements NetSDKLib.fDisConnect { @Override public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) { log.info("Device[{}}] Port[{}}] DisConnect!\n", pchDVRIP, nDVRPort); } } /** * // 网络连接恢复,设备重连成功回调 * // 通过 CLIENT_SetAutoReconnect 设置该回调函数,当已断线的设备重连成功时,SDK会调用该函数 */ private static class HaveReConnect implements NetSDKLib.fHaveReConnect { @Override public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) { log.info("ReConnect Device[{}] Port[{}]\n", pchDVRIP, nDVRPort); } } /** * 写成静态主要是防止被回收 */ private static class AnalyzerDataCB implements NetSDKLib.fAnalyzerDataCallBack { private AnalyzerDataCB() { } public static AnalyzerDataCB INSTANCE = new AnalyzerDataCB(); public static AnalyzerDataCB getInstance() { return INSTANCE; } public int invoke( NetSDKLib.LLong lAnalyzerHandle, int dwAlarmType, Pointer pAlarmInfo, Pointer pBuffer, int dwBufSize, Pointer dwUser, int nSequence, Pointer reserved) { if (lAnalyzerHandle.longValue() == 0 || pAlarmInfo == null) { return -1; } switch (dwAlarmType) { case NetSDKLib.EVENT_IVS_ACCESS_CTL:// /< 门禁事件 { NetSDKLib.DEV_EVENT_ACCESS_CTL_INFO msg = new NetSDKLib.DEV_EVENT_ACCESS_CTL_INFO(); ToolKits.GetPointerData(pAlarmInfo, msg); // 获取门禁信息 //打印msg中的卡信息和用戶信息 int szCardNo = ByteBuffer.wrap(msg.szCardNo).getInt(); System.out.println("卡号:" + szCardNo); int szUserId = ByteBuffer.wrap(msg.szUserID).getInt(); System.out.printf("用户ID:%d\n", szUserId); log.info("门禁事件:卡号:{},用户ID:{}", szCardNo, szUserId); // 释放内存 msg = null; System.gc(); break; } case NetSDKLib.EVENT_IVS_FACERECOGNITION: // /< 人脸识别事件 { // DEV_EVENT_FACERECOGNITION_INFO 结构体比较大,new对象会比较耗时, ToolKits.GetPointerData内容拷贝是不耗时的。 // 如果多台设备或者事件处理比较频繁,可以考虑将 static DEV_EVENT_FACERECOGNITION_INFO msg = new // DEV_EVENT_FACERECOGNITION_INFO(); 改为全局。 // 写成全局,是因为每次new花费时间较多, 如果改为全局,此case下的处理需要加锁 // 加锁,是因为共用一个对象,防止数据出错 // 耗时800ms左右 NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO msg = new NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO(); // 耗时20ms左右 ToolKits.GetPointerData(pAlarmInfo, msg); // 保存人脸对比信息 // 释放内存 msg = null; System.gc(); break; } case NetSDKLib.EVENT_IVS_FACEDETECT: // /< 人脸检测 { NetSDKLib.DEV_EVENT_FACEDETECT_INFO msg = new NetSDKLib.DEV_EVENT_FACEDETECT_INFO(); ToolKits.GetPointerData(pAlarmInfo, msg); // 保存图片,获取图片缓存 // 释放内存 msg = null; System.gc(); break; } default: break; } return 0; } } /** * 设备断线通知回调 */ private static final DisConnect DIS_CONNECT = new DisConnect() { }; /** * 网络连接恢复 */ private static final HaveReConnect HAVE_RE_CONNECT = new HaveReConnect(); @PostConstruct void init() { if("prod".equals(activeEnv)) { LoginModule.init(DIS_CONNECT, HAVE_RE_CONNECT); } } @PreDestroy void clean(){ if("prod".equals(activeEnv)) { LoginModule.cleanup(); } } }