Browse Source

完成向上级联->保活

pull/29/head
panlinlin 4 years ago
parent
commit
627a14f37e
  1. 2
      README.md
  2. 10
      src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
  3. 92
      src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java
  4. 36
      src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java
  5. 15
      src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformRegister.java
  6. 13
      src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
  7. 64
      src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java
  8. 23
      src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEvent.java
  9. 85
      src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEventLister.java
  10. 9
      src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java
  11. 8
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
  12. 9
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
  13. 150
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
  14. 34
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
  15. 44
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
  16. 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
  17. 19
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java
  18. 12
      src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
  19. 38
      src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
  20. 3
      src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
  21. 2
      src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
  22. 54
      src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java
  23. 26
      src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
  24. 42
      src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
  25. 8
      src/main/java/com/genersoft/iot/vmp/vmanager/platform/PlatformController.java
  26. BIN
      src/main/resources/wvp.sqlite
  27. 2
      web_src/src/components/ParentPlatformList.vue
  28. 2
      web_src/src/router/index.js

2
README.md

@ -39,7 +39,7 @@ https://gitee.com/18010473990/wvp-GB28181.git
- [ ] 国标通道向上级联 - [ ] 国标通道向上级联
- [X] WEB添加上级平台 - [X] WEB添加上级平台
- [X] 注册 - [X] 注册
- [ ] 心跳保活 - [X] 心跳保活
- [ ] 通道选择 - [ ] 通道选择
- [ ] 通道推送 - [ ] 通道推送
- [ ] 点播 - [ ] 点播

10
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java

