fuliqi
2025-02-21 64efb660b2c119c00432434c0f651f8996483f18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
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();
        }
    }
}