Commit 627a14f37e49d5e33cc5f593277ee24f913875b8
1 parent
34135cce
完成向上级联->保活
Showing
28 changed files
with
736 additions
and
67 deletions
README.md
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
| ... | ... | @@ -20,7 +20,15 @@ public class VideoManagerConstants { |
| 20 | 20 | |
| 21 | 21 | public static final String PLAY_BLACK_PREFIX = "VMP_playback_"; |
| 22 | 22 | |
| 23 | - public static final String PLATFORM_PREFIX = "VMP_platform_"; | |
| 23 | + public static final String PLATFORM_PREFIX = "VMP_platform"; | |
| 24 | + | |
| 25 | + public static final String PLATFORM_KEEPLIVEKEY_PREFIX = "VMP_platform_keeplive_"; | |
| 26 | + | |
| 27 | + public static final String PLATFORM_CATCH_PREFIX = "VMP_platform_catch_"; | |
| 28 | + | |
| 29 | + public static final String PLATFORM_REGISTER_PREFIX = "VMP_platform_register_"; | |
| 30 | + | |
| 31 | + public static final String Pattern_Topic = "VMP_keeplive_platform_"; | |
| 24 | 32 | |
| 25 | 33 | public static final String EVENT_ONLINE_REGISTER = "1"; |
| 26 | 34 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java
| 1 | 1 | /* |
| 2 | -* Conditions Of Use | |
| 3 | -* | |
| 4 | -* This software was developed by employees of the National Institute of | |
| 5 | -* Standards and Technology (NIST), an agency of the Federal Government. | |
| 6 | -* Pursuant to title 15 Untied States Code Section 105, works of NIST | |
| 7 | -* employees are not subject to copyright protection in the United States | |
| 8 | -* and are considered to be in the public domain. As a result, a formal | |
| 9 | -* license is not needed to use the software. | |
| 10 | -* | |
| 11 | -* This software is provided by NIST as a service and is expressly | |
| 12 | -* provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED | |
| 13 | -* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF | |
| 14 | -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT | |
| 15 | -* AND DATA ACCURACY. NIST does not warrant or make any representations | |
| 16 | -* regarding the use of the software or the results thereof, including but | |
| 17 | -* not limited to the correctness, accuracy, reliability or usefulness of | |
| 18 | -* the software. | |
| 19 | -* | |
| 20 | -* Permission to use this software is contingent upon your acceptance | |
| 21 | -* of the terms of this agreement | |
| 22 | -* | |
| 23 | -* . | |
| 24 | -* | |
| 25 | -*/ | |
| 2 | + * Conditions Of Use | |
| 3 | + * | |
| 4 | + * This software was developed by employees of the National Institute of | |
| 5 | + * Standards and Technology (NIST), an agency of the Federal Government. | |
| 6 | + * Pursuant to title 15 Untied States Code Section 105, works of NIST | |
| 7 | + * employees are not subject to copyright protection in the United States | |
| 8 | + * and are considered to be in the public domain. As a result, a formal | |
| 9 | + * license is not needed to use the software. | |
| 10 | + * | |
| 11 | + * This software is provided by NIST as a service and is expressly | |
| 12 | + * provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED | |
| 13 | + * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF | |
| 14 | + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT | |
| 15 | + * AND DATA ACCURACY. NIST does not warrant or make any representations | |
| 16 | + * regarding the use of the software or the results thereof, including but | |
| 17 | + * not limited to the correctness, accuracy, reliability or usefulness of | |
| 18 | + * the software. | |
| 19 | + * | |
| 20 | + * Permission to use this software is contingent upon your acceptance | |
| 21 | + * of the terms of this agreement | |
| 22 | + * | |
| 23 | + * . | |
| 24 | + * | |
| 25 | + */ | |
| 26 | 26 | package com.genersoft.iot.vmp.gb28181.auth; |
| 27 | 27 | |
| 28 | 28 | import java.security.MessageDigest; |
| ... | ... | @@ -42,18 +42,18 @@ import gov.nist.core.InternalErrorHandler; |
| 42 | 42 | |
| 43 | 43 | /** |
| 44 | 44 | * Implements the HTTP digest authentication method server side functionality. |
| 45 | - * | |
| 45 | + * | |
| 46 | 46 | * @author M. Ranganathan |
| 47 | 47 | * @author Marc Bednarek |
| 48 | 48 | */ |
| 49 | 49 | |
| 50 | 50 | public class DigestServerAuthenticationHelper { |
| 51 | - | |
| 51 | + | |
| 52 | 52 | private MessageDigest messageDigest; |
| 53 | - | |
| 53 | + | |
| 54 | 54 | public static final String DEFAULT_ALGORITHM = "MD5"; |
| 55 | 55 | public static final String DEFAULT_SCHEME = "Digest"; |
| 56 | - | |
| 56 | + | |
| 57 | 57 | |
| 58 | 58 | |
| 59 | 59 | |
| ... | ... | @@ -63,11 +63,11 @@ public class DigestServerAuthenticationHelper { |
| 63 | 63 | |
| 64 | 64 | /** |
| 65 | 65 | * Default constructor. |
| 66 | - * @throws NoSuchAlgorithmException | |
| 66 | + * @throws NoSuchAlgorithmException | |
| 67 | 67 | */ |
| 68 | - public DigestServerAuthenticationHelper() | |
| 69 | - throws NoSuchAlgorithmException { | |
| 70 | - messageDigest = MessageDigest.getInstance(DEFAULT_ALGORITHM); | |
| 68 | + public DigestServerAuthenticationHelper() | |
| 69 | + throws NoSuchAlgorithmException { | |
| 70 | + messageDigest = MessageDigest.getInstance(DEFAULT_ALGORITHM); | |
| 71 | 71 | } |
| 72 | 72 | |
| 73 | 73 | public static String toHexString(byte b[]) { |
| ... | ... | @@ -79,7 +79,7 @@ public class DigestServerAuthenticationHelper { |
| 79 | 79 | } |
| 80 | 80 | return new String(c); |
| 81 | 81 | } |
| 82 | - | |
| 82 | + | |
| 83 | 83 | /** |
| 84 | 84 | * Generate the challenge string. |
| 85 | 85 | * |
| ... | ... | @@ -121,34 +121,34 @@ public class DigestServerAuthenticationHelper { |
| 121 | 121 | * |
| 122 | 122 | * @param request - the request to authenticate. |
| 123 | 123 | * @param hashedPassword -- the MD5 hashed string of username:realm:plaintext password. |
| 124 | - * | |
| 124 | + * | |
| 125 | 125 | * @return true if authentication succeded and false otherwise. |
| 126 | 126 | */ |
| 127 | 127 | public boolean doAuthenticateHashedPassword(Request request, String hashedPassword) { |
| 128 | - AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); | |
| 128 | + AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); | |
| 129 | 129 | if ( authHeader == null ) return false; |
| 130 | 130 | String realm = authHeader.getRealm(); |
| 131 | 131 | String username = authHeader.getUsername(); |
| 132 | - | |
| 132 | + | |
| 133 | 133 | if ( username == null || realm == null ) { |
| 134 | 134 | return false; |
| 135 | 135 | } |
| 136 | - | |
| 136 | + | |
| 137 | 137 | String nonce = authHeader.getNonce(); |
| 138 | 138 | URI uri = authHeader.getURI(); |
| 139 | 139 | if (uri == null) { |
| 140 | 140 | return false; |
| 141 | 141 | } |
| 142 | - | |
| 143 | 142 | |
| 144 | - | |
| 143 | + | |
| 144 | + | |
| 145 | 145 | String A2 = request.getMethod().toUpperCase() + ":" + uri.toString(); |
| 146 | 146 | String HA1 = hashedPassword; |
| 147 | 147 | |
| 148 | - | |
| 148 | + | |
| 149 | 149 | byte[] mdbytes = messageDigest.digest(A2.getBytes()); |
| 150 | 150 | String HA2 = toHexString(mdbytes); |
| 151 | - | |
| 151 | + | |
| 152 | 152 | String cnonce = authHeader.getCNonce(); |
| 153 | 153 | String KD = HA1 + ":" + nonce; |
| 154 | 154 | if (cnonce != null) { |
| ... | ... | @@ -158,7 +158,7 @@ public class DigestServerAuthenticationHelper { |
| 158 | 158 | mdbytes = messageDigest.digest(KD.getBytes()); |
| 159 | 159 | String mdString = toHexString(mdbytes); |
| 160 | 160 | String response = authHeader.getResponse(); |
| 161 | - | |
| 161 | + | |
| 162 | 162 | |
| 163 | 163 | return mdString.equals(response); |
| 164 | 164 | } |
| ... | ... | @@ -168,11 +168,11 @@ public class DigestServerAuthenticationHelper { |
| 168 | 168 | * |
| 169 | 169 | * @param request - the request to authenticate. |
| 170 | 170 | * @param pass -- the plain text password. |
| 171 | - * | |
| 171 | + * | |
| 172 | 172 | * @return true if authentication succeded and false otherwise. |
| 173 | 173 | */ |
| 174 | 174 | public boolean doAuthenticatePlainTextPassword(Request request, String pass) { |
| 175 | - AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); | |
| 175 | + AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); | |
| 176 | 176 | if ( authHeader == null ) return false; |
| 177 | 177 | String realm = authHeader.getRealm().trim(); |
| 178 | 178 | String username = authHeader.getUsername().trim(); |
| ... | ... | @@ -184,7 +184,7 @@ public class DigestServerAuthenticationHelper { |
| 184 | 184 | String nonce = authHeader.getNonce(); |
| 185 | 185 | URI uri = authHeader.getURI(); |
| 186 | 186 | if (uri == null) { |
| 187 | - return false; | |
| 187 | + return false; | |
| 188 | 188 | } |
| 189 | 189 | // qop 保护质量 包含auth(默认的)和auth-int(增加了报文完整性检测)两种策略 |
| 190 | 190 | String qop = authHeader.getQop(); |
| ... | ... | @@ -233,7 +233,7 @@ public class DigestServerAuthenticationHelper { |
| 233 | 233 | String response = authHeader.getResponse(); |
| 234 | 234 | System.out.println("response: " + response); |
| 235 | 235 | return mdString.equals(response); |
| 236 | - | |
| 236 | + | |
| 237 | 237 | } |
| 238 | 238 | |
| 239 | 239 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.gb28181.bean; | |
| 2 | + | |
| 3 | +public class ParentPlatformCatch { | |
| 4 | + | |
| 5 | + private String id; | |
| 6 | + | |
| 7 | + // 心跳未回复次数 | |
| 8 | + private int keepAliveReply; | |
| 9 | + | |
| 10 | + // 注册未回复次数 | |
| 11 | + private int registerAliveReply; | |
| 12 | + | |
| 13 | + public String getId() { | |
| 14 | + return id; | |
| 15 | + } | |
| 16 | + | |
| 17 | + public void setId(String id) { | |
| 18 | + this.id = id; | |
| 19 | + } | |
| 20 | + | |
| 21 | + public int getKeepAliveReply() { | |
| 22 | + return keepAliveReply; | |
| 23 | + } | |
| 24 | + | |
| 25 | + public void setKeepAliveReply(int keepAliveReply) { | |
| 26 | + this.keepAliveReply = keepAliveReply; | |
| 27 | + } | |
| 28 | + | |
| 29 | + public int getRegisterAliveReply() { | |
| 30 | + return registerAliveReply; | |
| 31 | + } | |
| 32 | + | |
| 33 | + public void setRegisterAliveReply(int registerAliveReply) { | |
| 34 | + this.registerAliveReply = registerAliveReply; | |
| 35 | + } | |
| 36 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformRegister.java
0 → 100644
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.event; |
| 2 | 2 | |
| 3 | -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 3 | +import com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire.PlatformKeepaliveExpireEvent; | |
| 4 | 4 | import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformNotRegisterEvent; |
| 5 | -import com.genersoft.iot.vmp.vmanager.platform.PlatformController; | |
| 6 | 5 | import org.springframework.beans.factory.annotation.Autowired; |
| 7 | 6 | import org.springframework.context.ApplicationEventPublisher; |
| 8 | 7 | import org.springframework.stereotype.Component; |
| ... | ... | @@ -36,6 +35,16 @@ public class EventPublisher { |
| 36 | 35 | } |
| 37 | 36 | |
| 38 | 37 | /** |
| 38 | + * 平台心跳到期事件 | |
| 39 | + * @param platformGbId | |
| 40 | + */ | |
| 41 | + public void platformKeepaliveExpireEventPublish(String platformGbId){ | |
| 42 | + PlatformKeepaliveExpireEvent platformNotRegisterEvent = new PlatformKeepaliveExpireEvent(this); | |
| 43 | + platformNotRegisterEvent.setPlatformGbID(platformGbId); | |
| 44 | + applicationEventPublisher.publishEvent(platformNotRegisterEvent); | |
| 45 | + } | |
| 46 | + | |
| 47 | + /** | |
| 39 | 48 | * 平台未注册事件 |
| 40 | 49 | * @param platformGbId |
| 41 | 50 | */ | ... | ... |
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 org.slf4j.Logger; | |
| 4 | +import org.slf4j.LoggerFactory; | |
| 5 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 6 | +import org.springframework.beans.factory.annotation.Value; | |
| 7 | +import org.springframework.data.redis.connection.Message; | |
| 8 | +import org.springframework.data.redis.connection.MessageListener; | |
| 9 | +import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; | |
| 10 | +import org.springframework.data.redis.listener.RedisMessageListenerContainer; | |
| 11 | +import org.springframework.stereotype.Component; | |
| 12 | + | |
| 13 | +import com.genersoft.iot.vmp.common.VideoManagerConstants; | |
| 14 | +import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | |
| 15 | + | |
| 16 | +import java.nio.charset.StandardCharsets; | |
| 17 | + | |
| 18 | +/** | |
| 19 | + * @Description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件 | |
| 20 | + * @author: swwheihei | |
| 21 | + * @date: 2020年5月6日 上午11:35:46 | |
| 22 | + */ | |
| 23 | +@Component | |
| 24 | +public class KeepaliveTimeoutListenerForPlatform extends KeyExpirationEventMessageListener { | |
| 25 | + | |
| 26 | + @Autowired | |
| 27 | + private EventPublisher publisher; | |
| 28 | + | |
| 29 | + public KeepaliveTimeoutListenerForPlatform(RedisMessageListenerContainer listenerContainer) { | |
| 30 | + super(listenerContainer); | |
| 31 | + } | |
| 32 | + | |
| 33 | + | |
| 34 | + /** | |
| 35 | + * 监听失效的key | |
| 36 | + * @param message | |
| 37 | + * @param bytes | |
| 38 | + */ | |
| 39 | + @Override | |
| 40 | + public void onMessage(Message message, byte[] pattern) { | |
| 41 | + // 获取失效的key | |
| 42 | + String expiredKey = message.toString(); | |
| 43 | + System.out.println(expiredKey); | |
| 44 | + if(!expiredKey.startsWith(VideoManagerConstants.PLATFORM_PREFIX)){ | |
| 45 | + System.out.println("收到redis过期监听,但开头不是"+VideoManagerConstants.PLATFORM_PREFIX+",忽略"); | |
| 46 | + return; | |
| 47 | + } | |
| 48 | + // 平台心跳到期,需要重发, 判断是否已经多次未收到心跳回复, 多次未收到,则重新发起注册, 注册尝试多次未得到回复,则认为平台离线 | |
| 49 | + if (expiredKey.startsWith(VideoManagerConstants.PLATFORM_KEEPLIVEKEY_PREFIX)) { | |
| 50 | + String platformGBId = expiredKey.substring(VideoManagerConstants.PLATFORM_KEEPLIVEKEY_PREFIX.length(),expiredKey.length()); | |
| 51 | + | |
| 52 | + publisher.platformKeepaliveExpireEventPublish(platformGBId); | |
| 53 | + }else if (expiredKey.startsWith(VideoManagerConstants.PLATFORM_REGISTER_PREFIX)) { | |
| 54 | + System.out.println("11111111111111"); | |
| 55 | + String platformGBId = expiredKey.substring(VideoManagerConstants.PLATFORM_REGISTER_PREFIX.length(),expiredKey.length()); | |
| 56 | + | |
| 57 | + publisher.platformNotRegisterEventPublish(platformGBId); | |
| 58 | + }else{ | |
| 59 | + String deviceId = expiredKey.substring(VideoManagerConstants.KEEPLIVEKEY_PREFIX.length(),expiredKey.length()); | |
| 60 | + publisher.outlineEventPublish(deviceId, VideoManagerConstants.EVENT_OUTLINE_TIMEOUT); | |
| 61 | + } | |
| 62 | + | |
| 63 | + } | |
| 64 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEvent.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire; | |
| 2 | + | |
| 3 | +import org.springframework.context.ApplicationEvent; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * 平台心跳超时事件 | |
| 7 | + */ | |
| 8 | +public class PlatformKeepaliveExpireEvent extends ApplicationEvent { | |
| 9 | + | |
| 10 | + private String platformGbID; | |
| 11 | + | |
| 12 | + public PlatformKeepaliveExpireEvent(Object source) { | |
| 13 | + super(source); | |
| 14 | + } | |
| 15 | + | |
| 16 | + public String getPlatformGbID() { | |
| 17 | + return platformGbID; | |
| 18 | + } | |
| 19 | + | |
| 20 | + public void setPlatformGbID(String platformGbID) { | |
| 21 | + this.platformGbID = platformGbID; | |
| 22 | + } | |
| 23 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEventLister.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 4 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; | |
| 5 | +import com.genersoft.iot.vmp.gb28181.bean.PlatformRegister; | |
| 6 | +import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | |
| 7 | +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | |
| 8 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | |
| 9 | +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | |
| 10 | +import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | |
| 11 | +import org.jetbrains.annotations.NotNull; | |
| 12 | +import org.slf4j.Logger; | |
| 13 | +import org.slf4j.LoggerFactory; | |
| 14 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 15 | +import org.springframework.context.ApplicationListener; | |
| 16 | +import org.springframework.stereotype.Component; | |
| 17 | + | |
| 18 | +import javax.sip.ResponseEvent; | |
| 19 | +import javax.sip.message.Response; | |
| 20 | + | |
| 21 | +/** | |
| 22 | + * @Description: 平台心跳超时事件 | |
| 23 | + * @author: panll | |
| 24 | + * @date: 2020年11月5日 10:00 | |
| 25 | + */ | |
| 26 | +@Component | |
| 27 | +public class PlatformKeepaliveExpireEventLister implements ApplicationListener<PlatformKeepaliveExpireEvent> { | |
| 28 | + | |
| 29 | + | |
| 30 | + private final static Logger logger = LoggerFactory.getLogger(PlatformKeepaliveExpireEventLister.class); | |
| 31 | + | |
| 32 | + @Autowired | |
| 33 | + private IVideoManagerStorager storager; | |
| 34 | + | |
| 35 | + @Autowired | |
| 36 | + private IRedisCatchStorage redisCatchStorage; | |
| 37 | + | |
| 38 | + @Autowired | |
| 39 | + private ISIPCommanderForPlatform sipCommanderForPlatform; | |
| 40 | + | |
| 41 | + @Autowired | |
| 42 | + private SipSubscribe sipSubscribe; | |
| 43 | + | |
| 44 | + @Autowired | |
| 45 | + private EventPublisher publisher; | |
| 46 | + | |
| 47 | + @Override | |
| 48 | + public void onApplicationEvent(@NotNull PlatformKeepaliveExpireEvent event) { | |
| 49 | + | |
| 50 | + if (logger.isDebugEnabled()) { | |
| 51 | + logger.debug("平台心跳到期事件事件触发,平台国标ID:" + event.getPlatformGbID()); | |
| 52 | + } | |
| 53 | + ParentPlatform parentPlatform = storager.queryParentPlatById(event.getPlatformGbID()); | |
| 54 | + ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(event.getPlatformGbID()); | |
| 55 | + if (parentPlatform == null) { | |
| 56 | + logger.debug("平台心跳到期事件事件触发,但平台已经删除!!! 平台国标ID:" + event.getPlatformGbID()); | |
| 57 | + return; | |
| 58 | + } | |
| 59 | + if (parentPlatformCatch == null) { | |
| 60 | + return; | |
| 61 | + } | |
| 62 | + // 发送心跳 | |
| 63 | + if (parentPlatformCatch.getKeepAliveReply() >= 3) { | |
| 64 | + // 有3次未收到心跳回复, 设置平台状态为离线, 开始重新注册 | |
| 65 | + logger.warn("有3次未收到心跳回复,标记设置平台状态为离线, 并重新注册 平台国标ID:" + event.getPlatformGbID()); | |
| 66 | + publisher.platformNotRegisterEventPublish(event.getPlatformGbID()); | |
| 67 | + }else { | |
| 68 | + // 再次发送心跳 | |
| 69 | + String callId = sipCommanderForPlatform.keepalive(parentPlatform); | |
| 70 | + | |
| 71 | + parentPlatformCatch.setKeepAliveReply( parentPlatformCatch.getKeepAliveReply() + 1); | |
| 72 | + // 存储心跳信息, 并设置状态为未回复, 如果多次过期仍未收到回复,则认为上级平台已经离线 | |
| 73 | + redisCatchStorage.updatePlatformKeepalive(parentPlatform); | |
| 74 | + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | |
| 75 | + | |
| 76 | + sipSubscribe.addOkSubscribe(callId, (ResponseEvent responseEvent) ->{ | |
| 77 | + if (responseEvent.getResponse().getStatusCode() == Response.OK) { | |
| 78 | + // 收到心跳响应信息, | |
| 79 | + parentPlatformCatch.setKeepAliveReply(0); | |
| 80 | + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | |
| 81 | + } | |
| 82 | + } ); | |
| 83 | + } | |
| 84 | + } | |
| 85 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java
| ... | ... | @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.gb28181.event.platformNotRegister; |
| 3 | 3 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 4 | 4 | import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.event.online.OnlineEventListener; |
| 6 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; | |
| 6 | 7 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 7 | 8 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| 8 | 9 | import org.slf4j.Logger; |
| ... | ... | @@ -26,6 +27,8 @@ public class PlatformNotRegisterEventLister implements ApplicationListener<Platf |
| 26 | 27 | |
| 27 | 28 | @Autowired |
| 28 | 29 | private IVideoManagerStorager storager; |
| 30 | + @Autowired | |
| 31 | + private SIPCommanderFroPlatform sipCommanderFroPlatform; | |
| 29 | 32 | |
| 30 | 33 | @Autowired |
| 31 | 34 | private RedisUtil redis; |
| ... | ... | @@ -33,13 +36,13 @@ public class PlatformNotRegisterEventLister implements ApplicationListener<Platf |
| 33 | 36 | @Override |
| 34 | 37 | public void onApplicationEvent(PlatformNotRegisterEvent event) { |
| 35 | 38 | |
| 36 | - if (logger.isDebugEnabled()) { | |
| 37 | - logger.debug("平台未注册事件触发,平台国标ID:" + event.getPlatformGbID()); | |
| 38 | - } | |
| 39 | + logger.debug("平台未注册事件触发,平台国标ID:" + event.getPlatformGbID()); | |
| 40 | + | |
| 39 | 41 | ParentPlatform parentPlatform = storager.queryParentPlatById(event.getPlatformGbID()); |
| 40 | 42 | if (parentPlatform == null) { |
| 41 | 43 | logger.debug("平台未注册事件触发,但平台已经删除!!! 平台国标ID:" + event.getPlatformGbID()); |
| 42 | 44 | return; |
| 43 | 45 | } |
| 46 | + sipCommanderFroPlatform.register(parentPlatform); | |
| 44 | 47 | } |
| 45 | 48 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
| ... | ... | @@ -4,6 +4,8 @@ import javax.sip.RequestEvent; |
| 4 | 4 | import javax.sip.ResponseEvent; |
| 5 | 5 | import javax.sip.SipProvider; |
| 6 | 6 | import javax.sip.header.CSeqHeader; |
| 7 | +import javax.sip.header.CallIdHeader; | |
| 8 | +import javax.sip.header.Header; | |
| 7 | 9 | import javax.sip.message.Request; |
| 8 | 10 | import javax.sip.message.Response; |
| 9 | 11 | |
| ... | ... | @@ -11,6 +13,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 11 | 13 | import com.alibaba.fastjson.JSON; |
| 12 | 14 | import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; |
| 13 | 15 | import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; |
| 16 | +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | |
| 14 | 17 | import org.slf4j.Logger; |
| 15 | 18 | import org.slf4j.LoggerFactory; |
| 16 | 19 | import org.springframework.beans.factory.annotation.Autowired; |
| ... | ... | @@ -34,6 +37,10 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.impl.OtherRequestProcessor |
| 34 | 37 | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor; |
| 35 | 38 | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.SubscribeRequestProcessor; |
| 36 | 39 | import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; |
| 40 | +import com.genersoft.iot.vmp.gb28181.transmit.response.impl.ByeResponseProcessor; | |
| 41 | +import com.genersoft.iot.vmp.gb28181.transmit.response.impl.CancelResponseProcessor; | |
| 42 | +import com.genersoft.iot.vmp.gb28181.transmit.response.impl.InviteResponseProcessor; | |
| 43 | +import com.genersoft.iot.vmp.gb28181.transmit.response.impl.OtherResponseProcessor; | |
| 37 | 44 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 38 | 45 | import com.genersoft.iot.vmp.utils.SpringBeanFactory; |
| 39 | 46 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| ... | ... | @@ -88,6 +95,7 @@ public class SIPProcessorFactory { |
| 88 | 95 | @Lazy |
| 89 | 96 | private RegisterResponseProcessor registerResponseProcessor; |
| 90 | 97 | |
| 98 | + | |
| 91 | 99 | @Autowired |
| 92 | 100 | private OtherResponseProcessor otherResponseProcessor; |
| 93 | 101 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
| ... | ... | @@ -9,5 +9,14 @@ public interface ISIPCommanderForPlatform { |
| 9 | 9 | * @param parentPlatform |
| 10 | 10 | * @return |
| 11 | 11 | */ |
| 12 | + boolean register(ParentPlatform parentPlatform); | |
| 13 | + | |
| 12 | 14 | boolean register(ParentPlatform parentPlatform, String callId, String realm, String nonce, String scheme); |
| 15 | + | |
| 16 | + /** | |
| 17 | + * 向上级平发送心跳信息 | |
| 18 | + * @param parentPlatform | |
| 19 | + * @return callId(作为接受回复的判定) | |
| 20 | + */ | |
| 21 | + String keepalive(ParentPlatform parentPlatform); | |
| 13 | 22 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.gb28181.transmit.cmd; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.conf.SipConfig; | |
| 4 | +import com.genersoft.iot.vmp.gb28181.bean.Device; | |
| 5 | +import com.genersoft.iot.vmp.gb28181.bean.Host; | |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 7 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 8 | +import org.springframework.beans.factory.annotation.Qualifier; | |
| 9 | +import org.springframework.stereotype.Component; | |
| 10 | +import org.springframework.util.DigestUtils; | |
| 11 | + | |
| 12 | +import javax.sip.InvalidArgumentException; | |
| 13 | +import javax.sip.PeerUnavailableException; | |
| 14 | +import javax.sip.SipFactory; | |
| 15 | +import javax.sip.SipProvider; | |
| 16 | +import javax.sip.address.Address; | |
| 17 | +import javax.sip.address.SipURI; | |
| 18 | +import javax.sip.header.*; | |
| 19 | +import javax.sip.message.Request; | |
| 20 | +import javax.validation.constraints.NotNull; | |
| 21 | +import java.text.ParseException; | |
| 22 | +import java.util.ArrayList; | |
| 23 | + | |
| 24 | +/** | |
| 25 | + * @Description:摄像头命令request创造器 TODO 冗余代码太多待优化 | |
| 26 | + * @author: swwheihei | |
| 27 | + * @date: 2020年5月6日 上午9:29:02 | |
| 28 | + */ | |
| 29 | +@Component | |
| 30 | +public class SIPRequestHeaderPlarformProvider { | |
| 31 | + | |
| 32 | + @Autowired | |
| 33 | + private SipConfig sipConfig; | |
| 34 | + | |
| 35 | + @Autowired | |
| 36 | + private SipFactory sipFactory; | |
| 37 | + | |
| 38 | + @Autowired | |
| 39 | + @Qualifier(value="tcpSipProvider") | |
| 40 | + private SipProvider tcpSipProvider; | |
| 41 | + | |
| 42 | + @Autowired | |
| 43 | + @Qualifier(value="udpSipProvider") | |
| 44 | + private SipProvider udpSipProvider; | |
| 45 | + | |
| 46 | + | |
| 47 | + public Request createKeetpaliveMessageRequest(ParentPlatform parentPlatform, String content, String viaTag, String fromTag, String toTag) throws ParseException, InvalidArgumentException, PeerUnavailableException { | |
| 48 | + Request request = null; | |
| 49 | + // sipuri | |
| 50 | + SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); | |
| 51 | + // via | |
| 52 | + ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); | |
| 53 | + ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), | |
| 54 | + parentPlatform.getTransport(), viaTag); | |
| 55 | + viaHeader.setRPort(); | |
| 56 | + viaHeaders.add(viaHeader); | |
| 57 | + // from | |
| 58 | + SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), | |
| 59 | + sipConfig.getSipIp() + ":" + sipConfig.getSipPort()); | |
| 60 | + Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI); | |
| 61 | + FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag); | |
| 62 | + // to | |
| 63 | + SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort() ); | |
| 64 | + Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI); | |
| 65 | + ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag); | |
| 66 | + // callid | |
| 67 | + CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() | |
| 68 | + : udpSipProvider.getNewCallId(); | |
| 69 | + // Forwards | |
| 70 | + MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70); | |
| 71 | + // ceq | |
| 72 | + CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(1L, Request.MESSAGE); | |
| 73 | + | |
| 74 | + request = sipFactory.createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader, | |
| 75 | + toHeader, viaHeaders, maxForwards); | |
| 76 | + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); | |
| 77 | + request.setContent(content, contentTypeHeader); | |
| 78 | + return request; | |
| 79 | + } | |
| 80 | + | |
| 81 | + | |
| 82 | + public Request createRegisterRequest(@NotNull ParentPlatform platform, String fromTag, String viaTag) throws ParseException, InvalidArgumentException, PeerUnavailableException { | |
| 83 | + Request request = null; | |
| 84 | + String sipAddress = sipConfig.getSipIp() + ":" + sipConfig.getSipPort(); | |
| 85 | + //请求行 | |
| 86 | + SipURI requestLine = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(), | |
| 87 | + platform.getServerIP() + ":" + platform.getServerPort()); | |
| 88 | + //via | |
| 89 | + ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); | |
| 90 | + ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(platform.getServerIP(), platform.getServerPort(), platform.getTransport(), viaTag); | |
| 91 | + viaHeader.setRPort(); | |
| 92 | + viaHeaders.add(viaHeader); | |
| 93 | + //from | |
| 94 | + SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(),sipAddress); | |
| 95 | + Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI); | |
| 96 | + FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag); | |
| 97 | + //to | |
| 98 | + SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(),sipAddress); | |
| 99 | + Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI); | |
| 100 | + ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress,null); | |
| 101 | + | |
| 102 | + //callid | |
| 103 | + CallIdHeader callIdHeader = null; | |
| 104 | + if(platform.getTransport().equals("TCP")) { | |
| 105 | + callIdHeader = tcpSipProvider.getNewCallId(); | |
| 106 | + } | |
| 107 | + if(platform.getTransport().equals("UDP")) { | |
| 108 | + callIdHeader = udpSipProvider.getNewCallId(); | |
| 109 | + } | |
| 110 | + | |
| 111 | + //Forwards | |
| 112 | + MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70); | |
| 113 | + | |
| 114 | + //ceq | |
| 115 | + CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(1L, Request.REGISTER); | |
| 116 | + request = sipFactory.createMessageFactory().createRequest(requestLine, Request.REGISTER, callIdHeader, | |
| 117 | + cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | |
| 118 | + | |
| 119 | + Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory() | |
| 120 | + .createSipURI(platform.getDeviceGBId(), sipAddress)); | |
| 121 | + request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); | |
| 122 | + | |
| 123 | + return request; | |
| 124 | + } | |
| 125 | + | |
| 126 | + public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, String fromTag, String viaTag, | |
| 127 | + String callId, String realm, String nonce, String scheme) throws ParseException, PeerUnavailableException, InvalidArgumentException { | |
| 128 | + Request registerRequest = createRegisterRequest(parentPlatform, fromTag, viaTag); | |
| 129 | + | |
| 130 | + CallIdHeader callIdHeader = (CallIdHeader)registerRequest.getHeader(CallIdHeader.NAME); | |
| 131 | + callIdHeader.setCallId(callId); | |
| 132 | + | |
| 133 | + String uri = "sip:" + parentPlatform.getServerGBId() + | |
| 134 | + "@" + parentPlatform.getServerIP() + | |
| 135 | + ":" + parentPlatform.getServerPort(); | |
| 136 | + | |
| 137 | + String HA1 = DigestUtils.md5DigestAsHex((parentPlatform.getDeviceGBId() + ":" + realm + ":" + parentPlatform.getPassword()).getBytes()); | |
| 138 | + String HA2=DigestUtils.md5DigestAsHex((Request.REGISTER + ":" + uri).getBytes()); | |
| 139 | + String RESPONSE = DigestUtils.md5DigestAsHex((HA1 + ":" + nonce + ":" + HA2).getBytes()); | |
| 140 | + | |
| 141 | + String authorizationHeaderContent = scheme + " username=\"" + parentPlatform.getDeviceGBId() + "\", " + "realm=\"" | |
| 142 | + + realm + "\", uri=\"" + uri + "\", response=\"" + RESPONSE + "\", nonce=\"" | |
| 143 | + + nonce + "\""; | |
| 144 | + AuthorizationHeader authorizationHeader = sipFactory.createHeaderFactory().createAuthorizationHeader(authorizationHeaderContent); | |
| 145 | + registerRequest.addHeader(authorizationHeader); | |
| 146 | + | |
| 147 | + return registerRequest; | |
| 148 | + } | |
| 149 | + | |
| 150 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
| ... | ... | @@ -238,4 +238,38 @@ public class SIPRequestHeaderProvider { |
| 238 | 238 | |
| 239 | 239 | return registerRequest; |
| 240 | 240 | } |
| 241 | + | |
| 242 | +// public Request createKeetpaliveMessageRequest(ParentPlatform parentPlatform, String content, String fromTag, String toTag, Object o) throws PeerUnavailableException, ParseException, InvalidArgumentException { | |
| 243 | +// Request request = null; | |
| 244 | +// // sipuri | |
| 245 | +// SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); | |
| 246 | +// // via | |
| 247 | +// ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); | |
| 248 | +// ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), | |
| 249 | +// parentPlatform.getTransport(), null); | |
| 250 | +// viaHeader.setRPort(); | |
| 251 | +// viaHeaders.add(viaHeader); | |
| 252 | +// // from | |
| 253 | +// SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), | |
| 254 | +// sipConfig.getSipIp() + ":" + sipConfig.getSipPort()); | |
| 255 | +// Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI); | |
| 256 | +// FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag); | |
| 257 | +// // to | |
| 258 | +// SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerGBDomain()); | |
| 259 | +// Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI); | |
| 260 | +// ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag); | |
| 261 | +// // callid | |
| 262 | +// CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() | |
| 263 | +// : udpSipProvider.getNewCallId(); | |
| 264 | +// // Forwards | |
| 265 | +// MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70); | |
| 266 | +// // ceq | |
| 267 | +// CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(1L, Request.MESSAGE); | |
| 268 | +// | |
| 269 | +// request = sipFactory.createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader, | |
| 270 | +// toHeader, viaHeaders, maxForwards); | |
| 271 | +// ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "MANSCDP+xml"); | |
| 272 | +// request.setContent(content, contentTypeHeader); | |
| 273 | +// return request; | |
| 274 | +// } | |
| 241 | 275 | } | ... | ... |
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; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 6 | 6 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 7 | 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 8 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider; | |
| 8 | 9 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; |
| 9 | -import com.genersoft.iot.vmp.media.zlm.ZLMUtils; | |
| 10 | 10 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 11 | 11 | import org.springframework.beans.factory.annotation.Autowired; |
| 12 | 12 | import org.springframework.beans.factory.annotation.Qualifier; |
| ... | ... | @@ -15,8 +15,10 @@ import org.springframework.lang.Nullable; |
| 15 | 15 | import org.springframework.stereotype.Component; |
| 16 | 16 | |
| 17 | 17 | import javax.sip.*; |
| 18 | +import javax.sip.header.CallIdHeader; | |
| 18 | 19 | import javax.sip.message.Request; |
| 19 | 20 | import java.text.ParseException; |
| 21 | +import java.util.UUID; | |
| 20 | 22 | |
| 21 | 23 | @Component |
| 22 | 24 | public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| ... | ... | @@ -28,6 +30,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 28 | 30 | private SIPRequestHeaderProvider headerProvider; |
| 29 | 31 | |
| 30 | 32 | @Autowired |
| 33 | + private SIPRequestHeaderPlarformProvider headerProviderPlarformProvider; | |
| 34 | + | |
| 35 | + @Autowired | |
| 31 | 36 | private VideoStreamSessionManager streamSession; |
| 32 | 37 | |
| 33 | 38 | @Autowired |
| ... | ... | @@ -41,13 +46,15 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 41 | 46 | @Qualifier(value="udpSipProvider") |
| 42 | 47 | private SipProvider udpSipProvider; |
| 43 | 48 | |
| 44 | - @Autowired | |
| 45 | - private ZLMUtils zlmUtils; | |
| 46 | - | |
| 47 | 49 | @Value("${media.rtp.enable}") |
| 48 | 50 | private boolean rtpEnable; |
| 49 | 51 | |
| 50 | 52 | @Override |
| 53 | + public boolean register(ParentPlatform parentPlatform) { | |
| 54 | + return register(parentPlatform, null, null, null, null); | |
| 55 | + } | |
| 56 | + | |
| 57 | + @Override | |
| 51 | 58 | public boolean register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable String realm, @Nullable String nonce, @Nullable String scheme ) { |
| 52 | 59 | try { |
| 53 | 60 | Request request = null; |
| ... | ... | @@ -71,6 +78,35 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 71 | 78 | return false; |
| 72 | 79 | } |
| 73 | 80 | |
| 81 | + @Override | |
| 82 | + public String keepalive(ParentPlatform parentPlatform) { | |
| 83 | + String callId = null; | |
| 84 | + try { | |
| 85 | + | |
| 86 | + StringBuffer keepaliveXml = new StringBuffer(200); | |
| 87 | + keepaliveXml.append("<?xml version=\"1.0\" encoding=\"GB2312\" ?>\r\n"); | |
| 88 | + keepaliveXml.append("<Notify>\r\n"); | |
| 89 | + keepaliveXml.append("<CmdType>Keepalive</CmdType>\r\n"); | |
| 90 | + keepaliveXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); | |
| 91 | + keepaliveXml.append("<DeviceID>" + parentPlatform.getServerGBId() + "</DeviceID>\r\n"); | |
| 92 | + keepaliveXml.append("<Status>OK</Status>\r\n"); | |
| 93 | + keepaliveXml.append("</Notify>\r\n"); | |
| 94 | + | |
| 95 | + Request request = headerProviderPlarformProvider.createKeetpaliveMessageRequest( | |
| 96 | + parentPlatform, | |
| 97 | + keepaliveXml.toString(), | |
| 98 | + UUID.randomUUID().toString().replace("-", ""), | |
| 99 | + UUID.randomUUID().toString().replace("-", ""), | |
| 100 | + null); | |
| 101 | + transmitRequest(parentPlatform, request); | |
| 102 | + CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME); | |
| 103 | + callId = callIdHeader.getCallId(); | |
| 104 | + } catch (ParseException | InvalidArgumentException | SipException e) { | |
| 105 | + e.printStackTrace(); | |
| 106 | + } | |
| 107 | + return callId; | |
| 108 | + } | |
| 109 | + | |
| 74 | 110 | private void transmitRequest(ParentPlatform parentPlatform, Request request) throws SipException { |
| 75 | 111 | if("TCP".equals(parentPlatform.getTransport())) { |
| 76 | 112 | tcpSipProvider.sendRequest(request); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
| ... | ... | @@ -460,6 +460,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { |
| 460 | 460 | cmder.streamByeCmd(streamInfo.getStreamId()); |
| 461 | 461 | } |
| 462 | 462 | } |
| 463 | + | |
| 463 | 464 | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { |
| 464 | 465 | e.printStackTrace(); |
| 465 | 466 | } | ... | ... |
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; |
| 3 | 3 | import com.genersoft.iot.vmp.conf.SipConfig; |
| 4 | 4 | import com.genersoft.iot.vmp.gb28181.SipLayer; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; | |
| 6 | 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 7 | 8 | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor; |
| 8 | 9 | import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; |
| 10 | +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | |
| 9 | 11 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 10 | 12 | import gov.nist.core.Host; |
| 11 | 13 | import gov.nist.javax.sip.address.AddressImpl; |
| ... | ... | @@ -40,6 +42,12 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor { |
| 40 | 42 | @Autowired |
| 41 | 43 | private IVideoManagerStorager storager; |
| 42 | 44 | |
| 45 | + @Autowired | |
| 46 | + private IRedisCatchStorage redisCatchStorage; | |
| 47 | + | |
| 48 | + public RegisterResponseProcessor() { | |
| 49 | + } | |
| 50 | + | |
| 43 | 51 | /** |
| 44 | 52 | * 处理Register响应 |
| 45 | 53 | * |
| ... | ... | @@ -77,6 +85,17 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor { |
| 77 | 85 | logger.info(String.format("%s 注册成功", platformGBId )); |
| 78 | 86 | parentPlatform.setStatus(true); |
| 79 | 87 | storager.updateParentPlatform(parentPlatform); |
| 88 | + // | |
| 89 | + redisCatchStorage.updatePlatformRegister(parentPlatform); | |
| 90 | + | |
| 91 | + redisCatchStorage.updatePlatformKeepalive(parentPlatform); | |
| 92 | + | |
| 93 | + ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getDeviceGBId()); | |
| 94 | + if (parentPlatformCatch == null) { | |
| 95 | + parentPlatformCatch = new ParentPlatformCatch(); | |
| 96 | + parentPlatformCatch.setId(parentPlatform.getDeviceGBId()); | |
| 97 | + } | |
| 98 | + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | |
| 80 | 99 | } |
| 81 | 100 | } |
| 82 | 101 | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
| ... | ... | @@ -2,6 +2,9 @@ package com.genersoft.iot.vmp.storager; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 4 | 4 | import com.genersoft.iot.vmp.conf.MediaServerConfig; |
| 5 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; | |
| 7 | +import com.genersoft.iot.vmp.gb28181.bean.PlatformRegister; | |
| 5 | 8 | |
| 6 | 9 | import java.util.Map; |
| 7 | 10 | |
| ... | ... | @@ -55,4 +58,13 @@ public interface IRedisCatchStorage { |
| 55 | 58 | boolean stopPlayback(StreamInfo streamInfo); |
| 56 | 59 | |
| 57 | 60 | StreamInfo queryPlaybackByDevice(String deviceId, String code); |
| 61 | + | |
| 62 | + void updatePlatformCatchInfo(ParentPlatformCatch parentPlatformCatch); | |
| 63 | + | |
| 64 | + ParentPlatformCatch queryPlatformCatchInfo(String platformGbId); | |
| 65 | + | |
| 66 | + void updatePlatformKeepalive(ParentPlatform parentPlatform); | |
| 67 | + | |
| 68 | + void updatePlatformRegister(ParentPlatform parentPlatform); | |
| 69 | + | |
| 58 | 70 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
| 1 | 1 | package com.genersoft.iot.vmp.storager; |
| 2 | 2 | |
| 3 | 3 | import java.util.List; |
| 4 | +import java.util.Map; | |
| 4 | 5 | |
| 6 | +import com.genersoft.iot.vmp.common.StreamInfo; | |
| 5 | 7 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 6 | 8 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 9 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 7 | 10 | import com.github.pagehelper.PageInfo; |
| 8 | 11 | |
| 9 | 12 | /** |
| ... | ... | @@ -136,4 +139,39 @@ public interface IVideoManagerStorager { |
| 136 | 139 | */ |
| 137 | 140 | void cleanChannelsForDevice(String deviceId); |
| 138 | 141 | |
| 142 | + | |
| 143 | + /** | |
| 144 | + * 更新上级平台 | |
| 145 | + * @param parentPlatform | |
| 146 | + */ | |
| 147 | + boolean updateParentPlatform(ParentPlatform parentPlatform); | |
| 148 | + | |
| 149 | + | |
| 150 | + /** | |
| 151 | + * 添加上级平台 | |
| 152 | + * @param parentPlatform | |
| 153 | + */ | |
| 154 | + boolean addParentPlatform(ParentPlatform parentPlatform); | |
| 155 | + | |
| 156 | + /** | |
| 157 | + * 删除上级平台 | |
| 158 | + * @param parentPlatform | |
| 159 | + */ | |
| 160 | + boolean deleteParentPlatform(ParentPlatform parentPlatform); | |
| 161 | + | |
| 162 | + | |
| 163 | + /** | |
| 164 | + * 分页获取上级平台 | |
| 165 | + * @param page | |
| 166 | + * @param count | |
| 167 | + * @return | |
| 168 | + */ | |
| 169 | + PageInfo<ParentPlatform> queryParentPlatformList(int page, int count); | |
| 170 | + | |
| 171 | + /** | |
| 172 | + * 获取上级平台 | |
| 173 | + * @param platformGbId | |
| 174 | + * @return | |
| 175 | + */ | |
| 176 | + ParentPlatform queryParentPlatById(String platformGbId); | |
| 139 | 177 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
| 1 | 1 | package com.genersoft.iot.vmp.storager.dao; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 4 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 4 | 5 | import org.apache.ibatis.annotations.*; |
| 5 | 6 | |
| 6 | 7 | import java.util.List; |
| ... | ... | @@ -48,4 +49,6 @@ public interface DeviceChannelMapper { |
| 48 | 49 | @Delete("DELETE FROM device_channel WHERE deviceId=#{deviceId}") |
| 49 | 50 | int cleanChannelsByDeviceId(String deviceId); |
| 50 | 51 | |
| 52 | + | |
| 53 | + | |
| 51 | 54 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
| 1 | 1 | package com.genersoft.iot.vmp.storager.dao; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 4 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 4 | 5 | import org.apache.ibatis.annotations.*; |
| 5 | 6 | import org.springframework.stereotype.Repository; |
| 6 | 7 | |
| ... | ... | @@ -63,4 +64,5 @@ public interface DeviceMapper { |
| 63 | 64 | |
| 64 | 65 | @Delete("DELETE FROM device WHERE deviceId=#{deviceId}") |
| 65 | 66 | int del(String deviceId); |
| 67 | + | |
| 66 | 68 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.storager.dao; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 4 | +import org.apache.ibatis.annotations.*; | |
| 5 | +import org.springframework.stereotype.Repository; | |
| 6 | + | |
| 7 | +import java.util.List; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * 用于存储上级平台 | |
| 11 | + */ | |
| 12 | +@Mapper | |
| 13 | +@Repository | |
| 14 | +public interface ParentPlatformMapper { | |
| 15 | + | |
| 16 | + @Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " + | |
| 17 | + " devicePort, username, password, expires, keepTimeout, transport, characterSet, PTZEnable, rtcp, " + | |
| 18 | + " status) " + | |
| 19 | + " VALUES (${enable}, '${name}', '${serverGBId}', '${serverGBDomain}', '${serverIP}', ${serverPort}, '${deviceGBId}', '${deviceIp}', " + | |
| 20 | + " '${devicePort}', '${username}', '${password}', '${expires}', '${keepTimeout}', '${transport}', '${characterSet}', ${PTZEnable}, ${rtcp}, " + | |
| 21 | + " ${status})") | |
| 22 | + int addParentPlatform(ParentPlatform parentPlatform); | |
| 23 | + | |
| 24 | + @Update("UPDATE parent_platform " + | |
| 25 | + "SET enable=#{enable}, " + | |
| 26 | + "name=#{name}," + | |
| 27 | + "serverGBId=#{serverGBId}," + | |
| 28 | + "serverGBDomain=#{serverGBDomain}, " + | |
| 29 | + "serverIP=#{serverIP}," + | |
| 30 | + "serverPort=#{serverPort}, " + | |
| 31 | + "deviceIp=#{deviceIp}, " + | |
| 32 | + "devicePort=#{devicePort}, " + | |
| 33 | + "username=#{username}, " + | |
| 34 | + "password=#{password}, " + | |
| 35 | + "expires=#{expires}, " + | |
| 36 | + "keepTimeout=#{keepTimeout}, " + | |
| 37 | + "transport=#{transport}, " + | |
| 38 | + "characterSet=#{characterSet}, " + | |
| 39 | + "PTZEnable=#{PTZEnable}, " + | |
| 40 | + "rtcp=#{rtcp}, " + | |
| 41 | + "status=#{status} " + | |
| 42 | + "WHERE deviceGBId=#{deviceGBId}") | |
| 43 | + int updateParentPlatform(ParentPlatform parentPlatform); | |
| 44 | + | |
| 45 | + @Delete("DELETE FROM parent_platform WHERE deviceGBId=#{deviceGBId}") | |
| 46 | + int delParentPlatform(ParentPlatform parentPlatform); | |
| 47 | + | |
| 48 | + | |
| 49 | + @Select("SELECT * FROM parent_platform") | |
| 50 | + List<ParentPlatform> getParentPlatformList(); | |
| 51 | + | |
| 52 | + @Select("SELECT * FROM parent_platform WHERE deviceGBId=#{platformGbId}") | |
| 53 | + ParentPlatform getParentPlatById(String platformGbId); | |
| 54 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
| ... | ... | @@ -4,6 +4,9 @@ import com.genersoft.iot.vmp.common.StreamInfo; |
| 4 | 4 | import com.genersoft.iot.vmp.common.VideoManagerConstants; |
| 5 | 5 | import com.genersoft.iot.vmp.conf.MediaServerConfig; |
| 6 | 6 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 7 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 8 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; | |
| 9 | +import com.genersoft.iot.vmp.gb28181.bean.PlatformRegister; | |
| 7 | 10 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 8 | 11 | import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; |
| 9 | 12 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| ... | ... | @@ -163,4 +166,27 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { |
| 163 | 166 | if (playLeys == null || playLeys.size() == 0) return null; |
| 164 | 167 | return (StreamInfo)redis.get(playLeys.get(0).toString()); |
| 165 | 168 | } |
| 169 | + | |
| 170 | + @Override | |
| 171 | + public void updatePlatformCatchInfo(ParentPlatformCatch parentPlatformCatch) { | |
| 172 | + String key = VideoManagerConstants.PLATFORM_CATCH_PREFIX + parentPlatformCatch.getId(); | |
| 173 | + redis.set(key, parentPlatformCatch); | |
| 174 | + } | |
| 175 | + | |
| 176 | + @Override | |
| 177 | + public void updatePlatformKeepalive(ParentPlatform parentPlatform) { | |
| 178 | + String key = VideoManagerConstants.PLATFORM_KEEPLIVEKEY_PREFIX + parentPlatform.getDeviceGBId(); | |
| 179 | + redis.set(key, "", Integer.parseInt(parentPlatform.getKeepTimeout())); | |
| 180 | + } | |
| 181 | + | |
| 182 | + @Override | |
| 183 | + public void updatePlatformRegister(ParentPlatform parentPlatform) { | |
| 184 | + String key = VideoManagerConstants.PLATFORM_REGISTER_PREFIX + parentPlatform.getDeviceGBId(); | |
| 185 | + redis.set(key, "", Integer.parseInt(parentPlatform.getExpires())); | |
| 186 | + } | |
| 187 | + | |
| 188 | + @Override | |
| 189 | + public ParentPlatformCatch queryPlatformCatchInfo(String platformGbId) { | |
| 190 | + return (ParentPlatformCatch)redis.get(VideoManagerConstants.PLATFORM_CATCH_PREFIX + platformGbId); | |
| 191 | + } | |
| 166 | 192 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
| ... | ... | @@ -3,17 +3,17 @@ package com.genersoft.iot.vmp.storager.impl; |
| 3 | 3 | import java.util.*; |
| 4 | 4 | |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 6 | 7 | import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; |
| 7 | 8 | import com.genersoft.iot.vmp.storager.dao.DeviceMapper; |
| 9 | +import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; | |
| 8 | 10 | import com.github.pagehelper.PageHelper; |
| 9 | 11 | import com.github.pagehelper.PageInfo; |
| 10 | -import io.swagger.models.auth.In; | |
| 11 | 12 | import org.springframework.beans.factory.annotation.Autowired; |
| 12 | 13 | import org.springframework.stereotype.Component; |
| 13 | 14 | |
| 14 | 15 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 15 | 16 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 16 | -import org.springframework.util.StringUtils; | |
| 17 | 17 | |
| 18 | 18 | /** |
| 19 | 19 | * @Description:视频设备数据存储-jdbc实现 |
| ... | ... | @@ -29,6 +29,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { |
| 29 | 29 | @Autowired |
| 30 | 30 | private DeviceChannelMapper deviceChannelMapper; |
| 31 | 31 | |
| 32 | + @Autowired | |
| 33 | + private ParentPlatformMapper platformMapper; | |
| 34 | + | |
| 32 | 35 | |
| 33 | 36 | /** |
| 34 | 37 | * 根据设备ID判断设备是否存在 |
| ... | ... | @@ -198,5 +201,40 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { |
| 198 | 201 | int result = deviceChannelMapper.cleanChannelsByDeviceId(deviceId); |
| 199 | 202 | } |
| 200 | 203 | |
| 204 | + @Override | |
| 205 | + public boolean addParentPlatform(ParentPlatform parentPlatform) { | |
| 206 | + int result = platformMapper.addParentPlatform(parentPlatform); | |
| 207 | + return result > 0; | |
| 208 | + } | |
| 209 | + | |
| 210 | + @Override | |
| 211 | + public boolean updateParentPlatform(ParentPlatform parentPlatform) { | |
| 212 | + int result = 0; | |
| 213 | + if ( platformMapper.getParentPlatById(parentPlatform.getDeviceGBId()) == null) { | |
| 214 | + result = platformMapper.addParentPlatform(parentPlatform); | |
| 215 | + }else { | |
| 216 | + result = platformMapper.updateParentPlatform(parentPlatform); | |
| 217 | + } | |
| 218 | + return result > 0; | |
| 219 | + } | |
| 220 | + | |
| 221 | + @Override | |
| 222 | + public boolean deleteParentPlatform(ParentPlatform parentPlatform) { | |
| 223 | + int result = platformMapper.delParentPlatform(parentPlatform); | |
| 224 | + return result > 0; | |
| 225 | + } | |
| 226 | + | |
| 227 | + @Override | |
| 228 | + public PageInfo<ParentPlatform> queryParentPlatformList(int page, int count) { | |
| 229 | + PageHelper.startPage(page, count); | |
| 230 | + List<ParentPlatform> all = platformMapper.getParentPlatformList(); | |
| 231 | + return new PageInfo<>(all); | |
| 232 | + } | |
| 233 | + | |
| 234 | + @Override | |
| 235 | + public ParentPlatform queryParentPlatById(String platformGbId) { | |
| 236 | + return platformMapper.getParentPlatById(platformGbId); | |
| 237 | + } | |
| 238 | + | |
| 201 | 239 | |
| 202 | 240 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/platform/PlatformController.java
| 1 | 1 | package com.genersoft.iot.vmp.vmanager.platform; |
| 2 | 2 | |
| 3 | 3 | import com.alibaba.fastjson.JSONObject; |
| 4 | -import com.genersoft.iot.vmp.common.PageResult; | |
| 5 | -import com.genersoft.iot.vmp.gb28181.bean.Device; | |
| 6 | 4 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 7 | 5 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 8 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | |
| 9 | 6 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 10 | -import com.genersoft.iot.vmp.vmanager.device.DeviceController; | |
| 7 | +import com.github.pagehelper.PageInfo; | |
| 11 | 8 | import org.slf4j.Logger; |
| 12 | 9 | import org.slf4j.LoggerFactory; |
| 13 | 10 | import org.springframework.beans.factory.annotation.Autowired; |
| 14 | 11 | import org.springframework.http.HttpStatus; |
| 15 | 12 | import org.springframework.http.ResponseEntity; |
| 16 | -import org.springframework.stereotype.Controller; | |
| 17 | 13 | import org.springframework.util.StringUtils; |
| 18 | 14 | import org.springframework.web.bind.annotation.*; |
| 19 | 15 | import com.genersoft.iot.vmp.conf.SipConfig; |
| ... | ... | @@ -46,7 +42,7 @@ public class PlatformController { |
| 46 | 42 | } |
| 47 | 43 | |
| 48 | 44 | @GetMapping("/platforms/{count}/{page}") |
| 49 | - public PageResult<ParentPlatform> platforms(@PathVariable int page, @PathVariable int count){ | |
| 45 | + public PageInfo<ParentPlatform> platforms(@PathVariable int page, @PathVariable int count){ | |
| 50 | 46 | |
| 51 | 47 | if (logger.isDebugEnabled()) { |
| 52 | 48 | logger.debug("查询所有上级设备API调用"); | ... | ... |
src/main/resources/wvp.sqlite
No preview for this file type
web_src/src/components/ParentPlatformList.vue
| ... | ... | @@ -152,7 +152,7 @@ export default { |
| 152 | 152 | this.$axios.get(`/api/platforms/${that.count}/${that.currentPage - 1}`) |
| 153 | 153 | .then(function (res) { |
| 154 | 154 | that.total = res.data.total; |
| 155 | - that.platformList = res.data.data; | |
| 155 | + that.platformList = res.data.list; | |
| 156 | 156 | }) |
| 157 | 157 | .catch(function (error) { |
| 158 | 158 | console.log(error); | ... | ... |
web_src/src/router/index.js