@ -20,7 +20,15 @@ public class VideoManagerConstants {
public static final String PLAY_BLACK_PREFIX = "VMP_playback_"; public static final String PLAY_BLACK_PREFIX = "VMP_playback_";
public static final String PLATFORM_PREFIX = "VMP_platform_"; public static final String PLATFORM_PREFIX = "VMP_platform";
public static final String PLATFORM_KEEPLIVEKEY_PREFIX = "VMP_platform_keeplive_";
public static final String PLATFORM_CATCH_PREFIX = "VMP_platform_catch_";
public static final String PLATFORM_REGISTER_PREFIX = "VMP_platform_register_";
public static final String Pattern_Topic = "VMP_keeplive_platform_";
public static final String EVENT_ONLINE_REGISTER = "1"; public static final String EVENT_ONLINE_REGISTER = "1";

92
src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java

@ -1,28 +1,28 @@
/* /*
* Conditions Of Use * Conditions Of Use
* *
* This software was developed by employees of the National Institute of * This software was developed by employees of the National Institute of
* Standards and Technology (NIST), an agency of the Federal Government. * Standards and Technology (NIST), an agency of the Federal Government.
* Pursuant to title 15 Untied States Code Section 105, works of NIST * Pursuant to title 15 Untied States Code Section 105, works of NIST
* employees are not subject to copyright protection in the United States * employees are not subject to copyright protection in the United States
* and are considered to be in the public domain. As a result, a formal * and are considered to be in the public domain. As a result, a formal
* license is not needed to use the software. * license is not needed to use the software.
* *
* This software is provided by NIST as a service and is expressly * This software is provided by NIST as a service and is expressly
* provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED * provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
* AND DATA ACCURACY. NIST does not warrant or make any representations * AND DATA ACCURACY. NIST does not warrant or make any representations
* regarding the use of the software or the results thereof, including but * regarding the use of the software or the results thereof, including but
* not limited to the correctness, accuracy, reliability or usefulness of * not limited to the correctness, accuracy, reliability or usefulness of
* the software. * the software.
* *
* Permission to use this software is contingent upon your acceptance * Permission to use this software is contingent upon your acceptance
* of the terms of this agreement * of the terms of this agreement
* *
* . * .
* *
*/ */
package com.genersoft.iot.vmp.gb28181.auth; package com.genersoft.iot.vmp.gb28181.auth;
import java.security.MessageDigest; import java.security.MessageDigest;
@ -42,18 +42,18 @@ import gov.nist.core.InternalErrorHandler;
/** /**
* Implements the HTTP digest authentication method server side functionality. * Implements the HTTP digest authentication method server side functionality.
* *
* @author M. Ranganathan * @author M. Ranganathan
* @author Marc Bednarek * @author Marc Bednarek
*/ */
public class DigestServerAuthenticationHelper { public class DigestServerAuthenticationHelper {
private MessageDigest messageDigest; private MessageDigest messageDigest;
public static final String DEFAULT_ALGORITHM = "MD5"; public static final String DEFAULT_ALGORITHM = "MD5";
public static final String DEFAULT_SCHEME = "Digest"; public static final String DEFAULT_SCHEME = "Digest";
@ -63,11 +63,11 @@ public class DigestServerAuthenticationHelper {
/** /**
* Default constructor. * Default constructor.
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
*/ */
public DigestServerAuthenticationHelper() public DigestServerAuthenticationHelper()
throws NoSuchAlgorithmException { throws NoSuchAlgorithmException {
messageDigest = MessageDigest.getInstance(DEFAULT_ALGORITHM); messageDigest = MessageDigest.getInstance(DEFAULT_ALGORITHM);
} }
public static String toHexString(byte b[]) { public static String toHexString(byte b[]) {
@ -79,7 +79,7 @@ public class DigestServerAuthenticationHelper {
} }
return new String(c); return new String(c);
} }
/** /**
* Generate the challenge string. * Generate the challenge string.
* *
@ -121,34 +121,34 @@ public class DigestServerAuthenticationHelper {
* *
* @param request - the request to authenticate. * @param request - the request to authenticate.
* @param hashedPassword -- the MD5 hashed string of username:realm:plaintext password. * @param hashedPassword -- the MD5 hashed string of username:realm:plaintext password.
* *
* @return true if authentication succeded and false otherwise. * @return true if authentication succeded and false otherwise.
*/ */
public boolean doAuthenticateHashedPassword(Request request, String hashedPassword) { public boolean doAuthenticateHashedPassword(Request request, String hashedPassword) {
AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME);
if ( authHeader == null ) return false; if ( authHeader == null ) return false;
String realm = authHeader.getRealm(); String realm = authHeader.getRealm();
String username = authHeader.getUsername(); String username = authHeader.getUsername();
if ( username == null || realm == null ) { if ( username == null || realm == null ) {
return false; return false;
} }
String nonce = authHeader.getNonce(); String nonce = authHeader.getNonce();
URI uri = authHeader.getURI(); URI uri = authHeader.getURI();
if (uri == null) { if (uri == null) {
return false; return false;
} }
String A2 = request.getMethod().toUpperCase() + ":" + uri.toString(); String A2 = request.getMethod().toUpperCase() + ":" + uri.toString();
String HA1 = hashedPassword; String HA1 = hashedPassword;
byte[] mdbytes = messageDigest.digest(A2.getBytes()); byte[] mdbytes = messageDigest.digest(A2.getBytes());
String HA2 = toHexString(mdbytes); String HA2 = toHexString(mdbytes);
String cnonce = authHeader.getCNonce(); String cnonce = authHeader.getCNonce();
String KD = HA1 + ":" + nonce; String KD = HA1 + ":" + nonce;
if (cnonce != null) { if (cnonce != null) {
@ -158,7 +158,7 @@ public class DigestServerAuthenticationHelper {
mdbytes = messageDigest.digest(KD.getBytes()); mdbytes = messageDigest.digest(KD.getBytes());
String mdString = toHexString(mdbytes); String mdString = toHexString(mdbytes);
String response = authHeader.getResponse(); String response = authHeader.getResponse();
return mdString.equals(response); return mdString.equals(response);
} }
@ -168,11 +168,11 @@ public class DigestServerAuthenticationHelper {
* *
* @param request - the request to authenticate. * @param request - the request to authenticate.
* @param pass -- the plain text password. * @param pass -- the plain text password.
* *
* @return true if authentication succeded and false otherwise. * @return true if authentication succeded and false otherwise.
*/ */
public boolean doAuthenticatePlainTextPassword(Request request, String pass) { public boolean doAuthenticatePlainTextPassword(Request request, String pass) {
AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME);
if ( authHeader == null ) return false; if ( authHeader == null ) return false;
String realm = authHeader.getRealm().trim(); String realm = authHeader.getRealm().trim();
String username = authHeader.getUsername().trim(); String username = authHeader.getUsername().trim();
@ -184,7 +184,7 @@ public class DigestServerAuthenticationHelper {
String nonce = authHeader.getNonce(); String nonce = authHeader.getNonce();
URI uri = authHeader.getURI(); URI uri = authHeader.getURI();
if (uri == null) { if (uri == null) {
return false; return false;
} }
// qop 保护质量 包含auth(默认的)和auth-int(增加了报文完整性检测)两种策略 // qop 保护质量 包含auth(默认的)和auth-int(增加了报文完整性检测)两种策略
String qop = authHeader.getQop(); String qop = authHeader.getQop();
@ -233,7 +233,7 @@ public class DigestServerAuthenticationHelper {
String response = authHeader.getResponse(); String response = authHeader.getResponse();
System.out.println("response: " + response); System.out.println("response: " + response);
return mdString.equals(response); return mdString.equals(response);
} }

36
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java

@ -0,0 +1,36 @@
package com.genersoft.iot.vmp.gb28181.bean;
public class ParentPlatformCatch {
private String id;
// 心跳未回复次数
private int keepAliveReply;
// 注册未回复次数
private int registerAliveReply;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getKeepAliveReply() {
return keepAliveReply;
}
public void setKeepAliveReply(int keepAliveReply) {
this.keepAliveReply = keepAliveReply;
}
public int getRegisterAliveReply() {
return registerAliveReply;
}
public void setRegisterAliveReply(int registerAliveReply) {
this.registerAliveReply = registerAliveReply;
}
}

15
src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformRegister.java

@ -0,0 +1,15 @@
package com.genersoft.iot.vmp.gb28181.bean;
public class PlatformRegister {
// 未回复次数
private int reply;
public int getReply() {
return reply;
}
public void setReply(int reply) {
this.reply = reply;
}
}

13
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java

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

64
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java

@ -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);
}
}
}

23
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEvent.java

@ -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;
}
}

85
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEventLister.java

@ -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);
}
} );
}
}
}

