Commit 6e90050db47ca1d9ecec3de6bd95ea1bd1ca4060

Authored by 648540858
1 parent 8b6449ce

去除zlm使用redis过期作为心跳超时的方式

src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -14,8 +14,6 @@ public class VideoManagerConstants { @@ -14,8 +14,6 @@ public class VideoManagerConstants {
14 14
15 public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_"; 15 public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_";
16 16
17 - public static final String MEDIA_SERVER_KEEPALIVE_PREFIX = "VMP_MEDIA_SERVER_KEEPALIVE_";  
18 -  
19 public static final String MEDIA_SERVERS_ONLINE_PREFIX = "VMP_MEDIA_ONLINE_SERVERS_"; 17 public static final String MEDIA_SERVERS_ONLINE_PREFIX = "VMP_MEDIA_ONLINE_SERVERS_";
20 18
21 public static final String MEDIA_STREAM_PREFIX = "VMP_MEDIA_STREAM"; 19 public static final String MEDIA_STREAM_PREFIX = "VMP_MEDIA_STREAM";
src/main/java/com/genersoft/iot/vmp/conf/RedisKeyExpirationEventMessageListener.java renamed to src/main/java/com/genersoft/iot/vmp/conf/redis/RedisKeyExpirationEventMessageListener.java
1 -package com.genersoft.iot.vmp.conf; 1 +package com.genersoft.iot.vmp.conf.redis;
2 2
  3 +import com.genersoft.iot.vmp.conf.UserSetting;
3 import org.springframework.data.redis.connection.RedisConnection; 4 import org.springframework.data.redis.connection.RedisConnection;
4 import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; 5 import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
5 import org.springframework.data.redis.listener.RedisMessageListenerContainer; 6 import org.springframework.data.redis.listener.RedisMessageListenerContainer;
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.event.offline;
  2 +
  3 +import com.genersoft.iot.vmp.conf.UserSetting;
  4 +import com.genersoft.iot.vmp.conf.redis.RedisKeyExpirationEventMessageListener;
  5 +import com.genersoft.iot.vmp.gb28181.bean.Device;
  6 +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  7 +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
  8 +import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
  9 +import org.slf4j.Logger;
  10 +import org.slf4j.LoggerFactory;
  11 +import org.springframework.beans.factory.annotation.Autowired;
  12 +import org.springframework.data.redis.connection.Message;
  13 +import org.springframework.data.redis.listener.RedisMessageListenerContainer;
  14 +import org.springframework.stereotype.Component;
  15 +
  16 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  17 +import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
  18 +
  19 +/**
  20 + * 设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
  21 + * @author swwheihei
  22 + */
  23 +@Component
  24 +public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEventMessageListener {
  25 +
  26 + private Logger logger = LoggerFactory.getLogger(KeepaliveTimeoutListenerForPlatform.class);
  27 +
  28 + @Autowired
  29 + private EventPublisher publisher;
  30 +
  31 + @Autowired
  32 + private UserSetting userSetting;
  33 +
  34 + @Autowired
  35 + private SipSubscribe sipSubscribe;
  36 +
  37 + @Autowired
  38 + private IVideoManagerStorage storager;
  39 +
  40 + public KeepaliveTimeoutListenerForPlatform(RedisMessageListenerContainer listenerContainer, UserSetting userSetting) {
  41 + super(listenerContainer, userSetting);
  42 + }
  43 +
  44 +
  45 + /**
  46 + * 监听失效的key
  47 + * @param message
  48 + * @param pattern
  49 + */
  50 + @Override
  51 + public void onMessage(Message message, byte[] pattern) {
  52 + // 获取失效的key
  53 + String expiredKey = message.toString();
  54 + // 平台心跳到期,需要重发, 判断是否已经多次未收到心跳回复, 多次未收到,则重新发起注册, 注册尝试多次未得到回复,则认为平台离线
  55 + String PLATFORM_KEEPLIVEKEY_PREFIX = VideoManagerConstants.PLATFORM_KEEPALIVE_PREFIX + userSetting.getServerId() + "_";
  56 + String PLATFORM_REGISTER_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_PREFIX + userSetting.getServerId() + "_";
  57 + String REGISTER_INFO_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_";
  58 + if (expiredKey.startsWith(PLATFORM_KEEPLIVEKEY_PREFIX)) {
  59 + String platformGbId = expiredKey.substring(PLATFORM_KEEPLIVEKEY_PREFIX.length());
  60 + ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGbId);
  61 + if (platform != null) {
  62 + publisher.platformKeepaliveExpireEventPublish(platformGbId);
  63 + }
  64 + }else if (expiredKey.startsWith(PLATFORM_REGISTER_PREFIX)) {
  65 + String platformGbId = expiredKey.substring(PLATFORM_REGISTER_PREFIX.length(),expiredKey.length());
  66 + ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGbId);
  67 + if (platform != null) {
  68 + publisher.platformRegisterCycleEventPublish(platformGbId);
  69 + }
  70 + }else if (expiredKey.startsWith(REGISTER_INFO_PREFIX)) {
  71 + String callId = expiredKey.substring(REGISTER_INFO_PREFIX.length());
  72 + if (sipSubscribe.getErrorSubscribe(callId) != null) {
  73 + SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult();
  74 + eventResult.callId = callId;
  75 + eventResult.msg = "注册超时";
  76 + eventResult.type = "register timeout";
  77 + sipSubscribe.getErrorSubscribe(callId).response(eventResult);
  78 + }
  79 + }
  80 + }
  81 +}
