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 14  
15 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 17 public static final String MEDIA_SERVERS_ONLINE_PREFIX = "VMP_MEDIA_ONLINE_SERVERS_";
20 18  
21 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 4 import org.springframework.data.redis.connection.RedisConnection;
4 5 import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
5 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 8 import java.util.Map;
9 9 import java.util.Set;
10 10  
  11 +import com.genersoft.iot.vmp.conf.DynamicTask;
11 12 import com.genersoft.iot.vmp.conf.exception.ControllerException;
12 13 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
13 14 import org.slf4j.Logger;
... ... @@ -53,6 +54,8 @@ public class MediaServerServiceImpl implements IMediaServerService {
53 54  
54 55 private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class);
55 56  
  57 + private final String zlmKeepaliveKeyPrefix = "zlm-keepalive_";
  58 +
56 59 @Autowired
57 60 private SipConfig sipConfig;
58 61  
... ... @@ -83,10 +86,12 @@ public class MediaServerServiceImpl implements IMediaServerService {
83 86 @Autowired
84 87 private ZLMRTPServerFactory zlmrtpServerFactory;
85 88  
86   -
87 89 @Autowired
88 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 403 if (serverItem.isAutoConfig()) {
399 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 409 publisher.zlmOnlineEventPublish(serverItem.getId());
402 410 logger.info("[ZLM] 连接成功 {} - {}:{} ",
403 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 438 @Override
408 439 public void zlmServerOffline(String mediaServerId) {
... ... @@ -429,7 +460,6 @@ public class MediaServerServiceImpl implements IMediaServerService {
429 460 }else {
430 461 clearRTPServer(serverItem);
431 462 }
432   -
433 463 }
434 464  
435 465  
... ... @@ -625,9 +655,9 @@ public class MediaServerServiceImpl implements IMediaServerService {
625 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 663 private MediaServerItem getOneFromDatabase(String mediaServerId) {
... ...