9
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java

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

8
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java

@ -4,6 +4,8 @@ import javax.sip.RequestEvent;
import javax.sip.ResponseEvent; import javax.sip.ResponseEvent;
import javax.sip.SipProvider; import javax.sip.SipProvider;
import javax.sip.header.CSeqHeader; import javax.sip.header.CSeqHeader;
import javax.sip.header.CallIdHeader;
import javax.sip.header.Header;
import javax.sip.message.Request; import javax.sip.message.Request;
import javax.sip.message.Response; import javax.sip.message.Response;
@ -11,6 +13,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*;
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -34,6 +37,10 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.impl.OtherRequestProcessor
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.SubscribeRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.request.impl.SubscribeRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.ByeResponseProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.CancelResponseProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.InviteResponseProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.OtherResponseProcessor;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.utils.SpringBeanFactory; import com.genersoft.iot.vmp.utils.SpringBeanFactory;
import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.utils.redis.RedisUtil;
@ -88,6 +95,7 @@ public class SIPProcessorFactory {
@Lazy @Lazy
private RegisterResponseProcessor registerResponseProcessor; private RegisterResponseProcessor registerResponseProcessor;
@Autowired @Autowired
private OtherResponseProcessor otherResponseProcessor; private OtherResponseProcessor otherResponseProcessor;

9
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java

@ -9,5 +9,14 @@ public interface ISIPCommanderForPlatform {
* @param parentPlatform * @param parentPlatform
* @return * @return
*/ */
boolean register(ParentPlatform parentPlatform);
boolean register(ParentPlatform parentPlatform, String callId, String realm, String nonce, String scheme); boolean register(ParentPlatform parentPlatform, String callId, String realm, String nonce, String scheme);
/**
* 向上级平发送心跳信息
* @param parentPlatform
* @return callId(作为接受回复的判定)
*/
String keepalive(ParentPlatform parentPlatform);
} }

150
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java