src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMKeepliveTimeoutListener.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.media.zlm.event;  
2 -  
3 -import com.alibaba.fastjson.JSONObject;  
4 -import com.genersoft.iot.vmp.common.VideoManagerConstants;  
5 -import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener;  
6 -import com.genersoft.iot.vmp.conf.UserSetting;  
7 -import com.genersoft.iot.vmp.gb28181.event.EventPublisher;  
8 -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;  
9 -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;  
10 -import com.genersoft.iot.vmp.service.IMediaServerService;  
11 -import org.slf4j.Logger;  
12 -import org.slf4j.LoggerFactory;  
13 -import org.springframework.beans.factory.annotation.Autowired;  
14 -import org.springframework.data.redis.connection.Message;  
15 -import org.springframework.data.redis.listener.RedisMessageListenerContainer;  
16 -import org.springframework.stereotype.Component;  
17 -  
18 -/**  
19 - * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件  
20 - * @author: swwheihei  
21 - * @date: 2020年5月6日 上午11:35:46  
22 - */  
23 -@Component  
24 -public class ZLMKeepliveTimeoutListener extends RedisKeyExpirationEventMessageListener {  
25 -  
26 - private Logger logger = LoggerFactory.getLogger(ZLMKeepliveTimeoutListener.class);  
27 -  
28 - @Autowired  
29 - private EventPublisher publisher;  
30 -  
31 - @Autowired  
32 - private ZLMRESTfulUtils zlmresTfulUtils;  
33 -  
34 - @Autowired  
35 - private UserSetting userSetting;  
36 -  
37 - @Autowired  
38 - private IMediaServerService mediaServerService;  
39 -  
40 - public ZLMKeepliveTimeoutListener(RedisMessageListenerContainer listenerContainer, UserSetting userSetting) {  
41 - super(listenerContainer, userSetting);  
42 - }  
43 -  
44 -  
45 - /**  
46 - * 监听失效的key,key格式为keeplive_deviceId  
47 - * @param message  
48 - * @param pattern  
49 - */  
50 - @Override  
51 - public void onMessage(Message message, byte[] pattern) {  
52 - // 获取失效的key  
53 - String expiredKey = message.toString();  
54 - String KEEPLIVEKEY_PREFIX = VideoManagerConstants.MEDIA_SERVER_KEEPALIVE_PREFIX + userSetting.getServerId() + "_";  
55 - if(!expiredKey.startsWith(KEEPLIVEKEY_PREFIX)){  
56 - return;  
57 - }  
58 -  
59 - String mediaServerId = expiredKey.substring(KEEPLIVEKEY_PREFIX.length(),expiredKey.length());  
60 - logger.info("[zlm心跳到期]:" + mediaServerId);  
61 - // 发起http请求验证zlm是否确实无法连接,如果确实无法连接则发送离线事件,否则不作处理  
62 - MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);  
63 - JSONObject mediaServerConfig = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);  
64 - if (mediaServerConfig != null && mediaServerConfig.getInteger("code") == 0) {  
65 - logger.info("[zlm心跳到期]:{}验证后zlm仍在线,恢复心跳信息", mediaServerId);  
66 - // 添加zlm信息  
67 - mediaServerService.updateMediaServerKeepalive(mediaServerId, mediaServerConfig);  
68 - }else {  
69 - publisher.zlmOfflineEventPublish(mediaServerId);  
70 - }  
71 - }  
72 -}  
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
@@ -8,6 +8,7 @@ import java.util.List; @@ -8,6 +8,7 @@ import java.util.List;
8 import java.util.Map; 8 import java.util.Map;
9 import java.util.Set; 9 import java.util.Set;
10 10
  11 +import com.genersoft.iot.vmp.conf.DynamicTask;
