完成向上级联->保活

This commit is contained in:
panlinlin
2021-01-06 18:35:38 +08:00
parent 34135cce5d
commit 627a14f37e
28 changed files with 736 additions and 67 deletions

View File

@@ -1,8 +1,7 @@
package com.genersoft.iot.vmp.gb28181.event;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire.PlatformKeepaliveExpireEvent;
import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformNotRegisterEvent;
import com.genersoft.iot.vmp.vmanager.platform.PlatformController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@@ -35,6 +34,16 @@ public class EventPublisher {
applicationEventPublisher.publishEvent(outEvent);
}
/**
* 平台心跳到期事件
* @param platformGbId
*/
public void platformKeepaliveExpireEventPublish(String platformGbId){
PlatformKeepaliveExpireEvent platformNotRegisterEvent = new PlatformKeepaliveExpireEvent(this);
platformNotRegisterEvent.setPlatformGbID(platformGbId);
applicationEventPublisher.publishEvent(platformNotRegisterEvent);
}
/**
* 平台未注册事件
* @param platformGbId

View File

@@ -0,0 +1,64 @@
package com.genersoft.iot.vmp.gb28181.event.offline;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import java.nio.charset.StandardCharsets;
/**
* @Description:设备心跳超时监听,借助redis过期特性进行监听监听到说明设备心跳超时发送离线事件
* @author: swwheihei
* @date: 2020年5月6日 上午11:35:46
*/
@Component
public class KeepaliveTimeoutListenerForPlatform extends KeyExpirationEventMessageListener {
@Autowired
private EventPublisher publisher;
public KeepaliveTimeoutListenerForPlatform(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
/**
* 监听失效的key
* @param message
* @param bytes
*/
@Override
public void onMessage(Message message, byte[] pattern) {
// 获取失效的key
String expiredKey = message.toString();
System.out.println(expiredKey);
if(!expiredKey.startsWith(VideoManagerConstants.PLATFORM_PREFIX)){
System.out.println("收到redis过期监听但开头不是"+VideoManagerConstants.PLATFORM_PREFIX+",忽略");
return;
}
// 平台心跳到期,需要重发, 判断是否已经多次未收到心跳回复, 多次未收到,则重新发起注册, 注册尝试多次未得到回复,则认为平台离线
if (expiredKey.startsWith(VideoManagerConstants.PLATFORM_KEEPLIVEKEY_PREFIX)) {
String platformGBId = expiredKey.substring(VideoManagerConstants.PLATFORM_KEEPLIVEKEY_PREFIX.length(),expiredKey.length());
publisher.platformKeepaliveExpireEventPublish(platformGBId);
}else if (expiredKey.startsWith(VideoManagerConstants.PLATFORM_REGISTER_PREFIX)) {
System.out.println("11111111111111");
String platformGBId = expiredKey.substring(VideoManagerConstants.PLATFORM_REGISTER_PREFIX.length(),expiredKey.length());
publisher.platformNotRegisterEventPublish(platformGBId);
}else{
String deviceId = expiredKey.substring(VideoManagerConstants.KEEPLIVEKEY_PREFIX.length(),expiredKey.length());
publisher.outlineEventPublish(deviceId, VideoManagerConstants.EVENT_OUTLINE_TIMEOUT);
}
}
}

View File

@@ -0,0 +1,23 @@
package com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire;
import org.springframework.context.ApplicationEvent;
/**
* 平台心跳超时事件
*/
public class PlatformKeepaliveExpireEvent extends ApplicationEvent {
private String platformGbID;
public PlatformKeepaliveExpireEvent(Object source) {
super(source);
}
public String getPlatformGbID() {
return platformGbID;
}
public void setPlatformGbID(String platformGbID) {
this.platformGbID = platformGbID;
}
}

View File

@@ -0,0 +1,85 @@
package com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
import com.genersoft.iot.vmp.gb28181.bean.PlatformRegister;
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import javax.sip.ResponseEvent;
import javax.sip.message.Response;
/**
* @Description: 平台心跳超时事件
* @author: panll
* @date: 2020年11月5日 10:00
*/
@Component
public class PlatformKeepaliveExpireEventLister implements ApplicationListener<PlatformKeepaliveExpireEvent> {
private final static Logger logger = LoggerFactory.getLogger(PlatformKeepaliveExpireEventLister.class);
@Autowired
private IVideoManagerStorager storager;
@Autowired
private IRedisCatchStorage redisCatchStorage;
@Autowired
private ISIPCommanderForPlatform sipCommanderForPlatform;
@Autowired
private SipSubscribe sipSubscribe;
@Autowired
private EventPublisher publisher;
@Override
public void onApplicationEvent(@NotNull PlatformKeepaliveExpireEvent event) {
if (logger.isDebugEnabled()) {
logger.debug("平台心跳到期事件事件触发平台国标ID" + event.getPlatformGbID());
}
ParentPlatform parentPlatform = storager.queryParentPlatById(event.getPlatformGbID());
ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(event.getPlatformGbID());
if (parentPlatform == null) {
logger.debug("平台心跳到期事件事件触发,但平台已经删除!!! 平台国标ID" + event.getPlatformGbID());
return;
}
if (parentPlatformCatch == null) {
return;
}
// 发送心跳
if (parentPlatformCatch.getKeepAliveReply() >= 3) {
// 有3次未收到心跳回复, 设置平台状态为离线, 开始重新注册
logger.warn("有3次未收到心跳回复,标记设置平台状态为离线, 并重新注册 平台国标ID" + event.getPlatformGbID());
publisher.platformNotRegisterEventPublish(event.getPlatformGbID());
}else {
// 再次发送心跳
String callId = sipCommanderForPlatform.keepalive(parentPlatform);
parentPlatformCatch.setKeepAliveReply( parentPlatformCatch.getKeepAliveReply() + 1);
// 存储心跳信息, 并设置状态为未回复, 如果多次过期仍未收到回复,则认为上级平台已经离线
redisCatchStorage.updatePlatformKeepalive(parentPlatform);
redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
sipSubscribe.addOkSubscribe(callId, (ResponseEvent responseEvent) ->{
if (responseEvent.getResponse().getStatusCode() == Response.OK) {
// 收到心跳响应信息,
parentPlatformCatch.setKeepAliveReply(0);
redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
}
} );
}
}
}

View File

@@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.gb28181.event.platformNotRegister;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent;
import com.genersoft.iot.vmp.gb28181.event.online.OnlineEventListener;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import org.slf4j.Logger;
@@ -26,6 +27,8 @@ public class PlatformNotRegisterEventLister implements ApplicationListener<Platf
@Autowired
private IVideoManagerStorager storager;
@Autowired
private SIPCommanderFroPlatform sipCommanderFroPlatform;
@Autowired
private RedisUtil redis;
@@ -33,13 +36,13 @@ public class PlatformNotRegisterEventLister implements ApplicationListener<Platf
@Override
public void onApplicationEvent(PlatformNotRegisterEvent event) {
if (logger.isDebugEnabled()) {
logger.debug("平台未注册事件触发平台国标ID" + event.getPlatformGbID());
}
logger.debug("平台未注册事件触发平台国标ID" + event.getPlatformGbID());
ParentPlatform parentPlatform = storager.queryParentPlatById(event.getPlatformGbID());
if (parentPlatform == null) {
logger.debug("平台未注册事件触发,但平台已经删除!!! 平台国标ID" + event.getPlatformGbID());
return;
}
sipCommanderFroPlatform.register(parentPlatform);
}
}