@ -0,0 +1,150 @@
package com.genersoft.iot.vmp.gb28181.transmit.cmd;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.Host;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import javax.sip.InvalidArgumentException;
import javax.sip.PeerUnavailableException;
import javax.sip.SipFactory;
import javax.sip.SipProvider;
import javax.sip.address.Address;
import javax.sip.address.SipURI;
import javax.sip.header.*;
import javax.sip.message.Request;
import javax.validation.constraints.NotNull;
import java.text.ParseException;
import java.util.ArrayList;
/**
* @Description:摄像头命令request创造器 TODO 冗余代码太多待优化
* @author: swwheihei
* @date: 2020年5月6日 上午9:29:02
*/
@Component
public class SIPRequestHeaderPlarformProvider {
@Autowired
private SipConfig sipConfig;
@Autowired
private SipFactory sipFactory;
@Autowired
@Qualifier(value="tcpSipProvider")
private SipProvider tcpSipProvider;
@Autowired
@Qualifier(value="udpSipProvider")
private SipProvider udpSipProvider;
public Request createKeetpaliveMessageRequest(ParentPlatform parentPlatform, String content, String viaTag, String fromTag, String toTag) throws ParseException, InvalidArgumentException, PeerUnavailableException {
Request request = null;
// sipuri
SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());
// via
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(),
parentPlatform.getTransport(), viaTag);
viaHeader.setRPort();
viaHeaders.add(viaHeader);
// from
SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(),
sipConfig.getSipIp() + ":" + sipConfig.getSipPort());
Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag);
// to
SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort() );
Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag);
// callid
CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
: udpSipProvider.getNewCallId();
// Forwards
MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
// ceq
CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(1L, Request.MESSAGE);
request = sipFactory.createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
toHeader, viaHeaders, maxForwards);
ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
request.setContent(content, contentTypeHeader);
return request;
}
public Request createRegisterRequest(@NotNull ParentPlatform platform, String fromTag, String viaTag) throws ParseException, InvalidArgumentException, PeerUnavailableException {
Request request = null;
String sipAddress = sipConfig.getSipIp() + ":" + sipConfig.getSipPort();
//请求行
SipURI requestLine = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(),
platform.getServerIP() + ":" + platform.getServerPort());
//via
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(platform.getServerIP(), platform.getServerPort(), platform.getTransport(), viaTag);
viaHeader.setRPort();
viaHeaders.add(viaHeader);
//from
SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(),sipAddress);
Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag);
//to
SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(),sipAddress);
Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress,null);
//callid
CallIdHeader callIdHeader = null;
if(platform.getTransport().equals("TCP")) {
callIdHeader = tcpSipProvider.getNewCallId();
}
if(platform.getTransport().equals("UDP")) {
callIdHeader = udpSipProvider.getNewCallId();
}
//Forwards
MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
//ceq
CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(1L, Request.REGISTER);
request = sipFactory.createMessageFactory().createRequest(requestLine, Request.REGISTER, callIdHeader,
cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory()
.createSipURI(platform.getDeviceGBId(), sipAddress));
request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
return request;
}
public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, String fromTag, String viaTag,
String callId, String realm, String nonce, String scheme) throws ParseException, PeerUnavailableException, InvalidArgumentException {
Request registerRequest = createRegisterRequest(parentPlatform, fromTag, viaTag);
CallIdHeader callIdHeader = (CallIdHeader)registerRequest.getHeader(CallIdHeader.NAME);
callIdHeader.setCallId(callId);
String uri = "sip:" + parentPlatform.getServerGBId() +
"@" + parentPlatform.getServerIP() +
":" + parentPlatform.getServerPort();
String HA1 = DigestUtils.md5DigestAsHex((parentPlatform.getDeviceGBId() + ":" + realm + ":" + parentPlatform.getPassword()).getBytes());
String HA2=DigestUtils.md5DigestAsHex((Request.REGISTER + ":" + uri).getBytes());
String RESPONSE = DigestUtils.md5DigestAsHex((HA1 + ":" + nonce + ":" + HA2).getBytes());
String authorizationHeaderContent = scheme + " username=\"" + parentPlatform.getDeviceGBId() + "\", " + "realm=\""
+ realm + "\", uri=\"" + uri + "\", response=\"" + RESPONSE + "\", nonce=\""
+ nonce + "\"";
AuthorizationHeader authorizationHeader = sipFactory.createHeaderFactory().createAuthorizationHeader(authorizationHeaderContent);
registerRequest.addHeader(authorizationHeader);
return registerRequest;
}
}

