Commit 6e90050db47ca1d9ecec3de6bd95ea1bd1ca4060
1 parent
8b6449ce
去除zlm使用redis过期作为心跳超时的方式
Showing
5 changed files
with
118 additions
and
80 deletions
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) { | ... | ... |