Commit a82b831b8b2b96dfa5791808f1207500e16697cf
1 parent
09bfc69f
优化设备状态保持,自动记录心跳间隔,三次心跳失败则设备离线,不在使用设备有效期字段作为唯一判断标准,提高容错能力和稳定性。
Showing
7 changed files
with
51 additions
and
52 deletions
pom.xml
| @@ -11,7 +11,7 @@ | @@ -11,7 +11,7 @@ | ||
| 11 | 11 | ||
| 12 | <groupId>com.genersoft</groupId> | 12 | <groupId>com.genersoft</groupId> |
| 13 | <artifactId>wvp-pro</artifactId> | 13 | <artifactId>wvp-pro</artifactId> |
| 14 | - <version>2.6.6</version> | 14 | + <version>2.6.7</version> |
| 15 | <name>web video platform</name> | 15 | <name>web video platform</name> |
| 16 | <description>国标28181视频平台</description> | 16 | <description>国标28181视频平台</description> |
| 17 | 17 |
sql/update.sql
| 1 | -alter table media_server | ||
| 2 | - drop column streamNoneReaderDelayMS; | ||
| 3 | - | ||
| 4 | -alter table media_server | ||
| 5 | - drop column sendRtpPortRange; | ||
| 6 | - | ||
| 7 | -alter table stream_proxy | ||
| 8 | - add enable_disable_none_reader bit(1) default null; | ||
| 9 | - | 1 | +-- 2.6.6->2.6.7 |
| 10 | alter table device | 2 | alter table device |
| 11 | - add mediaServerId varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'auto'; | ||
| 12 | - | ||
| 13 | -alter table device | ||
| 14 | - add custom_name varchar(255) default null; | ||
| 15 | - | ||
| 16 | -alter table device | ||
| 17 | - add sdpIp varchar(50) default null; | ||
| 18 | - | ||
| 19 | -alter table device | ||
| 20 | - add localIp varchar(50) default null; | ||
| 21 | - | ||
| 22 | -alter table device | ||
| 23 | - add password varchar(255) default null; | ||
| 24 | - | ||
| 25 | -alter table device | ||
| 26 | - modify ip varchar(50) null; | ||
| 27 | - | ||
| 28 | -alter table device | ||
| 29 | - modify port int null; | ||
| 30 | - | ||
| 31 | -alter table device | ||
| 32 | - modify expires int null; | ||
| 33 | - | ||
| 34 | -alter table device | ||
| 35 | - modify subscribeCycleForCatalog int null; | ||
| 36 | - | ||
| 37 | -alter table device | ||
| 38 | - modify hostAddress varchar(50) null; | ||
| 39 | - | ||
| 40 | -alter table stream_proxy | ||
| 41 | - change enable_hls enable_audio bit null; | ||
| 42 | - | ||
| 43 | - | 3 | + add keepaliveIntervalTime int default null; |
| 44 | \ No newline at end of file | 4 | \ No newline at end of file |
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
| @@ -70,6 +70,8 @@ public class VideoManagerConstants { | @@ -70,6 +70,8 @@ public class VideoManagerConstants { | ||
| 70 | 70 | ||
| 71 | public static final String SYSTEM_INFO_DISK_PREFIX = "VMP_SYSTEM_INFO_DISK_"; | 71 | public static final String SYSTEM_INFO_DISK_PREFIX = "VMP_SYSTEM_INFO_DISK_"; |
| 72 | 72 | ||
| 73 | + public static final String REGISTER_EXPIRE_TASK_KEY_PREFIX = "VMP_device_register_expire_"; | ||
| 74 | + | ||
| 73 | 75 | ||
| 74 | 76 | ||
| 75 | 77 |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
| @@ -94,6 +94,13 @@ public class Device { | @@ -94,6 +94,13 @@ public class Device { | ||
| 94 | @Schema(description = "心跳时间") | 94 | @Schema(description = "心跳时间") |
| 95 | private String keepaliveTime; | 95 | private String keepaliveTime; |
| 96 | 96 | ||
| 97 | + | ||
| 98 | + /** | ||
| 99 | + * 心跳间隔 | ||
| 100 | + */ | ||
| 101 | + @Schema(description = "心跳间隔") | ||
| 102 | + private int keepaliveIntervalTime; | ||
| 103 | + | ||
| 97 | /** | 104 | /** |
| 98 | * 通道个数 | 105 | * 通道个数 |
| 99 | */ | 106 | */ |
| @@ -413,4 +420,12 @@ public class Device { | @@ -413,4 +420,12 @@ public class Device { | ||
| 413 | public void setLocalIp(String localIp) { | 420 | public void setLocalIp(String localIp) { |
| 414 | this.localIp = localIp; | 421 | this.localIp = localIp; |
| 415 | } | 422 | } |
| 423 | + | ||
| 424 | + public int getKeepaliveIntervalTime() { | ||
| 425 | + return keepaliveIntervalTime; | ||
| 426 | + } | ||
| 427 | + | ||
| 428 | + public void setKeepaliveIntervalTime(int keepaliveIntervalTime) { | ||
| 429 | + this.keepaliveIntervalTime = keepaliveIntervalTime; | ||
| 430 | + } | ||
| 416 | } | 431 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
| 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd; | 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd; |
| 2 | 2 | ||
| 3 | +import com.genersoft.iot.vmp.common.VideoManagerConstants; | ||
| 4 | +import com.genersoft.iot.vmp.conf.DynamicTask; | ||
| 3 | import com.genersoft.iot.vmp.conf.UserSetting; | 5 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 4 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 6 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 5 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | 7 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| @@ -43,6 +45,9 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp | @@ -43,6 +45,9 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp | ||
| 43 | @Autowired | 45 | @Autowired |
| 44 | private UserSetting userSetting; | 46 | private UserSetting userSetting; |
| 45 | 47 | ||
| 48 | + @Autowired | ||
| 49 | + private DynamicTask dynamicTask; | ||
| 50 | + | ||
| 46 | @Override | 51 | @Override |
| 47 | public void afterPropertiesSet() throws Exception { | 52 | public void afterPropertiesSet() throws Exception { |
| 48 | notifyMessageHandler.addHandler(cmdType, this); | 53 | notifyMessageHandler.addHandler(cmdType, this); |
| @@ -68,6 +73,13 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp | @@ -68,6 +73,13 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp | ||
| 68 | device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort()))); | 73 | device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort()))); |
| 69 | device.setIp(remoteAddressInfo.getIp()); | 74 | device.setIp(remoteAddressInfo.getIp()); |
| 70 | } | 75 | } |
| 76 | + if (device.getKeepaliveTime() == null) { | ||
| 77 | + device.setKeepaliveIntervalTime(60); | ||
| 78 | + }else { | ||
| 79 | + long lastTime = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(device.getKeepaliveTime()); | ||
| 80 | + device.setKeepaliveIntervalTime(new Long(System.currentTimeMillis()/1000-lastTime).intValue()); | ||
| 81 | + } | ||
| 82 | + | ||
| 71 | device.setKeepaliveTime(DateUtil.getNow()); | 83 | device.setKeepaliveTime(DateUtil.getNow()); |
| 72 | 84 | ||
| 73 | if (device.getOnline() == 1) { | 85 | if (device.getOnline() == 1) { |
| @@ -75,9 +87,15 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp | @@ -75,9 +87,15 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp | ||
| 75 | }else { | 87 | }else { |
| 76 | // 对于已经离线的设备判断他的注册是否已经过期 | 88 | // 对于已经离线的设备判断他的注册是否已经过期 |
| 77 | if (!deviceService.expire(device)){ | 89 | if (!deviceService.expire(device)){ |
| 90 | + device.setOnline(0); | ||
| 78 | deviceService.online(device); | 91 | deviceService.online(device); |
| 79 | } | 92 | } |
| 80 | } | 93 | } |
| 94 | + // 刷新过期任务 | ||
| 95 | + String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId(); | ||
| 96 | + // 如果三次心跳失败,则设置设备离线 | ||
| 97 | + dynamicTask.startDelay(registerExpireTaskKey, ()-> deviceService.offline(device.getDeviceId()), device.getKeepaliveIntervalTime()*1000*3); | ||
| 98 | + | ||
| 81 | } | 99 | } |
| 82 | 100 | ||
| 83 | @Override | 101 | @Override |
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
| 1 | package com.genersoft.iot.vmp.service.impl; | 1 | package com.genersoft.iot.vmp.service.impl; |
| 2 | 2 | ||
| 3 | +import com.genersoft.iot.vmp.common.VideoManagerConstants; | ||
| 3 | import com.genersoft.iot.vmp.conf.DynamicTask; | 4 | import com.genersoft.iot.vmp.conf.DynamicTask; |
| 4 | import com.genersoft.iot.vmp.conf.UserSetting; | 5 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 5 | import com.genersoft.iot.vmp.gb28181.bean.*; | 6 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| @@ -45,8 +46,6 @@ public class DeviceServiceImpl implements IDeviceService { | @@ -45,8 +46,6 @@ public class DeviceServiceImpl implements IDeviceService { | ||
| 45 | 46 | ||
| 46 | private final static Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class); | 47 | private final static Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class); |
| 47 | 48 | ||
| 48 | - private final String registerExpireTaskKeyPrefix = "device-register-expire-"; | ||
| 49 | - | ||
| 50 | @Autowired | 49 | @Autowired |
| 51 | private DynamicTask dynamicTask; | 50 | private DynamicTask dynamicTask; |
| 52 | 51 | ||
| @@ -101,7 +100,10 @@ public class DeviceServiceImpl implements IDeviceService { | @@ -101,7 +100,10 @@ public class DeviceServiceImpl implements IDeviceService { | ||
| 101 | redisCatchStorage.clearCatchByDeviceId(device.getDeviceId()); | 100 | redisCatchStorage.clearCatchByDeviceId(device.getDeviceId()); |
| 102 | } | 101 | } |
| 103 | device.setUpdateTime(now); | 102 | device.setUpdateTime(now); |
| 104 | - | 103 | + if (device.getKeepaliveIntervalTime() == 0) { |
| 104 | + // 默认心跳间隔60 | ||
| 105 | + device.setKeepaliveIntervalTime(60); | ||
| 106 | + } | ||
| 105 | // 第一次上线 或则设备之前是离线状态--进行通道同步和设备信息查询 | 107 | // 第一次上线 或则设备之前是离线状态--进行通道同步和设备信息查询 |
| 106 | if (device.getCreateTime() == null) { | 108 | if (device.getCreateTime() == null) { |
| 107 | device.setOnline(1); | 109 | device.setOnline(1); |
| @@ -116,7 +118,6 @@ public class DeviceServiceImpl implements IDeviceService { | @@ -116,7 +118,6 @@ public class DeviceServiceImpl implements IDeviceService { | ||
| 116 | } | 118 | } |
| 117 | sync(device); | 119 | sync(device); |
| 118 | }else { | 120 | }else { |
| 119 | - | ||
| 120 | if(device.getOnline() == 0){ | 121 | if(device.getOnline() == 0){ |
| 121 | device.setOnline(1); | 122 | device.setOnline(1); |
| 122 | device.setCreateTime(now); | 123 | device.setCreateTime(now); |
| @@ -153,19 +154,19 @@ public class DeviceServiceImpl implements IDeviceService { | @@ -153,19 +154,19 @@ public class DeviceServiceImpl implements IDeviceService { | ||
| 153 | addMobilePositionSubscribe(device); | 154 | addMobilePositionSubscribe(device); |
| 154 | } | 155 | } |
| 155 | // 刷新过期任务 | 156 | // 刷新过期任务 |
| 156 | - String registerExpireTaskKey = registerExpireTaskKeyPrefix + device.getDeviceId(); | ||
| 157 | - // 增加一个10秒给设备重发消息的机会 | ||
| 158 | - dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId()), (device.getExpires() + 10) * 1000); | 157 | + String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId(); |
| 158 | + // 如果第一次注册那么必须在60 * 3时间内收到一个心跳,否则设备离线 | ||
| 159 | + dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId()), device.getKeepaliveIntervalTime() * 1000 * 3); | ||
| 159 | } | 160 | } |
| 160 | 161 | ||
| 161 | @Override | 162 | @Override |
| 162 | public void offline(String deviceId) { | 163 | public void offline(String deviceId) { |
| 163 | - logger.info("[设备离线], device:{}", deviceId); | 164 | + logger.error("[设备离线], device:{}", deviceId); |
| 164 | Device device = deviceMapper.getDeviceByDeviceId(deviceId); | 165 | Device device = deviceMapper.getDeviceByDeviceId(deviceId); |
| 165 | if (device == null) { | 166 | if (device == null) { |
| 166 | return; | 167 | return; |
| 167 | } | 168 | } |
| 168 | - String registerExpireTaskKey = registerExpireTaskKeyPrefix + deviceId; | 169 | + String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + deviceId; |
| 169 | dynamicTask.stop(registerExpireTaskKey); | 170 | dynamicTask.stop(registerExpireTaskKey); |
| 170 | device.setOnline(0); | 171 | device.setOnline(0); |
| 171 | redisCatchStorage.updateDevice(device); | 172 | redisCatchStorage.updateDevice(device); |
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
| @@ -61,6 +61,7 @@ public interface DeviceMapper { | @@ -61,6 +61,7 @@ public interface DeviceMapper { | ||
| 61 | "expires," + | 61 | "expires," + |
| 62 | "registerTime," + | 62 | "registerTime," + |
| 63 | "keepaliveTime," + | 63 | "keepaliveTime," + |
| 64 | + "keepaliveIntervalTime," + | ||
| 64 | "createTime," + | 65 | "createTime," + |
| 65 | "updateTime," + | 66 | "updateTime," + |
| 66 | "charset," + | 67 | "charset," + |
| @@ -88,6 +89,7 @@ public interface DeviceMapper { | @@ -88,6 +89,7 @@ public interface DeviceMapper { | ||
| 88 | "#{expires}," + | 89 | "#{expires}," + |
| 89 | "#{registerTime}," + | 90 | "#{registerTime}," + |
| 90 | "#{keepaliveTime}," + | 91 | "#{keepaliveTime}," + |
| 92 | + "#{keepaliveIntervalTime}," + | ||
| 91 | "#{createTime}," + | 93 | "#{createTime}," + |
| 92 | "#{updateTime}," + | 94 | "#{updateTime}," + |
| 93 | "#{charset}," + | 95 | "#{charset}," + |
| @@ -117,6 +119,7 @@ public interface DeviceMapper { | @@ -117,6 +119,7 @@ public interface DeviceMapper { | ||
| 117 | "<if test=\"online != null\">, online=${online}</if>" + | 119 | "<if test=\"online != null\">, online=${online}</if>" + |
| 118 | "<if test=\"registerTime != null\">, registerTime='${registerTime}'</if>" + | 120 | "<if test=\"registerTime != null\">, registerTime='${registerTime}'</if>" + |
| 119 | "<if test=\"keepaliveTime != null\">, keepaliveTime='${keepaliveTime}'</if>" + | 121 | "<if test=\"keepaliveTime != null\">, keepaliveTime='${keepaliveTime}'</if>" + |
| 122 | + "<if test=\"keepaliveIntervalTime != null\">, keepaliveIntervalTime='${keepaliveIntervalTime}'</if>" + | ||
| 120 | "<if test=\"expires != null\">, expires=${expires}</if>" + | 123 | "<if test=\"expires != null\">, expires=${expires}</if>" + |
| 121 | "WHERE deviceId='${deviceId}'"+ | 124 | "WHERE deviceId='${deviceId}'"+ |
| 122 | " </script>"}) | 125 | " </script>"}) |