34
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java

@ -238,4 +238,38 @@ public class SIPRequestHeaderProvider {
return registerRequest; return registerRequest;
} }
// public Request createKeetpaliveMessageRequest(ParentPlatform parentPlatform, String content, String fromTag, String toTag, Object o) throws PeerUnavailableException, ParseException, InvalidArgumentException {
// Request request = null;
// // sipuri
// SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());
// // via
// ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
// ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(),
// parentPlatform.getTransport(), null);
// viaHeader.setRPort();
// viaHeaders.add(viaHeader);
// // from
// SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(),
// sipConfig.getSipIp() + ":" + sipConfig.getSipPort());
// Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
// FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag);
// // to
// SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerGBDomain());
// Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
// ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag);
// // callid
// CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
// : udpSipProvider.getNewCallId();
// // Forwards
// MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
// // ceq
// CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(1L, Request.MESSAGE);
//
// request = sipFactory.createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
// toHeader, viaHeaders, maxForwards);
// ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "MANSCDP+xml");
// request.setContent(content, contentTypeHeader);
// return request;
// }
} }

44
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java

@ -5,8 +5,8 @@ import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
import com.genersoft.iot.vmp.media.zlm.ZLMUtils;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
@ -15,8 +15,10 @@ import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.sip.*; import javax.sip.*;
import javax.sip.header.CallIdHeader;
import javax.sip.message.Request; import javax.sip.message.Request;
import java.text.ParseException; import java.text.ParseException;
import java.util.UUID;
@Component @Component
public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
@ -27,6 +29,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
@Autowired @Autowired
private SIPRequestHeaderProvider headerProvider; private SIPRequestHeaderProvider headerProvider;
@Autowired
private SIPRequestHeaderPlarformProvider headerProviderPlarformProvider;
@Autowired @Autowired
private VideoStreamSessionManager streamSession; private VideoStreamSessionManager streamSession;
@ -41,12 +46,14 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
@Qualifier(value="udpSipProvider") @Qualifier(value="udpSipProvider")
private SipProvider udpSipProvider; private SipProvider udpSipProvider;
@Autowired
private ZLMUtils zlmUtils;
@Value("${media.rtp.enable}") @Value("${media.rtp.enable}")
private boolean rtpEnable; private boolean rtpEnable;
@Override
public boolean register(ParentPlatform parentPlatform) {
return register(parentPlatform, null, null, null, null);
}
@Override @Override
public boolean register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable String realm, @Nullable String nonce, @Nullable String scheme ) { public boolean register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable String realm, @Nullable String nonce, @Nullable String scheme ) {
try { try {
@ -71,6 +78,35 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
return false; return false;
} }
@Override
public String keepalive(ParentPlatform parentPlatform) {
String callId = null;
try {
StringBuffer keepaliveXml = new StringBuffer(200);
keepaliveXml.append("<?xml version=\"1.0\" encoding=\"GB2312\" ?>\r\n");
keepaliveXml.append("<Notify>\r\n");
keepaliveXml.append("<CmdType>Keepalive</CmdType>\r\n");
keepaliveXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
keepaliveXml.append("<DeviceID>" + parentPlatform.getServerGBId() + "</DeviceID>\r\n");
keepaliveXml.append("<Status>OK</Status>\r\n");
keepaliveXml.append("</Notify>\r\n");
Request request = headerProviderPlarformProvider.createKeetpaliveMessageRequest(
parentPlatform,
keepaliveXml.toString(),
UUID.randomUUID().toString().replace("-", ""),
UUID.randomUUID().toString().replace("-", ""),
null);
transmitRequest(parentPlatform, request);
CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME);
callId = callIdHeader.getCallId();
} catch (ParseException | InvalidArgumentException | SipException e) {
e.printStackTrace();
}
return callId;
}
private void transmitRequest(ParentPlatform parentPlatform, Request request) throws SipException { private void transmitRequest(ParentPlatform parentPlatform, Request request) throws SipException {
if("TCP".equals(parentPlatform.getTransport())) { if("TCP".equals(parentPlatform.getTransport())) {
tcpSipProvider.sendRequest(request); tcpSipProvider.sendRequest(request);

1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java

@ -460,6 +460,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
cmder.streamByeCmd(streamInfo.getStreamId()); cmder.streamByeCmd(streamInfo.getStreamId());
} }
} }
} catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
e.printStackTrace(); e.printStackTrace();
} }