11 import com.genersoft.iot.vmp.conf.exception.ControllerException; 12 import com.genersoft.iot.vmp.conf.exception.ControllerException;
12 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; 13 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
13 import org.slf4j.Logger; 14 import org.slf4j.Logger;
@@ -53,6 +54,8 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -53,6 +54,8 @@ public class MediaServerServiceImpl implements IMediaServerService {
53 54
54 private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class); 55 private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class);
55 56
  57 + private final String zlmKeepaliveKeyPrefix = "zlm-keepalive_";
  58 +
56 @Autowired 59 @Autowired
57 private SipConfig sipConfig; 60 private SipConfig sipConfig;
58 61
@@ -83,10 +86,12 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -83,10 +86,12 @@ public class MediaServerServiceImpl implements IMediaServerService {
83 @Autowired 86 @Autowired
84 private ZLMRTPServerFactory zlmrtpServerFactory; 87 private ZLMRTPServerFactory zlmrtpServerFactory;
85 88
86 -  
87 @Autowired 89 @Autowired
88 private EventPublisher publisher; 90 private EventPublisher publisher;
89 91
  92 + @Autowired
  93 + private DynamicTask dynamicTask;
  94 +
90 /** 95 /**
91 * 初始化 96 * 初始化
92 */ 97 */
@@ -398,11 +403,37 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -398,11 +403,37 @@ public class MediaServerServiceImpl implements IMediaServerService {
398 if (serverItem.isAutoConfig()) { 403 if (serverItem.isAutoConfig()) {
399 setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable())); 404 setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable()));
400 } 405 }
  406 + final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + serverItem.getId();
  407 + dynamicTask.stop(zlmKeepaliveKey);
  408 + dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(serverItem), serverItem.getHookAliveInterval() * 1000);
401 publisher.zlmOnlineEventPublish(serverItem.getId()); 409 publisher.zlmOnlineEventPublish(serverItem.getId());
402 logger.info("[ZLM] 连接成功 {} - {}:{} ", 410 logger.info("[ZLM] 连接成功 {} - {}:{} ",
403 zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); 411 zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort());
404 } 412 }
405 413
  414 + class KeepAliveTimeoutRunnable implements Runnable{
  415 +
  416 + private MediaServerItem serverItem;
  417 +
  418 + public KeepAliveTimeoutRunnable(MediaServerItem serverItem) {
  419 + this.serverItem = serverItem;
  420 + }
  421 +
  422 + @Override
  423 + public void run() {
  424 + logger.info("[zlm心跳到期]:" + serverItem.getId());
  425 + // 发起http请求验证zlm是否确实无法连接,如果确实无法连接则发送离线事件,否则不作处理
  426 + JSONObject mediaServerConfig = zlmresTfulUtils.getMediaServerConfig(serverItem);
  427 + if (mediaServerConfig != null && mediaServerConfig.getInteger("code") == 0) {
  428 + logger.info("[zlm心跳到期]:{}验证后zlm仍在线,恢复心跳信息,请检查zlm是否可以正常向wvp发送心跳", serverItem.getId());
  429 + // 添加zlm信息
  430 + updateMediaServerKeepalive(serverItem.getId(), mediaServerConfig);
  431 + }else {
  432 + publisher.zlmOfflineEventPublish(serverItem.getId());
  433 + }
  434 + }
  435 + }
  436 +
406 437
407 @Override 438 @Override
408 public void zlmServerOffline(String mediaServerId) { 439 public void zlmServerOffline(String mediaServerId) {
@@ -429,7 +460,6 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -429,7 +460,6 @@ public class MediaServerServiceImpl implements IMediaServerService {
429 }else { 460 }else {
430 clearRTPServer(serverItem); 461 clearRTPServer(serverItem);
431 } 462 }
432 -  
433 } 463 }
434 464
435 465
@@ -625,9 +655,9 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -625,9 +655,9 @@ public class MediaServerServiceImpl implements IMediaServerService {
625 return; 655 return;
626 } 656 }
627 } 657 }
628 - String key = VideoManagerConstants.MEDIA_SERVER_KEEPALIVE_PREFIX + userSetting.getServerId() + "_" + mediaServerId;  
629 - int hookAliveInterval = mediaServerItem.getHookAliveInterval() + 2;  
630 - RedisUtil.set(key, data, hookAliveInterval); 658 + final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + mediaServerItem.getId();
  659 + dynamicTask.stop(zlmKeepaliveKey);
  660 + dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(mediaServerItem), mediaServerItem.getHookAliveInterval() * 1000);
631 } 661 }
632 662
633 private MediaServerItem getOneFromDatabase(String mediaServerId) { 663 private MediaServerItem getOneFromDatabase(String mediaServerId) {