一、问题
在使用海康sdk接收温度报警时,通过先去初始化设备然后没初始化一个设备就会获取一个独有的userId,这个userId是海康sdk的NET_DVR_Login_V30方法返回的,然后通过自己创建的实体类去set这个userId,最后把这个摄像仪添加到集合里面,理论可行,但是当我有80多台摄像仪同时去监听温度报警时就会出现报警混乱(例如IP55的摄像仪报警,但是接收的确实IP66的摄像仪),因为我是使用定时任务去执行的,刚开始以为是任务执行完了以后没有成功注销导致获取的userId重复(这个也确实是一个原因)于是我就修改注册时间为55分钟,定时任务每小时执行一次,后来发现还是不行。不说废话直接上代码
这是初始化的时候获取userId,然后给cameraInfo赋值
然后在run方法监听里面去调用上述方法,如果注册成功会把userId返回去
注册成功后线程睡眠40分钟进行监听,40分钟后停止接收报警
告警监听类这是我用的原本的方法去接收的
如果发生了超温报警那么就进入到超温报警的方法
然后去插入报警数据到数据库,但是我发现设备多了以后会增加好多重复报警,并且显示是不同设备(报警图片是同一张)。
二、解决方案
直接通过获取userId经常不唯一,因为当设备没有完全注销后可能注册的userId和上一个重复,解决方案就是通过Ip去获取设备,因为每个设备的IP是唯一的。通过这个想法我去查看海康提供的sdk里面的报警设备信息NET_DVR_ALARMER确实提供了IP,但是是byte[]数组,如图
然后我们将字节数组转换为字符串并去除空字符,这样就获取了IP
// 获取 sDeviceIp 字节数组byte[] sDeviceIp = pAlarmer.sDeviceIP;// 将字节数组转换为字符串并去除空字符String ipAddress = new String(sDeviceIp, 0, 15).trim(); // 取前 15 个字节,因为 IP 地址最大为 15 个字符// 输出 IP 地址,格式为 192.168.10.68System.out.println("设备 IP 地址: " + ipAddress);//CameraInfo camera = getCamera(lUserID);CameraInfo camera = getCameraByIp(ipAddress);
然后再写一个根据IP去获取摄像仪的方法即可
private CameraInfo getCameraByIp(String ipAddress) {for (CameraInfo camera : cameraInfos) {if (camera.getIpAdress().equals(ipAddress)) {return camera;}}return null;}
这样获取到的设备就是唯一的,就不会出现报警混乱的问题。