19
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java

@ -3,9 +3,11 @@ package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.SipLayer; import com.genersoft.iot.vmp.gb28181.SipLayer;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import gov.nist.core.Host; import gov.nist.core.Host;
import gov.nist.javax.sip.address.AddressImpl; import gov.nist.javax.sip.address.AddressImpl;
@ -40,6 +42,12 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor {
@Autowired @Autowired
private IVideoManagerStorager storager; private IVideoManagerStorager storager;
@Autowired
private IRedisCatchStorage redisCatchStorage;
public RegisterResponseProcessor() {
}
/** /**
* 处理Register响应 * 处理Register响应
* *
@ -77,6 +85,17 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor {
logger.info(String.format("%s 注册成功", platformGBId )); logger.info(String.format("%s 注册成功", platformGBId ));
parentPlatform.setStatus(true); parentPlatform.setStatus(true);
storager.updateParentPlatform(parentPlatform); storager.updateParentPlatform(parentPlatform);
//
redisCatchStorage.updatePlatformRegister(parentPlatform);
redisCatchStorage.updatePlatformKeepalive(parentPlatform);
ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getDeviceGBId());
if (parentPlatformCatch == null) {
parentPlatformCatch = new ParentPlatformCatch();
parentPlatformCatch.setId(parentPlatform.getDeviceGBId());
}
redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
} }
} }

12
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java

@ -2,6 +2,9 @@ package com.genersoft.iot.vmp.storager;
import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.MediaServerConfig; import com.genersoft.iot.vmp.conf.MediaServerConfig;
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 java.util.Map; import java.util.Map;
@ -55,4 +58,13 @@ public interface IRedisCatchStorage {
boolean stopPlayback(StreamInfo streamInfo); boolean stopPlayback(StreamInfo streamInfo);
StreamInfo queryPlaybackByDevice(String deviceId, String code); StreamInfo queryPlaybackByDevice(String deviceId, String code);
void updatePlatformCatchInfo(ParentPlatformCatch parentPlatformCatch);
ParentPlatformCatch queryPlatformCatchInfo(String platformGbId);
void updatePlatformKeepalive(ParentPlatform parentPlatform);
void updatePlatformRegister(ParentPlatform parentPlatform);
} }

38
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java

@ -1,9 +1,12 @@
package com.genersoft.iot.vmp.storager; package com.genersoft.iot.vmp.storager;
import java.util.List; import java.util.List;
import java.util.Map;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
/** /**
@ -136,4 +139,39 @@ public interface IVideoManagerStorager {
*/ */
void cleanChannelsForDevice(String deviceId); void cleanChannelsForDevice(String deviceId);
/**
* 更新上级平台
* @param parentPlatform
*/
boolean updateParentPlatform(ParentPlatform parentPlatform);
/**
* 添加上级平台
* @param parentPlatform
*/
boolean addParentPlatform(ParentPlatform parentPlatform);
/**
* 删除上级平台
* @param parentPlatform
*/
boolean deleteParentPlatform(ParentPlatform parentPlatform);
/**
* 分页获取上级平台
* @param page
* @param count
* @return
*/
PageInfo<ParentPlatform> queryParentPlatformList(int page, int count);
/**
* 获取上级平台
* @param platformGbId
* @return
*/
ParentPlatform queryParentPlatById(String platformGbId);
} }

3
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java

@ -1,6 +1,7 @@
package com.genersoft.iot.vmp.storager.dao; package com.genersoft.iot.vmp.storager.dao;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import org.apache.ibatis.annotations.*; import org.apache.ibatis.annotations.*;
import java.util.List; import java.util.List;
@ -48,4 +49,6 @@ public interface DeviceChannelMapper {
@Delete("DELETE FROM device_channel WHERE deviceId=#{deviceId}") @Delete("DELETE FROM device_channel WHERE deviceId=#{deviceId}")
int cleanChannelsByDeviceId(String deviceId); int cleanChannelsByDeviceId(String deviceId);
} }

