Commit 627a14f37e49d5e33cc5f593277ee24f913875b8
1 parent
34135cce
完成向上级联->保活
Showing
28 changed files
with
736 additions
and
67 deletions
README.md
| @@ -39,7 +39,7 @@ https://gitee.com/18010473990/wvp-GB28181.git | @@ -39,7 +39,7 @@ https://gitee.com/18010473990/wvp-GB28181.git | ||
| 39 | - [ ] 国标通道向上级联 | 39 | - [ ] 国标通道向上级联 |
| 40 | - [X] WEB添加上级平台 | 40 | - [X] WEB添加上级平台 |
| 41 | - [X] 注册 | 41 | - [X] 注册 |
| 42 | - - [ ] 心跳保活 | 42 | + - [X] 心跳保活 |
| 43 | - [ ] 通道选择 | 43 | - [ ] 通道选择 |
| 44 | - [ ] 通道推送 | 44 | - [ ] 通道推送 |
| 45 | - [ ] 点播 | 45 | - [ ] 点播 |
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
| @@ -20,7 +20,15 @@ public class VideoManagerConstants { | @@ -20,7 +20,15 @@ public class VideoManagerConstants { | ||
| 20 | 20 | ||
| 21 | public static final String PLAY_BLACK_PREFIX = "VMP_playback_"; | 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 | public static final String EVENT_ONLINE_REGISTER = "1"; | 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 | package com.genersoft.iot.vmp.gb28181.auth; | 26 | package com.genersoft.iot.vmp.gb28181.auth; |
| 27 | 27 | ||
| 28 | import java.security.MessageDigest; | 28 | import java.security.MessageDigest; |
| @@ -42,18 +42,18 @@ import gov.nist.core.InternalErrorHandler; | @@ -42,18 +42,18 @@ import gov.nist.core.InternalErrorHandler; | ||
| 42 | 42 | ||
| 43 | /** | 43 | /** |
| 44 | * Implements the HTTP digest authentication method server side functionality. | 44 | * Implements the HTTP digest authentication method server side functionality. |
| 45 | - * | 45 | + * |
| 46 | * @author M. Ranganathan | 46 | * @author M. Ranganathan |
| 47 | * @author Marc Bednarek | 47 | * @author Marc Bednarek |
| 48 | */ | 48 | */ |
| 49 | 49 | ||
| 50 | public class DigestServerAuthenticationHelper { | 50 | public class DigestServerAuthenticationHelper { |
| 51 | - | 51 | + |
| 52 | private MessageDigest messageDigest; | 52 | private MessageDigest messageDigest; |
| 53 | - | 53 | + |
| 54 | public static final String DEFAULT_ALGORITHM = "MD5"; | 54 | public static final String DEFAULT_ALGORITHM = "MD5"; |
| 55 | public static final String DEFAULT_SCHEME = "Digest"; | 55 | public static final String DEFAULT_SCHEME = "Digest"; |
| 56 | - | 56 | + |
| 57 | 57 | ||
| 58 | 58 | ||
| 59 | 59 | ||
| @@ -63,11 +63,11 @@ public class DigestServerAuthenticationHelper { | @@ -63,11 +63,11 @@ public class DigestServerAuthenticationHelper { | ||
| 63 | 63 | ||
| 64 | /** | 64 | /** |
| 65 | * Default constructor. | 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 | public static String toHexString(byte b[]) { | 73 | public static String toHexString(byte b[]) { |
| @@ -79,7 +79,7 @@ public class DigestServerAuthenticationHelper { | @@ -79,7 +79,7 @@ public class DigestServerAuthenticationHelper { | ||
| 79 | } | 79 | } |
| 80 | return new String(c); | 80 | return new String(c); |
| 81 | } | 81 | } |
| 82 | - | 82 | + |
| 83 | /** | 83 | /** |
| 84 | * Generate the challenge string. | 84 | * Generate the challenge string. |
| 85 | * | 85 | * |
| @@ -121,34 +121,34 @@ public class DigestServerAuthenticationHelper { | @@ -121,34 +121,34 @@ public class DigestServerAuthenticationHelper { | ||
| 121 | * | 121 | * |
| 122 | * @param request - the request to authenticate. | 122 | * @param request - the request to authenticate. |
| 123 | * @param hashedPassword -- the MD5 hashed string of username:realm:plaintext password. | 123 | * @param hashedPassword -- the MD5 hashed string of username:realm:plaintext password. |
| 124 | - * | 124 | + * |
| 125 | * @return true if authentication succeded and false otherwise. | 125 | * @return true if authentication succeded and false otherwise. |
| 126 | */ | 126 | */ |
| 127 | public boolean doAuthenticateHashedPassword(Request request, String hashedPassword) { | 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 | if ( authHeader == null ) return false; | 129 | if ( authHeader == null ) return false; |
| 130 | String realm = authHeader.getRealm(); | 130 | String realm = authHeader.getRealm(); |
| 131 | String username = authHeader.getUsername(); | 131 | String username = authHeader.getUsername(); |
| 132 | - | 132 | + |
| 133 | if ( username == null || realm == null ) { | 133 | if ( username == null || realm == null ) { |
| 134 | return false; | 134 | return false; |
| 135 | } | 135 | } |
| 136 | - | 136 | + |
| 137 | String nonce = authHeader.getNonce(); | 137 | String nonce = authHeader.getNonce(); |
| 138 | URI uri = authHeader.getURI(); | 138 | URI uri = authHeader.getURI(); |
| 139 | if (uri == null) { | 139 | if (uri == null) { |
| 140 | return false; | 140 | return false; |
| 141 | } | 141 | } |
| 142 | - | ||
| 143 | 142 | ||
| 144 | - | 143 | + |
| 144 | + | ||
| 145 | String A2 = request.getMethod().toUpperCase() + ":" + uri.toString(); | 145 | String A2 = request.getMethod().toUpperCase() + ":" + uri.toString(); |
| 146 | String HA1 = hashedPassword; | 146 | String HA1 = hashedPassword; |
| 147 | 147 | ||
| 148 | - | 148 | + |
| 149 | byte[] mdbytes = messageDigest.digest(A2.getBytes()); | 149 | byte[] mdbytes = messageDigest.digest(A2.getBytes()); |
| 150 | String HA2 = toHexString(mdbytes); | 150 | String HA2 = toHexString(mdbytes); |
| 151 | - | 151 | + |
| 152 | String cnonce = authHeader.getCNonce(); | 152 | String cnonce = authHeader.getCNonce(); |
| 153 | String KD = HA1 + ":" + nonce; | 153 | String KD = HA1 + ":" + nonce; |
| 154 | if (cnonce != null) { | 154 | if (cnonce != null) { |
| @@ -158,7 +158,7 @@ public class DigestServerAuthenticationHelper { | @@ -158,7 +158,7 @@ public class DigestServerAuthenticationHelper { | ||
| 158 | mdbytes = messageDigest.digest(KD.getBytes()); | 158 | mdbytes = messageDigest.digest(KD.getBytes()); |
| 159 | String mdString = toHexString(mdbytes); | 159 | String mdString = toHexString(mdbytes); |
| 160 | String response = authHeader.getResponse(); | 160 | String response = authHeader.getResponse(); |
| 161 | - | 161 | + |
| 162 | 162 | ||
| 163 | return mdString.equals(response); | 163 | return mdString.equals(response); |
| 164 | } | 164 | } |
| @@ -168,11 +168,11 @@ public class DigestServerAuthenticationHelper { | @@ -168,11 +168,11 @@ public class DigestServerAuthenticationHelper { | ||
| 168 | * | 168 | * |
| 169 | * @param request - the request to authenticate. | 169 | * @param request - the request to authenticate. |
| 170 | * @param pass -- the plain text password. | 170 | * @param pass -- the plain text password. |
| 171 | - * | 171 | + * |
| 172 | * @return true if authentication succeded and false otherwise. | 172 | * @return true if authentication succeded and false otherwise. |
| 173 | */ | 173 | */ |
| 174 | public boolean doAuthenticatePlainTextPassword(Request request, String pass) { | 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 | if ( authHeader == null ) return false; | 176 | if ( authHeader == null ) return false; |
| 177 | String realm = authHeader.getRealm().trim(); | 177 | String realm = authHeader.getRealm().trim(); |
| 178 | String username = authHeader.getUsername().trim(); | 178 | String username = authHeader.getUsername().trim(); |
| @@ -184,7 +184,7 @@ public class DigestServerAuthenticationHelper { | @@ -184,7 +184,7 @@ public class DigestServerAuthenticationHelper { | ||
| 184 | String nonce = authHeader.getNonce(); | 184 | String nonce = authHeader.getNonce(); |
| 185 | URI uri = authHeader.getURI(); | 185 | URI uri = authHeader.getURI(); |
| 186 | if (uri == null) { | 186 | if (uri == null) { |
| 187 | - return false; | 187 | + return false; |
| 188 | } | 188 | } |
| 189 | // qop 保护质量 包含auth(默认的)和auth-int(增加了报文完整性检测)两种策略 | 189 | // qop 保护质量 包含auth(默认的)和auth-int(增加了报文完整性检测)两种策略 |
| 190 | String qop = authHeader.getQop(); | 190 | String qop = authHeader.getQop(); |
| @@ -233,7 +233,7 @@ public class DigestServerAuthenticationHelper { | @@ -233,7 +233,7 @@ public class DigestServerAuthenticationHelper { | ||
| 233 | String response = authHeader.getResponse(); | 233 | String response = authHeader.getResponse(); |
| 234 | System.out.println("response: " + response); | 234 | System.out.println("response: " + response); |
| 235 | return mdString.equals(response); | 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 | package com.genersoft.iot.vmp.gb28181.event; | 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 | import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformNotRegisterEvent; | 4 | import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformNotRegisterEvent; |
| 5 | -import com.genersoft.iot.vmp.vmanager.platform.PlatformController; | ||
| 6 | import org.springframework.beans.factory.annotation.Autowired; | 5 | import org.springframework.beans.factory.annotation.Autowired; |
| 7 | import org.springframework.context.ApplicationEventPublisher; | 6 | import org.springframework.context.ApplicationEventPublisher; |
| 8 | import org.springframework.stereotype.Component; | 7 | import org.springframework.stereotype.Component; |
| @@ -36,6 +35,16 @@ public class EventPublisher { | @@ -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 | * @param platformGbId | 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,6 +3,7 @@ package com.genersoft.iot.vmp.gb28181.event.platformNotRegister; | ||
| 3 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | 3 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 4 | import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent; | 4 | import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent; |
| 5 | import com.genersoft.iot.vmp.gb28181.event.online.OnlineEventListener; | 5 | import com.genersoft.iot.vmp.gb28181.event.online.OnlineEventListener; |
| 6 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; | ||
| 6 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 7 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 7 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; | 8 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| 8 | import org.slf4j.Logger; | 9 | import org.slf4j.Logger; |
| @@ -26,6 +27,8 @@ public class PlatformNotRegisterEventLister implements ApplicationListener<Platf | @@ -26,6 +27,8 @@ public class PlatformNotRegisterEventLister implements ApplicationListener<Platf | ||
| 26 | 27 | ||
| 27 | @Autowired | 28 | @Autowired |
| 28 | private IVideoManagerStorager storager; | 29 | private IVideoManagerStorager storager; |
| 30 | + @Autowired | ||
| 31 | + private SIPCommanderFroPlatform sipCommanderFroPlatform; | ||
| 29 | 32 | ||
| 30 | @Autowired | 33 | @Autowired |
| 31 | private RedisUtil redis; | 34 | private RedisUtil redis; |
| @@ -33,13 +36,13 @@ public class PlatformNotRegisterEventLister implements ApplicationListener<Platf | @@ -33,13 +36,13 @@ public class PlatformNotRegisterEventLister implements ApplicationListener<Platf | ||
| 33 | @Override | 36 | @Override |
| 34 | public void onApplicationEvent(PlatformNotRegisterEvent event) { | 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 | ParentPlatform parentPlatform = storager.queryParentPlatById(event.getPlatformGbID()); | 41 | ParentPlatform parentPlatform = storager.queryParentPlatById(event.getPlatformGbID()); |
| 40 | if (parentPlatform == null) { | 42 | if (parentPlatform == null) { |
| 41 | logger.debug("平台未注册事件触发,但平台已经删除!!! 平台国标ID:" + event.getPlatformGbID()); | 43 | logger.debug("平台未注册事件触发,但平台已经删除!!! 平台国标ID:" + event.getPlatformGbID()); |
| 42 | return; | 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,6 +4,8 @@ import javax.sip.RequestEvent; | ||
| 4 | import javax.sip.ResponseEvent; | 4 | import javax.sip.ResponseEvent; |
| 5 | import javax.sip.SipProvider; | 5 | import javax.sip.SipProvider; |
| 6 | import javax.sip.header.CSeqHeader; | 6 | import javax.sip.header.CSeqHeader; |
| 7 | +import javax.sip.header.CallIdHeader; | ||
| 8 | +import javax.sip.header.Header; | ||
| 7 | import javax.sip.message.Request; | 9 | import javax.sip.message.Request; |
| 8 | import javax.sip.message.Response; | 10 | import javax.sip.message.Response; |
| 9 | 11 | ||
| @@ -11,6 +13,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | @@ -11,6 +13,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | ||
| 11 | import com.alibaba.fastjson.JSON; | 13 | import com.alibaba.fastjson.JSON; |
| 12 | import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; | 14 | import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; |
| 13 | import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; | 15 | import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; |
| 16 | +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | ||
| 14 | import org.slf4j.Logger; | 17 | import org.slf4j.Logger; |
| 15 | import org.slf4j.LoggerFactory; | 18 | import org.slf4j.LoggerFactory; |
| 16 | import org.springframework.beans.factory.annotation.Autowired; | 19 | import org.springframework.beans.factory.annotation.Autowired; |
| @@ -34,6 +37,10 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.impl.OtherRequestProcessor | @@ -34,6 +37,10 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.impl.OtherRequestProcessor | ||
| 34 | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor; | 37 | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor; |
| 35 | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.SubscribeRequestProcessor; | 38 | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.SubscribeRequestProcessor; |
| 36 | import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; | 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 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 44 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 38 | import com.genersoft.iot.vmp.utils.SpringBeanFactory; | 45 | import com.genersoft.iot.vmp.utils.SpringBeanFactory; |
| 39 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; | 46 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| @@ -88,6 +95,7 @@ public class SIPProcessorFactory { | @@ -88,6 +95,7 @@ public class SIPProcessorFactory { | ||
| 88 | @Lazy | 95 | @Lazy |
| 89 | private RegisterResponseProcessor registerResponseProcessor; | 96 | private RegisterResponseProcessor registerResponseProcessor; |
| 90 | 97 | ||
| 98 | + | ||
| 91 | @Autowired | 99 | @Autowired |
| 92 | private OtherResponseProcessor otherResponseProcessor; | 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,5 +9,14 @@ public interface ISIPCommanderForPlatform { | ||
| 9 | * @param parentPlatform | 9 | * @param parentPlatform |
| 10 | * @return | 10 | * @return |
| 11 | */ | 11 | */ |
| 12 | + boolean register(ParentPlatform parentPlatform); | ||
| 13 | + | ||
| 12 | boolean register(ParentPlatform parentPlatform, String callId, String realm, String nonce, String scheme); | 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,4 +238,38 @@ public class SIPRequestHeaderProvider { | ||
| 238 | 238 | ||
| 239 | return registerRequest; | 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,8 +5,8 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 5 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | 5 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 6 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | 6 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 8 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider; | ||
| 8 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; | 9 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; |
| 9 | -import com.genersoft.iot.vmp.media.zlm.ZLMUtils; | ||
| 10 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 10 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 11 | import org.springframework.beans.factory.annotation.Autowired; | 11 | import org.springframework.beans.factory.annotation.Autowired; |
| 12 | import org.springframework.beans.factory.annotation.Qualifier; | 12 | import org.springframework.beans.factory.annotation.Qualifier; |
| @@ -15,8 +15,10 @@ import org.springframework.lang.Nullable; | @@ -15,8 +15,10 @@ import org.springframework.lang.Nullable; | ||
| 15 | import org.springframework.stereotype.Component; | 15 | import org.springframework.stereotype.Component; |
| 16 | 16 | ||
| 17 | import javax.sip.*; | 17 | import javax.sip.*; |
| 18 | +import javax.sip.header.CallIdHeader; | ||
| 18 | import javax.sip.message.Request; | 19 | import javax.sip.message.Request; |
| 19 | import java.text.ParseException; | 20 | import java.text.ParseException; |
| 21 | +import java.util.UUID; | ||
| 20 | 22 | ||
| 21 | @Component | 23 | @Component |
| 22 | public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | 24 | public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| @@ -28,6 +30,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | @@ -28,6 +30,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | ||
| 28 | private SIPRequestHeaderProvider headerProvider; | 30 | private SIPRequestHeaderProvider headerProvider; |
| 29 | 31 | ||
| 30 | @Autowired | 32 | @Autowired |
| 33 | + private SIPRequestHeaderPlarformProvider headerProviderPlarformProvider; | ||
| 34 | + | ||
| 35 | + @Autowired | ||
| 31 | private VideoStreamSessionManager streamSession; | 36 | private VideoStreamSessionManager streamSession; |
| 32 | 37 | ||
| 33 | @Autowired | 38 | @Autowired |
| @@ -41,13 +46,15 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | @@ -41,13 +46,15 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | ||
| 41 | @Qualifier(value="udpSipProvider") | 46 | @Qualifier(value="udpSipProvider") |
| 42 | private SipProvider udpSipProvider; | 47 | private SipProvider udpSipProvider; |
| 43 | 48 | ||
| 44 | - @Autowired | ||
| 45 | - private ZLMUtils zlmUtils; | ||
| 46 | - | ||
| 47 | @Value("${media.rtp.enable}") | 49 | @Value("${media.rtp.enable}") |
| 48 | private boolean rtpEnable; | 50 | private boolean rtpEnable; |
| 49 | 51 | ||
| 50 | @Override | 52 | @Override |
| 53 | + public boolean register(ParentPlatform parentPlatform) { | ||
| 54 | + return register(parentPlatform, null, null, null, null); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + @Override | ||
| 51 | public boolean register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable String realm, @Nullable String nonce, @Nullable String scheme ) { | 58 | public boolean register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable String realm, @Nullable String nonce, @Nullable String scheme ) { |
| 52 | try { | 59 | try { |
| 53 | Request request = null; | 60 | Request request = null; |
| @@ -71,6 +78,35 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | @@ -71,6 +78,35 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | ||
| 71 | return false; | 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 | private void transmitRequest(ParentPlatform parentPlatform, Request request) throws SipException { | 110 | private void transmitRequest(ParentPlatform parentPlatform, Request request) throws SipException { |
| 75 | if("TCP".equals(parentPlatform.getTransport())) { | 111 | if("TCP".equals(parentPlatform.getTransport())) { |
| 76 | tcpSipProvider.sendRequest(request); | 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,6 +460,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 460 | cmder.streamByeCmd(streamInfo.getStreamId()); | 460 | cmder.streamByeCmd(streamInfo.getStreamId()); |
| 461 | } | 461 | } |
| 462 | } | 462 | } |
| 463 | + | ||
| 463 | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { | 464 | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { |
| 464 | e.printStackTrace(); | 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,9 +3,11 @@ package com.genersoft.iot.vmp.gb28181.transmit.response.impl; | ||
| 3 | import com.genersoft.iot.vmp.conf.SipConfig; | 3 | import com.genersoft.iot.vmp.conf.SipConfig; |
| 4 | import com.genersoft.iot.vmp.gb28181.SipLayer; | 4 | import com.genersoft.iot.vmp.gb28181.SipLayer; |
| 5 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | 5 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; | ||
| 6 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 7 | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor; | 8 | import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor; |
| 8 | import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; | 9 | import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; |
| 10 | +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | ||
| 9 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 11 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 10 | import gov.nist.core.Host; | 12 | import gov.nist.core.Host; |
| 11 | import gov.nist.javax.sip.address.AddressImpl; | 13 | import gov.nist.javax.sip.address.AddressImpl; |
| @@ -40,6 +42,12 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor { | @@ -40,6 +42,12 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor { | ||
| 40 | @Autowired | 42 | @Autowired |
| 41 | private IVideoManagerStorager storager; | 43 | private IVideoManagerStorager storager; |
| 42 | 44 | ||
| 45 | + @Autowired | ||
| 46 | + private IRedisCatchStorage redisCatchStorage; | ||
| 47 | + | ||
| 48 | + public RegisterResponseProcessor() { | ||
| 49 | + } | ||
| 50 | + | ||
| 43 | /** | 51 | /** |
| 44 | * 处理Register响应 | 52 | * 处理Register响应 |
| 45 | * | 53 | * |
| @@ -77,6 +85,17 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor { | @@ -77,6 +85,17 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor { | ||
| 77 | logger.info(String.format("%s 注册成功", platformGBId )); | 85 | logger.info(String.format("%s 注册成功", platformGBId )); |
| 78 | parentPlatform.setStatus(true); | 86 | parentPlatform.setStatus(true); |
| 79 | storager.updateParentPlatform(parentPlatform); | 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,6 +2,9 @@ package com.genersoft.iot.vmp.storager; | ||
| 2 | 2 | ||
| 3 | import com.genersoft.iot.vmp.common.StreamInfo; | 3 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 4 | import com.genersoft.iot.vmp.conf.MediaServerConfig; | 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 | import java.util.Map; | 9 | import java.util.Map; |
| 7 | 10 | ||
| @@ -55,4 +58,13 @@ public interface IRedisCatchStorage { | @@ -55,4 +58,13 @@ public interface IRedisCatchStorage { | ||
| 55 | boolean stopPlayback(StreamInfo streamInfo); | 58 | boolean stopPlayback(StreamInfo streamInfo); |
| 56 | 59 | ||
| 57 | StreamInfo queryPlaybackByDevice(String deviceId, String code); | 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 | package com.genersoft.iot.vmp.storager; | 1 | package com.genersoft.iot.vmp.storager; |
| 2 | 2 | ||
| 3 | import java.util.List; | 3 | import java.util.List; |
| 4 | +import java.util.Map; | ||
| 4 | 5 | ||
| 6 | +import com.genersoft.iot.vmp.common.StreamInfo; | ||
| 5 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 7 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 6 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | 8 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 9 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | ||
| 7 | import com.github.pagehelper.PageInfo; | 10 | import com.github.pagehelper.PageInfo; |
| 8 | 11 | ||
| 9 | /** | 12 | /** |
| @@ -136,4 +139,39 @@ public interface IVideoManagerStorager { | @@ -136,4 +139,39 @@ public interface IVideoManagerStorager { | ||
| 136 | */ | 139 | */ |
| 137 | void cleanChannelsForDevice(String deviceId); | 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 | package com.genersoft.iot.vmp.storager.dao; | 1 | package com.genersoft.iot.vmp.storager.dao; |
| 2 | 2 | ||
| 3 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | 3 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 4 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | ||
| 4 | import org.apache.ibatis.annotations.*; | 5 | import org.apache.ibatis.annotations.*; |
| 5 | 6 | ||
| 6 | import java.util.List; | 7 | import java.util.List; |
| @@ -48,4 +49,6 @@ public interface DeviceChannelMapper { | @@ -48,4 +49,6 @@ public interface DeviceChannelMapper { | ||
| 48 | @Delete("DELETE FROM device_channel WHERE deviceId=#{deviceId}") | 49 | @Delete("DELETE FROM device_channel WHERE deviceId=#{deviceId}") |
| 49 | int cleanChannelsByDeviceId(String deviceId); | 50 | int cleanChannelsByDeviceId(String deviceId); |
| 50 | 51 | ||
| 52 | + | ||
| 53 | + | ||
| 51 | } | 54 | } |
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
| 1 | package com.genersoft.iot.vmp.storager.dao; | 1 | package com.genersoft.iot.vmp.storager.dao; |
| 2 | 2 | ||
| 3 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 3 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 4 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | ||
| 4 | import org.apache.ibatis.annotations.*; | 5 | import org.apache.ibatis.annotations.*; |
| 5 | import org.springframework.stereotype.Repository; | 6 | import org.springframework.stereotype.Repository; |
| 6 | 7 | ||
| @@ -63,4 +64,5 @@ public interface DeviceMapper { | @@ -63,4 +64,5 @@ public interface DeviceMapper { | ||
| 63 | 64 | ||
| 64 | @Delete("DELETE FROM device WHERE deviceId=#{deviceId}") | 65 | @Delete("DELETE FROM device WHERE deviceId=#{deviceId}") |
| 65 | int del(String deviceId); | 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,6 +4,9 @@ import com.genersoft.iot.vmp.common.StreamInfo; | ||
| 4 | import com.genersoft.iot.vmp.common.VideoManagerConstants; | 4 | import com.genersoft.iot.vmp.common.VideoManagerConstants; |
| 5 | import com.genersoft.iot.vmp.conf.MediaServerConfig; | 5 | import com.genersoft.iot.vmp.conf.MediaServerConfig; |
| 6 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | 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 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 10 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 8 | import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; | 11 | import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; |
| 9 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; | 12 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| @@ -163,4 +166,27 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { | @@ -163,4 +166,27 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { | ||
| 163 | if (playLeys == null || playLeys.size() == 0) return null; | 166 | if (playLeys == null || playLeys.size() == 0) return null; |
| 164 | return (StreamInfo)redis.get(playLeys.get(0).toString()); | 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,17 +3,17 @@ package com.genersoft.iot.vmp.storager.impl; | ||
| 3 | import java.util.*; | 3 | import java.util.*; |
| 4 | 4 | ||
| 5 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | 5 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | ||
| 6 | import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; | 7 | import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; |
| 7 | import com.genersoft.iot.vmp.storager.dao.DeviceMapper; | 8 | import com.genersoft.iot.vmp.storager.dao.DeviceMapper; |
| 9 | +import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; | ||
| 8 | import com.github.pagehelper.PageHelper; | 10 | import com.github.pagehelper.PageHelper; |
| 9 | import com.github.pagehelper.PageInfo; | 11 | import com.github.pagehelper.PageInfo; |
| 10 | -import io.swagger.models.auth.In; | ||
| 11 | import org.springframework.beans.factory.annotation.Autowired; | 12 | import org.springframework.beans.factory.annotation.Autowired; |
| 12 | import org.springframework.stereotype.Component; | 13 | import org.springframework.stereotype.Component; |
| 13 | 14 | ||
| 14 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 15 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 15 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 16 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 16 | -import org.springframework.util.StringUtils; | ||
| 17 | 17 | ||
| 18 | /** | 18 | /** |
| 19 | * @Description:视频设备数据存储-jdbc实现 | 19 | * @Description:视频设备数据存储-jdbc实现 |
| @@ -29,6 +29,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { | @@ -29,6 +29,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { | ||
| 29 | @Autowired | 29 | @Autowired |
| 30 | private DeviceChannelMapper deviceChannelMapper; | 30 | private DeviceChannelMapper deviceChannelMapper; |
| 31 | 31 | ||
| 32 | + @Autowired | ||
| 33 | + private ParentPlatformMapper platformMapper; | ||
| 34 | + | ||
| 32 | 35 | ||
| 33 | /** | 36 | /** |
| 34 | * 根据设备ID判断设备是否存在 | 37 | * 根据设备ID判断设备是否存在 |
| @@ -198,5 +201,40 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { | @@ -198,5 +201,40 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { | ||
| 198 | int result = deviceChannelMapper.cleanChannelsByDeviceId(deviceId); | 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 | package com.genersoft.iot.vmp.vmanager.platform; | 1 | package com.genersoft.iot.vmp.vmanager.platform; |
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson.JSONObject; | 3 | import com.alibaba.fastjson.JSONObject; |
| 4 | -import com.genersoft.iot.vmp.common.PageResult; | ||
| 5 | -import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 6 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | 4 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | 5 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 8 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 9 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 6 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 10 | -import com.genersoft.iot.vmp.vmanager.device.DeviceController; | 7 | +import com.github.pagehelper.PageInfo; |
| 11 | import org.slf4j.Logger; | 8 | import org.slf4j.Logger; |
| 12 | import org.slf4j.LoggerFactory; | 9 | import org.slf4j.LoggerFactory; |
| 13 | import org.springframework.beans.factory.annotation.Autowired; | 10 | import org.springframework.beans.factory.annotation.Autowired; |
| 14 | import org.springframework.http.HttpStatus; | 11 | import org.springframework.http.HttpStatus; |
| 15 | import org.springframework.http.ResponseEntity; | 12 | import org.springframework.http.ResponseEntity; |
| 16 | -import org.springframework.stereotype.Controller; | ||
| 17 | import org.springframework.util.StringUtils; | 13 | import org.springframework.util.StringUtils; |
| 18 | import org.springframework.web.bind.annotation.*; | 14 | import org.springframework.web.bind.annotation.*; |
| 19 | import com.genersoft.iot.vmp.conf.SipConfig; | 15 | import com.genersoft.iot.vmp.conf.SipConfig; |
| @@ -46,7 +42,7 @@ public class PlatformController { | @@ -46,7 +42,7 @@ public class PlatformController { | ||
| 46 | } | 42 | } |
| 47 | 43 | ||
| 48 | @GetMapping("/platforms/{count}/{page}") | 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 | if (logger.isDebugEnabled()) { | 47 | if (logger.isDebugEnabled()) { |
| 52 | logger.debug("查询所有上级设备API调用"); | 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,7 +152,7 @@ export default { | ||
| 152 | this.$axios.get(`/api/platforms/${that.count}/${that.currentPage - 1}`) | 152 | this.$axios.get(`/api/platforms/${that.count}/${that.currentPage - 1}`) |
| 153 | .then(function (res) { | 153 | .then(function (res) { |
| 154 | that.total = res.data.total; | 154 | that.total = res.data.total; |
| 155 | - that.platformList = res.data.data; | 155 | + that.platformList = res.data.list; |
| 156 | }) | 156 | }) |
| 157 | .catch(function (error) { | 157 | .catch(function (error) { |
| 158 | console.log(error); | 158 | console.log(error); |
web_src/src/router/index.js
| @@ -35,7 +35,7 @@ export default new VueRouter({ | @@ -35,7 +35,7 @@ export default new VueRouter({ | ||
| 35 | path: '/channelList/:deviceId/:parentChannelId/:count/:page', | 35 | path: '/channelList/:deviceId/:parentChannelId/:count/:page', |
| 36 | name: 'channelList', | 36 | name: 'channelList', |
| 37 | component: channelList, | 37 | component: channelList, |
| 38 | - }, | 38 | + },, |
| 39 | { | 39 | { |
| 40 | path: '/parentPlatformList/:count/:page', | 40 | path: '/parentPlatformList/:count/:page', |
| 41 | name: 'parentPlatformList', | 41 | name: 'parentPlatformList', |