2
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java

@ -1,6 +1,7 @@
package com.genersoft.iot.vmp.storager.dao; package com.genersoft.iot.vmp.storager.dao;
import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import org.apache.ibatis.annotations.*; import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@ -63,4 +64,5 @@ public interface DeviceMapper {
@Delete("DELETE FROM device WHERE deviceId=#{deviceId}") @Delete("DELETE FROM device WHERE deviceId=#{deviceId}")
int del(String deviceId); int del(String deviceId);
} }

54
src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java

@ -0,0 +1,54 @@
package com.genersoft.iot.vmp.storager.dao;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 用于存储上级平台
*/
@Mapper
@Repository
public interface ParentPlatformMapper {
@Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " +
" devicePort, username, password, expires, keepTimeout, transport, characterSet, PTZEnable, rtcp, " +
" status) " +
" VALUES (${enable}, '${name}', '${serverGBId}', '${serverGBDomain}', '${serverIP}', ${serverPort}, '${deviceGBId}', '${deviceIp}', " +
" '${devicePort}', '${username}', '${password}', '${expires}', '${keepTimeout}', '${transport}', '${characterSet}', ${PTZEnable}, ${rtcp}, " +
" ${status})")
int addParentPlatform(ParentPlatform parentPlatform);
@Update("UPDATE parent_platform " +
"SET enable=#{enable}, " +
"name=#{name}," +
"serverGBId=#{serverGBId}," +
"serverGBDomain=#{serverGBDomain}, " +
"serverIP=#{serverIP}," +
"serverPort=#{serverPort}, " +
"deviceIp=#{deviceIp}, " +
"devicePort=#{devicePort}, " +
"username=#{username}, " +
"password=#{password}, " +
"expires=#{expires}, " +
"keepTimeout=#{keepTimeout}, " +
"transport=#{transport}, " +
"characterSet=#{characterSet}, " +
"PTZEnable=#{PTZEnable}, " +
"rtcp=#{rtcp}, " +
"status=#{status} " +
"WHERE deviceGBId=#{deviceGBId}")
int updateParentPlatform(ParentPlatform parentPlatform);
@Delete("DELETE FROM parent_platform WHERE deviceGBId=#{deviceGBId}")
int delParentPlatform(ParentPlatform parentPlatform);
@Select("SELECT * FROM parent_platform")
List<ParentPlatform> getParentPlatformList();
@Select("SELECT * FROM parent_platform WHERE deviceGBId=#{platformGbId}")
ParentPlatform getParentPlatById(String platformGbId);
}

26
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java

@ -4,6 +4,9 @@ import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.conf.MediaServerConfig; import com.genersoft.iot.vmp.conf.MediaServerConfig;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
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.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.utils.redis.RedisUtil;
@ -163,4 +166,27 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
if (playLeys == null || playLeys.size() == 0) return null; if (playLeys == null || playLeys.size() == 0) return null;
return (StreamInfo)redis.get(playLeys.get(0).toString()); return (StreamInfo)redis.get(playLeys.get(0).toString());
} }
@Override
public void updatePlatformCatchInfo(ParentPlatformCatch parentPlatformCatch) {
String key = VideoManagerConstants.PLATFORM_CATCH_PREFIX + parentPlatformCatch.getId();
redis.set(key, parentPlatformCatch);
}
@Override
public void updatePlatformKeepalive(ParentPlatform parentPlatform) {
String key = VideoManagerConstants.PLATFORM_KEEPLIVEKEY_PREFIX + parentPlatform.getDeviceGBId();
redis.set(key, "", Integer.parseInt(parentPlatform.getKeepTimeout()));
}
@Override
public void updatePlatformRegister(ParentPlatform parentPlatform) {
String key = VideoManagerConstants.PLATFORM_REGISTER_PREFIX + parentPlatform.getDeviceGBId();
redis.set(key, "", Integer.parseInt(parentPlatform.getExpires()));
}
@Override
public ParentPlatformCatch queryPlatformCatchInfo(String platformGbId) {
return (ParentPlatformCatch)redis.get(VideoManagerConstants.PLATFORM_CATCH_PREFIX + platformGbId);
}
} }

42
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java

@ -3,17 +3,17 @@ package com.genersoft.iot.vmp.storager.impl;
import java.util.*; import java.util.*;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
import com.genersoft.iot.vmp.storager.dao.DeviceMapper; import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import org.springframework.util.StringUtils;
/** /**
* @Description:视频设备数据存储-jdbc实现 * @Description:视频设备数据存储-jdbc实现
@ -29,6 +29,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
@Autowired @Autowired
private DeviceChannelMapper deviceChannelMapper; private DeviceChannelMapper deviceChannelMapper;
@Autowired
private ParentPlatformMapper platformMapper;
/** /**
* 根据设备ID判断设备是否存在 * 根据设备ID判断设备是否存在
@ -198,5 +201,40 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
int result = deviceChannelMapper.cleanChannelsByDeviceId(deviceId); int result = deviceChannelMapper.cleanChannelsByDeviceId(deviceId);
} }
@Override
public boolean addParentPlatform(ParentPlatform parentPlatform) {
int result = platformMapper.addParentPlatform(parentPlatform);
return result > 0;
}
@Override
public boolean updateParentPlatform(ParentPlatform parentPlatform) {
int result = 0;
if ( platformMapper.getParentPlatById(parentPlatform.getDeviceGBId()) == null) {
result = platformMapper.addParentPlatform(parentPlatform);
}else {
result = platformMapper.updateParentPlatform(parentPlatform);
}
return result > 0;
}
@Override
public boolean deleteParentPlatform(ParentPlatform parentPlatform) {
int result = platformMapper.delParentPlatform(parentPlatform);
return result > 0;
}
@Override
public PageInfo<ParentPlatform> queryParentPlatformList(int page, int count) {
PageHelper.startPage(page, count);
List<ParentPlatform> all = platformMapper.getParentPlatformList();
return new PageInfo<>(all);
}
@Override
public ParentPlatform queryParentPlatById(String platformGbId) {
return platformMapper.getParentPlatById(platformGbId);
}
} }

8
src/main/java/com/genersoft/iot/vmp/vmanager/platform/PlatformController.java

@ -1,19 +1,15 @@
package com.genersoft.iot.vmp.vmanager.platform; package com.genersoft.iot.vmp.vmanager.platform;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.common.PageResult;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.vmanager.device.DeviceController; import com.github.pagehelper.PageInfo;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.conf.SipConfig;
@ -46,7 +42,7 @@ public class PlatformController {
} }
@GetMapping("/platforms/{count}/{page}") @GetMapping("/platforms/{count}/{page}")
public PageResult<ParentPlatform> platforms(@PathVariable int page, @PathVariable int count){ public PageInfo<ParentPlatform> platforms(@PathVariable int page, @PathVariable int count){
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("查询所有上级设备API调用"); logger.debug("查询所有上级设备API调用");

BIN
src/main/resources/wvp.sqlite

Binary file not shown.

2
web_src/src/components/ParentPlatformList.vue

@ -152,7 +152,7 @@ export default {
this.$axios.get(`/api/platforms/${that.count}/${that.currentPage - 1}`) this.$axios.get(`/api/platforms/${that.count}/${that.currentPage - 1}`)
.then(function (res) { .then(function (res) {
that.total = res.data.total; that.total = res.data.total;
that.platformList = res.data.data; that.platformList = res.data.list;
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);

2
web_src/src/router/index.js

@ -35,7 +35,7 @@ export default new VueRouter({
path: '/channelList/:deviceId/:parentChannelId/:count/:page', path: '/channelList/:deviceId/:parentChannelId/:count/:page',
name: 'channelList', name: 'channelList',
component: channelList, component: channelList,
}, },,
{ {
path: '/parentPlatformList/:count/:page', path: '/parentPlatformList/:count/:page',
name: 'parentPlatformList', name: 'parentPlatformList',

Loading…
Cancel
Save