Commit 03d6ad289baddf8feed64ffca5f1b13828bea710
Merge branch 'wvp-28181-2.0'
# Conflicts: # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java # src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java # src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java # src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
Showing
76 changed files
with
979 additions
and
904 deletions
doc/_content/donation.md deleted
100644 → 0
| 1 | -# 捐赠 | |
| 2 | -项目目前仍在积极开发。大家的捐赠以及start可以让我看到大家的支持于关注。更加有动力把项目维护下去。 | |
| 3 | - | |
| 4 | -<div align="left"> | |
| 5 | -<img src=_media/weixin.jpg style="height: 500px; border: 1px solid #e2e2e2"/> | |
| 6 | -<img src=_media/zhifubao.jpg style="height: 500px; border: 1px solid #e2e2e2; margin-left: 20px"/> | |
| 7 | -</div> | |
| 8 | 0 | \ No newline at end of file |
doc/_sidebar.md
pom.xml
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
| ... | ... | @@ -31,6 +31,8 @@ public class StreamInfo { |
| 31 | 31 | private String rtsp; |
| 32 | 32 | private String rtsps; |
| 33 | 33 | private String rtc; |
| 34 | + | |
| 35 | + private String rtcs; | |
| 34 | 36 | private String mediaServerId; |
| 35 | 37 | private Object tracks; |
| 36 | 38 | private String startTime; |
| ... | ... | @@ -302,4 +304,12 @@ public class StreamInfo { |
| 302 | 304 | public void setIp(String ip) { |
| 303 | 305 | this.ip = ip; |
| 304 | 306 | } |
| 307 | + | |
| 308 | + public String getRtcs() { | |
| 309 | + return rtcs; | |
| 310 | + } | |
| 311 | + | |
| 312 | + public void setRtcs(String rtcs) { | |
| 313 | + this.rtcs = rtcs; | |
| 314 | + } | |
| 305 | 315 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
| ... | ... | @@ -14,8 +14,6 @@ public class VideoManagerConstants { |
| 14 | 14 | |
| 15 | 15 | public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_"; |
| 16 | 16 | |
| 17 | - public static final String MEDIA_SERVER_KEEPALIVE_PREFIX = "VMP_MEDIA_SERVER_KEEPALIVE_"; | |
| 18 | - | |
| 19 | 17 | public static final String MEDIA_SERVERS_ONLINE_PREFIX = "VMP_MEDIA_ONLINE_SERVERS_"; |
| 20 | 18 | |
| 21 | 19 | public static final String MEDIA_STREAM_PREFIX = "VMP_MEDIA_STREAM"; | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/RedisKeyExpirationEventMessageListener.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.conf; | |
| 2 | - | |
| 3 | -import org.springframework.data.redis.connection.RedisConnection; | |
| 4 | -import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; | |
| 5 | -import org.springframework.data.redis.listener.RedisMessageListenerContainer; | |
| 6 | - | |
| 7 | -import java.util.Properties; | |
| 8 | - | |
| 9 | -public class RedisKeyExpirationEventMessageListener extends KeyExpirationEventMessageListener { | |
| 10 | - | |
| 11 | - private UserSetting userSetting; | |
| 12 | - private RedisMessageListenerContainer listenerContainer; | |
| 13 | - private String keyspaceNotificationsConfigParameter = "EA"; | |
| 14 | - | |
| 15 | - public RedisKeyExpirationEventMessageListener(RedisMessageListenerContainer listenerContainer, UserSetting userSetting) { | |
| 16 | - super(listenerContainer); | |
| 17 | - this.listenerContainer = listenerContainer; | |
| 18 | - this.userSetting = userSetting; | |
| 19 | - } | |
| 20 | - | |
| 21 | - @Override | |
| 22 | - public void init() { | |
| 23 | - if (!userSetting.getRedisConfig()) { | |
| 24 | - // 配置springboot默认Config为空,即不让应用去修改redis的默认配置,因为Redis服务出于安全会禁用CONFIG命令给远程用户使用 | |
| 25 | - setKeyspaceNotificationsConfigParameter(""); | |
| 26 | - }else { | |
| 27 | - | |
| 28 | - RedisConnection connection = this.listenerContainer.getConnectionFactory().getConnection(); | |
| 29 | - Properties config = connection.getConfig("notify-keyspace-events"); | |
| 30 | - try { | |
| 31 | - if (!keyspaceNotificationsConfigParameter.equals(config.getProperty("notify-keyspace-events"))) { | |
| 32 | - connection.setConfig("notify-keyspace-events", keyspaceNotificationsConfigParameter); | |
| 33 | - } | |
| 34 | - } finally { | |
| 35 | - connection.close(); | |
| 36 | - } | |
| 37 | - } | |
| 38 | - super.init(); | |
| 39 | - } | |
| 40 | -} |
src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
| ... | ... | @@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 4 | 4 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| 6 | 6 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 7 | +import com.genersoft.iot.vmp.service.IPlatformService; | |
| 7 | 8 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 8 | 9 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 9 | 10 | import org.springframework.beans.factory.annotation.Autowired; |
| ... | ... | @@ -15,6 +16,7 @@ import java.util.List; |
| 15 | 16 | |
| 16 | 17 | /** |
| 17 | 18 | * 系统启动时控制上级平台重新注册 |
| 19 | + * @author lin | |
| 18 | 20 | */ |
| 19 | 21 | @Component |
| 20 | 22 | @Order(value=3) |
| ... | ... | @@ -27,7 +29,7 @@ public class SipPlatformRunner implements CommandLineRunner { |
| 27 | 29 | private IRedisCatchStorage redisCatchStorage; |
| 28 | 30 | |
| 29 | 31 | @Autowired |
| 30 | - private EventPublisher publisher; | |
| 32 | + private IPlatformService platformService; | |
| 31 | 33 | |
| 32 | 34 | @Autowired |
| 33 | 35 | private ISIPCommanderForPlatform sipCommanderForPlatform; |
| ... | ... | @@ -35,33 +37,26 @@ public class SipPlatformRunner implements CommandLineRunner { |
| 35 | 37 | |
| 36 | 38 | @Override |
| 37 | 39 | public void run(String... args) throws Exception { |
| 38 | - // 设置所有平台离线 | |
| 39 | - storager.outlineForAllParentPlatform(); | |
| 40 | - | |
| 41 | - // 清理所有平台注册缓存 | |
| 42 | - redisCatchStorage.cleanPlatformRegisterInfos(); | |
| 43 | - | |
| 44 | - // 停止所有推流 | |
| 45 | -// zlmrtpServerFactory.closeAllSendRtpStream(); | |
| 46 | - | |
| 40 | + // 获取所有启用的平台 | |
| 47 | 41 | List<ParentPlatform> parentPlatforms = storager.queryEnableParentPlatformList(true); |
| 48 | 42 | |
| 49 | 43 | for (ParentPlatform parentPlatform : parentPlatforms) { |
| 50 | - redisCatchStorage.updatePlatformRegister(parentPlatform); | |
| 51 | - | |
| 52 | - redisCatchStorage.updatePlatformKeepalive(parentPlatform); | |
| 53 | - | |
| 44 | + // 更新缓存 | |
| 54 | 45 | ParentPlatformCatch parentPlatformCatch = new ParentPlatformCatch(); |
| 55 | - | |
| 56 | 46 | parentPlatformCatch.setParentPlatform(parentPlatform); |
| 57 | 47 | parentPlatformCatch.setId(parentPlatform.getServerGBId()); |
| 58 | 48 | redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); |
| 49 | + if (parentPlatform.isStatus()) { | |
| 50 | + // 设置所有平台离线 | |
| 51 | + platformService.offline(parentPlatform); | |
| 52 | + // 取消订阅 | |
| 53 | + sipCommanderForPlatform.unregister(parentPlatform, null, (eventResult)->{ | |
| 54 | + platformService.login(parentPlatform); | |
| 55 | + }); | |
| 56 | + }else { | |
| 57 | + platformService.login(parentPlatform); | |
| 58 | + } | |
| 59 | 59 | |
| 60 | - // 取消订阅 | |
| 61 | - sipCommanderForPlatform.unregister(parentPlatform, null, (eventResult)->{ | |
| 62 | - // 发送平台未注册消息 | |
| 63 | - publisher.platformNotRegisterEventPublish(parentPlatform.getServerGBId()); | |
| 64 | - }); | |
| 65 | 60 | } |
| 66 | 61 | } |
| 67 | 62 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
| ... | ... | @@ -31,8 +31,6 @@ public class UserSetting { |
| 31 | 31 | |
| 32 | 32 | private Boolean logInDatebase = Boolean.TRUE; |
| 33 | 33 | |
| 34 | - private Boolean redisConfig = Boolean.TRUE; | |
| 35 | - | |
| 36 | 34 | private String serverId = "000000"; |
| 37 | 35 | |
| 38 | 36 | private String thirdPartyGBIdReg = "[\\s\\S]*"; |
| ... | ... | @@ -123,14 +121,6 @@ public class UserSetting { |
| 123 | 121 | this.thirdPartyGBIdReg = thirdPartyGBIdReg; |
| 124 | 122 | } |
| 125 | 123 | |
| 126 | - public Boolean getRedisConfig() { | |
| 127 | - return redisConfig; | |
| 128 | - } | |
| 129 | - | |
| 130 | - public void setRedisConfig(Boolean redisConfig) { | |
| 131 | - this.redisConfig = redisConfig; | |
| 132 | - } | |
| 133 | - | |
| 134 | 124 | public Boolean getRecordSip() { |
| 135 | 125 | return recordSip; |
| 136 | 126 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/security/AnonymousAuthenticationEntryPoint.java
| 1 | 1 | package com.genersoft.iot.vmp.conf.security; |
| 2 | 2 | |
| 3 | 3 | import com.alibaba.fastjson.JSONObject; |
| 4 | +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; | |
| 5 | +import org.apache.poi.hssf.eventmodel.ERFListener; | |
| 4 | 6 | import org.slf4j.Logger; |
| 5 | 7 | import org.slf4j.LoggerFactory; |
| 6 | 8 | import org.springframework.security.core.AuthenticationException; |
| ... | ... | @@ -28,8 +30,8 @@ public class AnonymousAuthenticationEntryPoint implements AuthenticationEntryPoi |
| 28 | 30 | response.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified"); |
| 29 | 31 | response.setHeader("Content-type", "application/json;charset=UTF-8"); |
| 30 | 32 | JSONObject jsonObject = new JSONObject(); |
| 31 | - jsonObject.put("code", "-1"); | |
| 32 | - jsonObject.put("msg", "请登录后重新请求"); | |
| 33 | + jsonObject.put("code", ErrorCode.ERROR401.getCode()); | |
| 34 | + jsonObject.put("msg", ErrorCode.ERROR401.getMsg()); | |
| 33 | 35 | String logUri = "api/user/login"; |
| 34 | 36 | if (request.getRequestURI().contains(logUri)){ |
| 35 | 37 | jsonObject.put("msg", e.getMessage()); | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/security/UrlTokenHandler.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.conf.security; | |
| 2 | + | |
| 3 | +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; | |
| 4 | + | |
| 5 | +import javax.servlet.ServletContext; | |
| 6 | +import javax.servlet.ServletException; | |
| 7 | +import javax.servlet.SessionCookieConfig; | |
| 8 | +import javax.servlet.SessionTrackingMode; | |
| 9 | +import java.util.Collections; | |
| 10 | + | |
| 11 | +public class UrlTokenHandler extends SpringBootServletInitializer { | |
| 12 | + | |
| 13 | + @Override | |
| 14 | + public void onStartup(ServletContext servletContext) throws ServletException { | |
| 15 | + super.onStartup(servletContext); | |
| 16 | + | |
| 17 | + servletContext.setSessionTrackingModes( | |
| 18 | + Collections.singleton(SessionTrackingMode.COOKIE) | |
| 19 | + ); | |
| 20 | + SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig(); | |
| 21 | + sessionCookieConfig.setHttpOnly(true); | |
| 22 | + | |
| 23 | + } | |
| 24 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
| ... | ... | @@ -10,14 +10,10 @@ import org.springframework.beans.factory.annotation.Autowired; |
| 10 | 10 | import org.springframework.context.annotation.Bean; |
| 11 | 11 | import org.springframework.context.annotation.Configuration; |
| 12 | 12 | import org.springframework.context.annotation.DependsOn; |
| 13 | -import org.springframework.stereotype.Component; | |
| 14 | 13 | |
| 15 | 14 | import javax.sip.*; |
| 16 | 15 | import java.util.Properties; |
| 17 | 16 | import java.util.TooManyListenersException; |
| 18 | -import java.util.concurrent.LinkedBlockingQueue; | |
| 19 | -import java.util.concurrent.ThreadPoolExecutor; | |
| 20 | -import java.util.concurrent.TimeUnit; | |
| 21 | 17 | |
| 22 | 18 | @Configuration |
| 23 | 19 | public class SipLayer{ |
| ... | ... | @@ -52,7 +48,9 @@ public class SipLayer{ |
| 52 | 48 | * 完整配置参考 gov.nist.javax.sip.SipStackImpl,需要下载源码 |
| 53 | 49 | * gov/nist/javax/sip/SipStackImpl.class |
| 54 | 50 | */ |
| 55 | - properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true"); | |
| 51 | + if (logger.isDebugEnabled()) { | |
| 52 | + properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false"); | |
| 53 | + } | |
| 56 | 54 | // 接收所有notify请求,即使没有订阅 |
| 57 | 55 | properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); |
| 58 | 56 | // 为_NULL _对话框传递_终止的_事件 |
| ... | ... | @@ -63,13 +61,13 @@ public class SipLayer{ |
| 63 | 61 | properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "60"); |
| 64 | 62 | |
| 65 | 63 | /** |
| 66 | - * sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE = | |
| 67 | - * 0; public static final int TRACE_MESSAGES = 16; public static final int | |
| 68 | - * TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32; | |
| 64 | + * sip_server_log.log 和 sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE | |
| 69 | 65 | */ |
| 70 | - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "0"); | |
| 71 | - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log"); | |
| 72 | - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log"); | |
| 66 | + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "ERROR"); | |
| 67 | +// if (logger.isDebugEnabled()) { | |
| 68 | +// properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "DEBUG"); | |
| 69 | +// } | |
| 70 | + | |
| 73 | 71 | sipStack = (SipStackImpl) sipFactory.createSipStack(properties); |
| 74 | 72 | |
| 75 | 73 | return sipStack; | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java
| ... | ... | @@ -84,7 +84,7 @@ public class ParentPlatform { |
| 84 | 84 | * 注册周期 (秒) |
| 85 | 85 | */ |
| 86 | 86 | @Schema(description = "注册周期 (秒)") |
| 87 | - private String expires; | |
| 87 | + private int expires; | |
| 88 | 88 | |
| 89 | 89 | /** |
| 90 | 90 | * 心跳周期(秒) |
| ... | ... | @@ -286,11 +286,11 @@ public class ParentPlatform { |
| 286 | 286 | this.password = password; |
| 287 | 287 | } |
| 288 | 288 | |
| 289 | - public String getExpires() { | |
| 289 | + public int getExpires() { | |
| 290 | 290 | return expires; |
| 291 | 291 | } |
| 292 | 292 | |
| 293 | - public void setExpires(String expires) { | |
| 293 | + public void setExpires(int expires) { | |
| 294 | 294 | this.expires = expires; |
| 295 | 295 | } |
| 296 | 296 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
| ... | ... | @@ -2,9 +2,6 @@ package com.genersoft.iot.vmp.gb28181.event; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 4 | 4 | import com.genersoft.iot.vmp.gb28181.event.device.RequestTimeoutEvent; |
| 5 | -import com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire.PlatformKeepaliveExpireEvent; | |
| 6 | -import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformCycleRegisterEvent; | |
| 7 | -import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformNotRegisterEvent; | |
| 8 | 5 | import com.genersoft.iot.vmp.gb28181.event.record.RecordEndEvent; |
| 9 | 6 | import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; |
| 10 | 7 | import com.genersoft.iot.vmp.media.zlm.event.ZLMOfflineEvent; |
| ... | ... | @@ -31,36 +28,6 @@ public class EventPublisher { |
| 31 | 28 | |
| 32 | 29 | @Autowired |
| 33 | 30 | private ApplicationEventPublisher applicationEventPublisher; |
| 34 | - | |
| 35 | - /** | |
| 36 | - * 平台心跳到期事件 | |
| 37 | - * @param platformGbId | |
| 38 | - */ | |
| 39 | - public void platformKeepaliveExpireEventPublish(String platformGbId){ | |
| 40 | - PlatformKeepaliveExpireEvent platformKeepaliveExpireEvent = new PlatformKeepaliveExpireEvent(this); | |
| 41 | - platformKeepaliveExpireEvent.setPlatformGbID(platformGbId); | |
| 42 | - applicationEventPublisher.publishEvent(platformKeepaliveExpireEvent); | |
| 43 | - } | |
| 44 | - | |
| 45 | - /** | |
| 46 | - * 平台未注册事件 | |
| 47 | - * @param platformGbId | |
| 48 | - */ | |
| 49 | - public void platformNotRegisterEventPublish(String platformGbId){ | |
| 50 | - PlatformNotRegisterEvent platformNotRegisterEvent = new PlatformNotRegisterEvent(this); | |
| 51 | - platformNotRegisterEvent.setPlatformGbID(platformGbId); | |
| 52 | - applicationEventPublisher.publishEvent(platformNotRegisterEvent); | |
| 53 | - } | |
| 54 | - | |
| 55 | - /** | |
| 56 | - * 平台周期注册事件 | |
| 57 | - * @param paltformGbId | |
| 58 | - */ | |
| 59 | - public void platformRegisterCycleEventPublish(String paltformGbId) { | |
| 60 | - PlatformCycleRegisterEvent platformCycleRegisterEvent = new PlatformCycleRegisterEvent(this); | |
| 61 | - platformCycleRegisterEvent.setPlatformGbID(paltformGbId); | |
| 62 | - applicationEventPublisher.publishEvent(platformCycleRegisterEvent); | |
| 63 | - } | |
| 64 | 31 | |
| 65 | 32 | /** |
| 66 | 33 | * 设备报警事件 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
| ... | ... | @@ -59,9 +59,25 @@ public class SipSubscribe { |
| 59 | 59 | void response(EventResult eventResult); |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | + /** | |
| 63 | + * | |
| 64 | + */ | |
| 65 | + public enum EventResultType{ | |
| 66 | + // 超时 | |
| 67 | + timeout, | |
| 68 | + // 回复 | |
| 69 | + response, | |
| 70 | + // 事务已结束 | |
| 71 | + transactionTerminated, | |
| 72 | + // 会话已结束 | |
| 73 | + dialogTerminated, | |
| 74 | + // 设备未找到 | |
| 75 | + deviceNotFoundEvent | |
| 76 | + } | |
| 77 | + | |
| 62 | 78 | public static class EventResult<EventObject>{ |
| 63 | 79 | public int statusCode; |
| 64 | - public String type; | |
| 80 | + public EventResultType type; | |
| 65 | 81 | public String msg; |
| 66 | 82 | public String callId; |
| 67 | 83 | public Dialog dialog; |
| ... | ... | @@ -76,7 +92,7 @@ public class SipSubscribe { |
| 76 | 92 | ResponseEvent responseEvent = (ResponseEvent)event; |
| 77 | 93 | Response response = responseEvent.getResponse(); |
| 78 | 94 | this.dialog = responseEvent.getDialog(); |
| 79 | - this.type = "response"; | |
| 95 | + this.type = EventResultType.response; | |
| 80 | 96 | if (response != null) { |
| 81 | 97 | this.msg = response.getReasonPhrase(); |
| 82 | 98 | this.statusCode = response.getStatusCode(); |
| ... | ... | @@ -85,28 +101,28 @@ public class SipSubscribe { |
| 85 | 101 | |
| 86 | 102 | }else if (event instanceof TimeoutEvent) { |
| 87 | 103 | TimeoutEvent timeoutEvent = (TimeoutEvent)event; |
| 88 | - this.type = "timeout"; | |
| 104 | + this.type = EventResultType.timeout; | |
| 89 | 105 | this.msg = "消息超时未回复"; |
| 90 | 106 | this.statusCode = -1024; |
| 91 | 107 | this.dialog = timeoutEvent.getClientTransaction().getDialog(); |
| 92 | 108 | this.callId = this.dialog != null?timeoutEvent.getClientTransaction().getDialog().getCallId().getCallId(): null; |
| 93 | 109 | }else if (event instanceof TransactionTerminatedEvent) { |
| 94 | 110 | TransactionTerminatedEvent transactionTerminatedEvent = (TransactionTerminatedEvent)event; |
| 95 | - this.type = "transactionTerminated"; | |
| 111 | + this.type = EventResultType.transactionTerminated; | |
| 96 | 112 | this.msg = "事务已结束"; |
| 97 | 113 | this.statusCode = -1024; |
| 98 | 114 | this.callId = transactionTerminatedEvent.getClientTransaction().getDialog().getCallId().getCallId(); |
| 99 | 115 | this.dialog = transactionTerminatedEvent.getClientTransaction().getDialog(); |
| 100 | 116 | }else if (event instanceof DialogTerminatedEvent) { |
| 101 | 117 | DialogTerminatedEvent dialogTerminatedEvent = (DialogTerminatedEvent)event; |
| 102 | - this.type = "dialogTerminated"; | |
| 118 | + this.type = EventResultType.dialogTerminated; | |
| 103 | 119 | this.msg = "会话已结束"; |
| 104 | 120 | this.statusCode = -1024; |
| 105 | 121 | this.callId = dialogTerminatedEvent.getDialog().getCallId().getCallId(); |
| 106 | 122 | this.dialog = dialogTerminatedEvent.getDialog(); |
| 107 | 123 | }else if (event instanceof DeviceNotFoundEvent) { |
| 108 | 124 | DeviceNotFoundEvent deviceNotFoundEvent = (DeviceNotFoundEvent)event; |
| 109 | - this.type = "deviceNotFoundEvent"; | |
| 125 | + this.type = EventResultType.deviceNotFoundEvent; | |
| 110 | 126 | this.msg = "设备未找到"; |
| 111 | 127 | this.statusCode = -1024; |
| 112 | 128 | this.dialog = deviceNotFoundEvent.getDialog(); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEvent.java deleted
100644 → 0
| 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 | - /** | |
| 11 | - * Add default serial version ID | |
| 12 | - */ | |
| 13 | - private static final long serialVersionUID = 1L; | |
| 14 | - | |
| 15 | - private String platformGbID; | |
| 16 | - | |
| 17 | - public PlatformKeepaliveExpireEvent(Object source) { | |
| 18 | - super(source); | |
| 19 | - } | |
| 20 | - | |
| 21 | - public String getPlatformGbID() { | |
| 22 | - return platformGbID; | |
| 23 | - } | |
| 24 | - | |
| 25 | - public void setPlatformGbID(String platformGbID) { | |
| 26 | - this.platformGbID = platformGbID; | |
| 27 | - } | |
| 28 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEventLister.java deleted
100644 → 0
| 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.event.EventPublisher; | |
| 6 | -import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | |
| 7 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | |
| 8 | -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | |
| 9 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; | |
| 10 | -import org.jetbrains.annotations.NotNull; | |
| 11 | -import org.slf4j.Logger; | |
| 12 | -import org.slf4j.LoggerFactory; | |
| 13 | -import org.springframework.beans.factory.annotation.Autowired; | |
| 14 | -import org.springframework.context.ApplicationListener; | |
| 15 | -import org.springframework.stereotype.Component; | |
| 16 | - | |
| 17 | -import javax.sip.message.Response; | |
| 18 | - | |
| 19 | -/** | |
| 20 | - * @description: 平台心跳超时事件 | |
| 21 | - * @author: panll | |
| 22 | - * @date: 2020年11月5日 10:00 | |
| 23 | - */ | |
| 24 | -@Component | |
| 25 | -public class PlatformKeepaliveExpireEventLister implements ApplicationListener<PlatformKeepaliveExpireEvent> { | |
| 26 | - | |
| 27 | - | |
| 28 | - private final static Logger logger = LoggerFactory.getLogger(PlatformKeepaliveExpireEventLister.class); | |
| 29 | - | |
| 30 | - @Autowired | |
| 31 | - private IVideoManagerStorage storager; | |
| 32 | - | |
| 33 | - @Autowired | |
| 34 | - private IRedisCatchStorage redisCatchStorage; | |
| 35 | - | |
| 36 | - @Autowired | |
| 37 | - private ISIPCommanderForPlatform sipCommanderForPlatform; | |
| 38 | - | |
| 39 | - @Autowired | |
| 40 | - private SipSubscribe sipSubscribe; | |
| 41 | - | |
| 42 | - @Autowired | |
| 43 | - private EventPublisher publisher; | |
| 44 | - | |
| 45 | - @Override | |
| 46 | - public void onApplicationEvent(@NotNull PlatformKeepaliveExpireEvent event) { | |
| 47 | - | |
| 48 | - if (logger.isDebugEnabled()) { | |
| 49 | - logger.debug("平台心跳到期事件事件触发,平台国标ID:" + event.getPlatformGbID()); | |
| 50 | - } | |
| 51 | - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(event.getPlatformGbID()); | |
| 52 | - ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(event.getPlatformGbID()); | |
| 53 | - if (parentPlatformCatch == null) { | |
| 54 | - return; | |
| 55 | - } | |
| 56 | - if (parentPlatform == null) { | |
| 57 | - logger.debug("平台心跳到期事件事件触发,但平台已经删除!!! 平台国标ID:" + event.getPlatformGbID()); | |
| 58 | - return; | |
| 59 | - } | |
| 60 | - parentPlatformCatch.setParentPlatform(parentPlatform); | |
| 61 | - // 发送心跳 | |
| 62 | - if (parentPlatformCatch.getKeepAliveReply() >= 3) { | |
| 63 | - // 有3次未收到心跳回复, 设置平台状态为离线, 开始重新注册 | |
| 64 | - logger.warn("有3次未收到心跳回复,标记设置平台状态为离线, 并重新注册 平台国标ID:" + event.getPlatformGbID()); | |
| 65 | - storager.updateParentPlatformStatus(event.getPlatformGbID(), false); | |
| 66 | - publisher.platformNotRegisterEventPublish(event.getPlatformGbID()); | |
| 67 | - parentPlatformCatch.setKeepAliveReply(0); | |
| 68 | - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | |
| 69 | - }else { | |
| 70 | - // 再次发送心跳 | |
| 71 | - String callId = sipCommanderForPlatform.keepalive(parentPlatform); | |
| 72 | - | |
| 73 | - parentPlatformCatch.setKeepAliveReply( parentPlatformCatch.getKeepAliveReply() + 1); | |
| 74 | - // 存储心跳信息, 并设置状态为未回复, 如果多次过期仍未收到回复,则认为上级平台已经离线 | |
| 75 | - redisCatchStorage.updatePlatformKeepalive(parentPlatform); | |
| 76 | - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | |
| 77 | - | |
| 78 | - sipSubscribe.addOkSubscribe(callId, (SipSubscribe.EventResult eventResult) ->{ | |
| 79 | - if (eventResult.statusCode == Response.OK) { | |
| 80 | - // 收到心跳响应信息, | |
| 81 | - parentPlatformCatch.setKeepAliveReply(0); | |
| 82 | - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | |
| 83 | - } | |
| 84 | - } ); | |
| 85 | - } | |
| 86 | - } | |
| 87 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformCycleRegisterEvent.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.event.platformNotRegister; | |
| 2 | - | |
| 3 | -import org.springframework.context.ApplicationEvent; | |
| 4 | - | |
| 5 | -public class PlatformCycleRegisterEvent extends ApplicationEvent { | |
| 6 | - /** | |
| 7 | - * Add default serial version ID | |
| 8 | - */ | |
| 9 | - private static final long serialVersionUID = 1L; | |
| 10 | - | |
| 11 | - private String platformGbID; | |
| 12 | - | |
| 13 | - public String getPlatformGbID() { | |
| 14 | - return platformGbID; | |
| 15 | - } | |
| 16 | - | |
| 17 | - public void setPlatformGbID(String platformGbID) { | |
| 18 | - this.platformGbID = platformGbID; | |
| 19 | - } | |
| 20 | - | |
| 21 | - public PlatformCycleRegisterEvent(Object source) { | |
| 22 | - super(source); | |
| 23 | - } | |
| 24 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformCycleRegisterEventLister.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.event.platformNotRegister; | |
| 2 | - | |
| 3 | -import com.genersoft.iot.vmp.conf.DynamicTask; | |
| 4 | -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 5 | -import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | |
| 6 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | |
| 7 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; | |
| 8 | -import org.slf4j.Logger; | |
| 9 | -import org.slf4j.LoggerFactory; | |
| 10 | -import org.springframework.beans.factory.annotation.Autowired; | |
| 11 | -import org.springframework.context.ApplicationListener; | |
| 12 | -import org.springframework.stereotype.Component; | |
| 13 | - | |
| 14 | -import java.util.Timer; | |
| 15 | -import java.util.TimerTask; | |
| 16 | - | |
| 17 | -@Component | |
| 18 | -public class PlatformCycleRegisterEventLister implements ApplicationListener<PlatformCycleRegisterEvent> { | |
| 19 | - | |
| 20 | - private final static Logger logger = LoggerFactory.getLogger(PlatformCycleRegisterEventLister.class); | |
| 21 | - | |
| 22 | - @Autowired | |
| 23 | - private IVideoManagerStorage storager; | |
| 24 | - @Autowired | |
| 25 | - private ISIPCommanderForPlatform sipCommanderFroPlatform; | |
| 26 | - @Autowired | |
| 27 | - private DynamicTask dynamicTask; | |
| 28 | - | |
| 29 | - @Override | |
| 30 | - public void onApplicationEvent(PlatformCycleRegisterEvent event) { | |
| 31 | - logger.info("上级平台周期注册事件"); | |
| 32 | - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(event.getPlatformGbID()); | |
| 33 | - if (parentPlatform == null) { | |
| 34 | - logger.info("[ 平台未注册事件 ] 平台已经删除!!! 平台国标ID:" + event.getPlatformGbID()); | |
| 35 | - return; | |
| 36 | - } | |
| 37 | - String taskKey = "platform-cycle-register" + parentPlatform.getServerGBId();; | |
| 38 | - SipSubscribe.Event okEvent = (responseEvent)->{ | |
| 39 | - dynamicTask.stop(taskKey); | |
| 40 | - }; | |
| 41 | - dynamicTask.startCron(taskKey, ()->{ | |
| 42 | - logger.info("[平台注册]再次向平台注册,平台国标ID:" + event.getPlatformGbID()); | |
| 43 | - sipCommanderFroPlatform.register(parentPlatform, null, okEvent); | |
| 44 | - }, Integer.parseInt(parentPlatform.getExpires())* 1000); | |
| 45 | - } | |
| 46 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEvent.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.event.platformNotRegister; | |
| 2 | - | |
| 3 | -import org.springframework.context.ApplicationEvent; | |
| 4 | - | |
| 5 | -public class PlatformNotRegisterEvent extends ApplicationEvent { | |
| 6 | - | |
| 7 | - /** | |
| 8 | - * Add default serial version ID | |
| 9 | - */ | |
| 10 | - private static final long serialVersionUID = 1L; | |
| 11 | - | |
| 12 | - private String platformGbID; | |
| 13 | - | |
| 14 | - public PlatformNotRegisterEvent(Object source) { | |
| 15 | - super(source); | |
| 16 | - } | |
| 17 | - | |
| 18 | - public String getPlatformGbID() { | |
| 19 | - return platformGbID; | |
| 20 | - } | |
| 21 | - | |
| 22 | - public void setPlatformGbID(String platformGbID) { | |
| 23 | - this.platformGbID = platformGbID; | |
| 24 | - } | |
| 25 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.event.platformNotRegister; | |
| 2 | - | |
| 3 | -import com.genersoft.iot.vmp.conf.DynamicTask; | |
| 4 | -import com.genersoft.iot.vmp.conf.SipConfig; | |
| 5 | -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 6 | -import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | |
| 7 | -import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | |
| 8 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; | |
| 9 | -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | |
| 10 | -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | |
| 11 | -import com.genersoft.iot.vmp.service.IMediaServerService; | |
| 12 | -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | |
| 13 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; | |
| 14 | -import org.slf4j.Logger; | |
| 15 | -import org.slf4j.LoggerFactory; | |
| 16 | -import org.springframework.beans.factory.annotation.Autowired; | |
| 17 | -import org.springframework.context.ApplicationListener; | |
| 18 | -import org.springframework.stereotype.Component; | |
| 19 | - | |
| 20 | -import java.util.*; | |
| 21 | - | |
| 22 | -/** | |
| 23 | - * @description: 平台未注册事件,来源有二: | |
| 24 | - * 1、平台新添加 | |
| 25 | - * 2、平台心跳超时 | |
| 26 | - * @author: panll | |
| 27 | - * @date: 2020年11月24日 10:00 | |
| 28 | - */ | |
| 29 | -@Component | |
| 30 | -public class PlatformNotRegisterEventLister implements ApplicationListener<PlatformNotRegisterEvent> { | |
| 31 | - | |
| 32 | - private final static Logger logger = LoggerFactory.getLogger(PlatformNotRegisterEventLister.class); | |
| 33 | - | |
| 34 | - @Autowired | |
| 35 | - private IVideoManagerStorage storager; | |
| 36 | - @Autowired | |
| 37 | - private IRedisCatchStorage redisCatchStorage; | |
| 38 | - @Autowired | |
| 39 | - private IMediaServerService mediaServerService; | |
| 40 | - | |
| 41 | - @Autowired | |
| 42 | - private SIPCommanderFroPlatform sipCommanderFroPlatform; | |
| 43 | - | |
| 44 | - @Autowired | |
| 45 | - private ZLMRTPServerFactory zlmrtpServerFactory; | |
| 46 | - | |
| 47 | - @Autowired | |
| 48 | - private SipConfig config; | |
| 49 | - | |
| 50 | - @Autowired | |
| 51 | - private DynamicTask dynamicTask; | |
| 52 | - | |
| 53 | - // @Autowired | |
| 54 | - // private RedisUtil redis; | |
| 55 | - | |
| 56 | - @Override | |
| 57 | - public void onApplicationEvent(PlatformNotRegisterEvent event) { | |
| 58 | - | |
| 59 | - logger.info("[ 平台未注册事件 ]平台国标ID:" + event.getPlatformGbID()); | |
| 60 | - | |
| 61 | - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(event.getPlatformGbID()); | |
| 62 | - if (parentPlatform == null) { | |
| 63 | - logger.info("[ 平台未注册事件 ] 平台已经删除!!! 平台国标ID:" + event.getPlatformGbID()); | |
| 64 | - return; | |
| 65 | - } | |
| 66 | - // 查询是否有推流, 如果有则都停止 | |
| 67 | - List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServer(event.getPlatformGbID()); | |
| 68 | - if (sendRtpItems != null && sendRtpItems.size() > 0) { | |
| 69 | - logger.info("[ 平台未注册事件 ] 停止[ {} ]的所有推流", event.getPlatformGbID()); | |
| 70 | - for (SendRtpItem sendRtpItem : sendRtpItems) { | |
| 71 | - redisCatchStorage.deleteSendRTPServer(event.getPlatformGbID(), sendRtpItem.getChannelId(), null, null); | |
| 72 | - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | |
| 73 | - Map<String, Object> param = new HashMap<>(); | |
| 74 | - param.put("vhost", "__defaultVhost__"); | |
| 75 | - param.put("app", sendRtpItem.getApp()); | |
| 76 | - param.put("stream", sendRtpItem.getStreamId()); | |
| 77 | - zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); | |
| 78 | - } | |
| 79 | - | |
| 80 | - } | |
| 81 | - String taskKey = "platform-not-register-" + parentPlatform.getServerGBId(); | |
| 82 | - SipSubscribe.Event okEvent = (responseEvent)->{ | |
| 83 | - dynamicTask.stop(taskKey); | |
| 84 | - }; | |
| 85 | - dynamicTask.startCron(taskKey, ()->{ | |
| 86 | - logger.info("[平台注册]再次向平台注册,平台国标ID:" + event.getPlatformGbID()); | |
| 87 | - sipCommanderFroPlatform.register(parentPlatform, null, okEvent); | |
| 88 | - }, config.getRegisterTimeInterval()* 1000); | |
| 89 | - } | |
| 90 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java
| ... | ... | @@ -30,24 +30,11 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> { |
| 30 | 30 | |
| 31 | 31 | @Autowired |
| 32 | 32 | private IVideoManagerStorage storager; |
| 33 | - @Autowired | |
| 34 | - private IRedisCatchStorage redisCatchStorage; | |
| 35 | - @Autowired | |
| 36 | - private IMediaServerService mediaServerService; | |
| 37 | 33 | |
| 38 | 34 | @Autowired |
| 39 | 35 | private SIPCommanderFroPlatform sipCommanderFroPlatform; |
| 40 | 36 | |
| 41 | 37 | @Autowired |
| 42 | - private ZLMRTPServerFactory zlmrtpServerFactory; | |
| 43 | - | |
| 44 | - @Autowired | |
| 45 | - private SipConfig config; | |
| 46 | - | |
| 47 | - @Autowired | |
| 48 | - private UserSetting userSetting; | |
| 49 | - | |
| 50 | - @Autowired | |
| 51 | 38 | private IGbStreamService gbStreamService; |
| 52 | 39 | |
| 53 | 40 | @Autowired | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java
| ... | ... | @@ -60,7 +60,6 @@ public class MobilePositionSubscribeHandlerTask implements ISubscribeTask { |
| 60 | 60 | // TODO 暂时只处理视频流的回复,后续增加对国标设备的支持 |
| 61 | 61 | List<DeviceChannel> gbStreams = storager.queryGbStreamListInPlatform(platform.getServerGBId()); |
| 62 | 62 | if (gbStreams.size() == 0) { |
| 63 | - logger.info("发送订阅时发现平台已经没有关联的直播流:{}", platform.getServerGBId()); | |
| 64 | 63 | return; |
| 65 | 64 | } |
| 66 | 65 | for (DeviceChannel deviceChannel : gbStreams) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java
| ... | ... | @@ -71,7 +71,6 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { |
| 71 | 71 | @Override |
| 72 | 72 | @Async |
| 73 | 73 | public void processRequest(RequestEvent requestEvent) { |
| 74 | - logger.debug("\n收到请求:\n{}", requestEvent.getRequest()); | |
| 75 | 74 | String method = requestEvent.getRequest().getMethod(); |
| 76 | 75 | ISIPRequestProcessor sipRequestProcessor = requestProcessorMap.get(method); |
| 77 | 76 | if (sipRequestProcessor == null) { |
| ... | ... | @@ -90,7 +89,6 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { |
| 90 | 89 | @Async |
| 91 | 90 | public void processResponse(ResponseEvent responseEvent) { |
| 92 | 91 | Response response = responseEvent.getResponse(); |
| 93 | - logger.debug("\n收到响应:\n{}", responseEvent.getResponse()); | |
| 94 | 92 | int status = response.getStatusCode(); |
| 95 | 93 | |
| 96 | 94 | if (((status >= 200) && (status < 300)) || status == Response.UNAUTHORIZED) { // Success! |
| ... | ... | @@ -114,7 +112,7 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { |
| 114 | 112 | } else if ((status >= 100) && (status < 200)) { |
| 115 | 113 | // 增加其它无需回复的响应,如101、180等 |
| 116 | 114 | } else { |
| 117 | - logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/); | |
| 115 | + logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()); | |
| 118 | 116 | if (responseEvent.getResponse() != null && sipSubscribe.getErrorSubscribesSize() > 0 ) { |
| 119 | 117 | CallIdHeader callIdHeader = (CallIdHeader)responseEvent.getResponse().getHeader(CallIdHeader.NAME); |
| 120 | 118 | if (callIdHeader != null) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
| ... | ... | @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; |
| 3 | 3 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 4 | 4 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 6 | -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | |
| 6 | +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; | |
| 7 | 7 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 8 | 8 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| 9 | 9 | import gov.nist.javax.sip.message.SIPRequest; |
| ... | ... | @@ -98,7 +98,7 @@ public interface ISIPCommander { |
| 98 | 98 | * @param device 视频设备 |
| 99 | 99 | * @param channelId 预览通道 |
| 100 | 100 | */ |
| 101 | - void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent); | |
| 101 | + void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent); | |
| 102 | 102 | |
| 103 | 103 | /** |
| 104 | 104 | * 请求回放视频流 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
| ... | ... | @@ -15,7 +15,7 @@ public interface ISIPCommanderForPlatform { |
| 15 | 15 | * @return |
| 16 | 16 | */ |
| 17 | 17 | boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent); |
| 18 | - boolean register(ParentPlatform parentPlatform, String callId, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain); | |
| 18 | + boolean register(ParentPlatform parentPlatform, String callId, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister); | |
| 19 | 19 | |
| 20 | 20 | /** |
| 21 | 21 | * 向上级平台注销 |
| ... | ... | @@ -30,7 +30,7 @@ public interface ISIPCommanderForPlatform { |
| 30 | 30 | * @param parentPlatform |
| 31 | 31 | * @return callId(作为接受回复的判定) |
| 32 | 32 | */ |
| 33 | - String keepalive(ParentPlatform parentPlatform); | |
| 33 | + String keepalive(ParentPlatform parentPlatform,SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent); | |
| 34 | 34 | |
| 35 | 35 | |
| 36 | 36 | /** | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
| ... | ... | @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; |
| 3 | 3 | import com.genersoft.iot.vmp.conf.SipConfig; |
| 4 | 4 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo; |
| 6 | +import com.genersoft.iot.vmp.gb28181.utils.HeaderUtils; | |
| 6 | 7 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 7 | 8 | import gov.nist.javax.sip.message.MessageFactoryImpl; |
| 8 | 9 | import org.springframework.beans.factory.annotation.Autowired; |
| ... | ... | @@ -75,7 +76,7 @@ public class SIPRequestHeaderPlarformProvider { |
| 75 | 76 | } |
| 76 | 77 | |
| 77 | 78 | |
| 78 | - public Request createRegisterRequest(@NotNull ParentPlatform platform, long CSeq, String fromTag, String viaTag, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException { | |
| 79 | + public Request createRegisterRequest(@NotNull ParentPlatform platform, long CSeq, String fromTag, String viaTag, CallIdHeader callIdHeader, boolean isRegister) throws ParseException, InvalidArgumentException, PeerUnavailableException { | |
| 79 | 80 | Request request = null; |
| 80 | 81 | String sipAddress = sipConfig.getIp() + ":" + sipConfig.getPort(); |
| 81 | 82 | //请求行 |
| ... | ... | @@ -109,18 +110,20 @@ public class SIPRequestHeaderPlarformProvider { |
| 109 | 110 | .createSipURI(platform.getDeviceGBId(), sipAddress)); |
| 110 | 111 | request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); |
| 111 | 112 | |
| 112 | - ExpiresHeader expires = sipFactory.createHeaderFactory().createExpiresHeader(Integer.parseInt(platform.getExpires())); | |
| 113 | + ExpiresHeader expires = sipFactory.createHeaderFactory().createExpiresHeader(isRegister ? platform.getExpires() : 0); | |
| 113 | 114 | request.addHeader(expires); |
| 114 | 115 | |
| 116 | + UserAgentHeader userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory); | |
| 117 | + request.addHeader(userAgentHeader); | |
| 115 | 118 | |
| 116 | 119 | return request; |
| 117 | 120 | } |
| 118 | 121 | |
| 119 | 122 | public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, String fromTag, String viaTag, |
| 120 | - String callId, WWWAuthenticateHeader www , CallIdHeader callIdHeader) throws ParseException, PeerUnavailableException, InvalidArgumentException { | |
| 123 | + String callId, WWWAuthenticateHeader www , CallIdHeader callIdHeader, boolean isRegister) throws ParseException, PeerUnavailableException, InvalidArgumentException { | |
| 121 | 124 | |
| 122 | 125 | |
| 123 | - Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(), fromTag, viaTag, callIdHeader); | |
| 126 | + Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(), fromTag, viaTag, callIdHeader, isRegister); | |
| 124 | 127 | SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); |
| 125 | 128 | if (www == null) { |
| 126 | 129 | AuthorizationHeader authorizationHeader = sipFactory.createHeaderFactory().createAuthorizationHeader("Digest"); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
| ... | ... | @@ -12,6 +12,7 @@ import javax.sip.message.Request; |
| 12 | 12 | |
| 13 | 13 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 14 | 14 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 15 | +import com.genersoft.iot.vmp.gb28181.utils.HeaderUtils; | |
| 15 | 16 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 16 | 17 | import gov.nist.javax.sip.SipProviderImpl; |
| 17 | 18 | import gov.nist.javax.sip.SipStackImpl; |
| ... | ... | @@ -266,15 +267,7 @@ public class SIPRequestHeaderProvider { |
| 266 | 267 | Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory() |
| 267 | 268 | .createSipURI(sipConfig.getId(), sipConfig.getIp() + ":" + sipConfig.getPort())); |
| 268 | 269 | infoRequest.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); |
| 269 | - List<String> agentParam = new ArrayList<>(); | |
| 270 | - agentParam.add("wvp-pro"); | |
| 271 | - // TODO 添加版本信息以及日期 | |
| 272 | - UserAgentHeader userAgentHeader = null; | |
| 273 | - try { | |
| 274 | - userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); | |
| 275 | - } catch (ParseException e) { | |
| 276 | - throw new RuntimeException(e); | |
| 277 | - } | |
| 270 | + UserAgentHeader userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory); | |
| 278 | 271 | infoRequest.addHeader(userAgentHeader); |
| 279 | 272 | |
| 280 | 273 | ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| ... | ... | @@ -10,12 +10,12 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 10 | 10 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 11 | 11 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
| 12 | 12 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; |
| 13 | +import com.genersoft.iot.vmp.gb28181.utils.HeaderUtils; | |
| 13 | 14 | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; |
| 14 | 15 | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; |
| 15 | -import com.genersoft.iot.vmp.media.zlm.dto.HookType; | |
| 16 | 16 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 17 | 17 | import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; |
| 18 | -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | |
| 18 | +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; | |
| 19 | 19 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 20 | 20 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 21 | 21 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| ... | ... | @@ -33,19 +33,15 @@ import org.springframework.beans.factory.annotation.Qualifier; |
| 33 | 33 | import org.springframework.context.annotation.DependsOn; |
| 34 | 34 | import org.springframework.stereotype.Component; |
| 35 | 35 | import org.springframework.util.ObjectUtils; |
| 36 | -import org.springframework.util.StringUtils; | |
| 37 | 36 | |
| 38 | 37 | import javax.sip.*; |
| 39 | 38 | import javax.sip.address.Address; |
| 40 | 39 | import javax.sip.address.SipURI; |
| 41 | -import javax.sip.address.URI; | |
| 42 | 40 | import javax.sip.header.*; |
| 43 | 41 | import javax.sip.message.Request; |
| 44 | 42 | import java.lang.reflect.Field; |
| 45 | 43 | import java.text.ParseException; |
| 46 | -import java.util.ArrayList; | |
| 47 | 44 | import java.util.HashSet; |
| 48 | -import java.util.List; | |
| 49 | 45 | |
| 50 | 46 | /** |
| 51 | 47 | * @description:设备能力接口,用于定义设备的控制、查询能力 |
| ... | ... | @@ -88,7 +84,7 @@ public class SIPCommander implements ISIPCommander { |
| 88 | 84 | private UserSetting userSetting; |
| 89 | 85 | |
| 90 | 86 | @Autowired |
| 91 | - private ZLMHttpHookSubscribe subscribe; | |
| 87 | + private ZlmHttpHookSubscribe subscribe; | |
| 92 | 88 | |
| 93 | 89 | @Autowired |
| 94 | 90 | private SipSubscribe sipSubscribe; |
| ... | ... | @@ -351,7 +347,7 @@ public class SIPCommander implements ISIPCommander { |
| 351 | 347 | */ |
| 352 | 348 | @Override |
| 353 | 349 | public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, |
| 354 | - ZLMHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) { | |
| 350 | + ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) { | |
| 355 | 351 | String stream = ssrcInfo.getStream(); |
| 356 | 352 | try { |
| 357 | 353 | if (device == null) { |
| ... | ... | @@ -640,7 +636,7 @@ public class SIPCommander implements ISIPCommander { |
| 640 | 636 | hookEvent.call(new InviteStreamInfo(mediaServerItem, json, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream())); |
| 641 | 637 | subscribe.removeSubscribe(hookSubscribe); |
| 642 | 638 | hookSubscribe.getContent().put("regist", false); |
| 643 | - hookSubscribe.getContent().put("schema", "rtmp"); | |
| 639 | + hookSubscribe.getContent().put("schema", "rtsp"); | |
| 644 | 640 | // 添加流注销的订阅,注销了后向设备发送bye |
| 645 | 641 | subscribe.addSubscribe(hookSubscribe, |
| 646 | 642 | (MediaServerItem mediaServerItemForEnd, JSONObject jsonForEnd)->{ |
| ... | ... | @@ -780,15 +776,7 @@ public class SIPCommander implements ISIPCommander { |
| 780 | 776 | // 增加Contact header |
| 781 | 777 | Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort())); |
| 782 | 778 | byeRequest.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); |
| 783 | - List<String> agentParam = new ArrayList<>(); | |
| 784 | - agentParam.add("wvp-pro"); | |
| 785 | - // TODO 添加版本信息以及日期 | |
| 786 | - UserAgentHeader userAgentHeader = null; | |
| 787 | - try { | |
| 788 | - userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); | |
| 789 | - } catch (ParseException e) { | |
| 790 | - throw new RuntimeException(e); | |
| 791 | - } | |
| 779 | + UserAgentHeader userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory); | |
| 792 | 780 | byeRequest.addHeader(userAgentHeader); |
| 793 | 781 | ClientTransaction clientTransaction = null; |
| 794 | 782 | if("TCP".equals(protocol)) { |
| ... | ... | @@ -1680,14 +1668,11 @@ public class SIPCommander implements ISIPCommander { |
| 1680 | 1668 | clientTransaction = udpSipProvider.getNewClientTransaction(request); |
| 1681 | 1669 | } |
| 1682 | 1670 | if (request.getHeader(UserAgentHeader.NAME) == null) { |
| 1683 | - List<String> agentParam = new ArrayList<>(); | |
| 1684 | - agentParam.add("wvp-pro"); | |
| 1685 | - // TODO 添加版本信息以及日期 | |
| 1686 | 1671 | UserAgentHeader userAgentHeader = null; |
| 1687 | 1672 | try { |
| 1688 | - userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); | |
| 1673 | + userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory); | |
| 1689 | 1674 | } catch (ParseException e) { |
| 1690 | - throw new RuntimeException(e); | |
| 1675 | + logger.error("添加UserAgentHeader失败", e); | |
| 1691 | 1676 | } |
| 1692 | 1677 | request.addHeader(userAgentHeader); |
| 1693 | 1678 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
| ... | ... | @@ -4,6 +4,8 @@ import com.genersoft.iot.vmp.gb28181.bean.*; |
| 4 | 4 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 6 | 6 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider; |
| 7 | +import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; | |
| 8 | +import com.genersoft.iot.vmp.utils.DateUtil; | |
| 7 | 9 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 8 | 10 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 9 | 11 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| ... | ... | @@ -75,28 +77,21 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 75 | 77 | |
| 76 | 78 | @Override |
| 77 | 79 | public boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { |
| 78 | - return register(parentPlatform, null, null, errorEvent, okEvent, false); | |
| 80 | + return register(parentPlatform, null, null, errorEvent, okEvent, false, true); | |
| 79 | 81 | } |
| 80 | 82 | |
| 81 | 83 | @Override |
| 82 | 84 | public boolean unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { |
| 83 | - ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); | |
| 84 | - parentPlatform.setExpires("0"); | |
| 85 | - if (parentPlatformCatch != null) { | |
| 86 | - parentPlatformCatch.setParentPlatform(parentPlatform); | |
| 87 | - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | |
| 88 | - } | |
| 89 | - return register(parentPlatform, null, null, errorEvent, okEvent, false); | |
| 85 | + return register(parentPlatform, null, null, errorEvent, okEvent, false, false); | |
| 90 | 86 | } |
| 91 | 87 | |
| 92 | 88 | @Override |
| 93 | 89 | public boolean register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable WWWAuthenticateHeader www, |
| 94 | - SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain) { | |
| 90 | + SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) { | |
| 95 | 91 | try { |
| 96 | 92 | Request request; |
| 97 | 93 | String tm = Long.toString(System.currentTimeMillis()); |
| 98 | 94 | if (!registerAgain ) { |
| 99 | - // //callid | |
| 100 | 95 | CallIdHeader callIdHeader = null; |
| 101 | 96 | if(parentPlatform.getTransport().equals("TCP")) { |
| 102 | 97 | callIdHeader = tcpSipProvider.getNewCallId(); |
| ... | ... | @@ -107,10 +102,10 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 107 | 102 | |
| 108 | 103 | request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, |
| 109 | 104 | redisCatchStorage.getCSEQ(), "FromRegister" + tm, |
| 110 | - "z9hG4bK-" + UUID.randomUUID().toString().replace("-", ""), callIdHeader); | |
| 105 | + "z9hG4bK-" + UUID.randomUUID().toString().replace("-", ""), callIdHeader, isRegister); | |
| 111 | 106 | // 将 callid 写入缓存, 等注册成功可以更新状态 |
| 112 | 107 | String callIdFromHeader = callIdHeader.getCallId(); |
| 113 | - redisCatchStorage.updatePlatformRegisterInfo(callIdFromHeader, parentPlatform.getServerGBId()); | |
| 108 | + redisCatchStorage.updatePlatformRegisterInfo(callIdFromHeader, PlatformRegisterInfo.getInstance(parentPlatform.getServerGBId(), isRegister)); | |
| 114 | 109 | |
| 115 | 110 | sipSubscribe.addErrorSubscribe(callIdHeader.getCallId(), (event)->{ |
| 116 | 111 | if (event != null) { |
| ... | ... | @@ -127,7 +122,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 127 | 122 | }else { |
| 128 | 123 | CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() |
| 129 | 124 | : udpSipProvider.getNewCallId(); |
| 130 | - request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, "FromRegister" + tm, null, callId, www, callIdHeader); | |
| 125 | + request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, "FromRegister" + tm, null, callId, www, callIdHeader, isRegister); | |
| 131 | 126 | } |
| 132 | 127 | |
| 133 | 128 | transmitRequest(parentPlatform, request, null, okEvent); |
| ... | ... | @@ -145,7 +140,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 145 | 140 | } |
| 146 | 141 | |
| 147 | 142 | @Override |
| 148 | - public String keepalive(ParentPlatform parentPlatform) { | |
| 143 | + public String keepalive(ParentPlatform parentPlatform,SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { | |
| 149 | 144 | String callId = null; |
| 150 | 145 | try { |
| 151 | 146 | String characterSet = parentPlatform.getCharacterSet(); |
| ... | ... | @@ -168,7 +163,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 168 | 163 | UUID.randomUUID().toString().replace("-", ""), |
| 169 | 164 | null, |
| 170 | 165 | callIdHeader); |
| 171 | - transmitRequest(parentPlatform, request); | |
| 166 | + transmitRequest(parentPlatform, request, errorEvent, okEvent); | |
| 172 | 167 | callId = callIdHeader.getCallId(); |
| 173 | 168 | } catch (ParseException | InvalidArgumentException | SipException e) { |
| 174 | 169 | e.printStackTrace(); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java
| ... | ... | @@ -59,6 +59,9 @@ public abstract class SIPRequestProcessorParent { |
| 59 | 59 | public ServerTransaction getServerTransaction(RequestEvent evt) { |
| 60 | 60 | Request request = evt.getRequest(); |
| 61 | 61 | ServerTransaction serverTransaction = evt.getServerTransaction(); |
| 62 | + if (serverTransaction != null) { | |
| 63 | + System.out.println(serverTransaction.getState().toString()); | |
| 64 | + } | |
| 62 | 65 | // 判断TCP还是UDP |
| 63 | 66 | boolean isTcp = false; |
| 64 | 67 | ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); |
| ... | ... | @@ -86,6 +89,8 @@ public abstract class SIPRequestProcessorParent { |
| 86 | 89 | logger.error(e.getMessage()); |
| 87 | 90 | } catch (TransactionUnavailableException e) { |
| 88 | 91 | logger.error(e.getMessage()); |
| 92 | + }finally { | |
| 93 | + | |
| 89 | 94 | } |
| 90 | 95 | } |
| 91 | 96 | return serverTransaction; |
| ... | ... | @@ -182,6 +187,10 @@ public abstract class SIPRequestProcessorParent { |
| 182 | 187 | sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost()+":"+sipURI.getPort() |
| 183 | 188 | )); |
| 184 | 189 | response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); |
| 190 | + ServerTransaction serverTransaction = getServerTransaction(evt); | |
| 191 | + if (serverTransaction == null) { | |
| 192 | + | |
| 193 | + } | |
| 185 | 194 | getServerTransaction(evt).sendResponse(response); |
| 186 | 195 | } |
| 187 | 196 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
| ... | ... | @@ -4,12 +4,14 @@ import com.alibaba.fastjson.JSONObject; |
| 4 | 4 | import com.genersoft.iot.vmp.conf.DynamicTask; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 6 | 6 | import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; |
| 7 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 8 | +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | |
| 7 | 9 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| 8 | 10 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
| 9 | 11 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 10 | 12 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; |
| 11 | 13 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| 12 | -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | |
| 14 | +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; | |
| 13 | 15 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 14 | 16 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 15 | 17 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| ... | ... | @@ -66,7 +68,7 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In |
| 66 | 68 | private IMediaServerService mediaServerService; |
| 67 | 69 | |
| 68 | 70 | @Autowired |
| 69 | - private ZLMHttpHookSubscribe subscribe; | |
| 71 | + private ZlmHttpHookSubscribe subscribe; | |
| 70 | 72 | |
| 71 | 73 | @Autowired |
| 72 | 74 | private DynamicTask dynamicTask; | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
| ... | ... | @@ -19,7 +19,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; |
| 19 | 19 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; |
| 20 | 20 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| 21 | 21 | import com.genersoft.iot.vmp.gb28181.utils.SipUtils; |
| 22 | -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | |
| 22 | +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; | |
| 23 | 23 | import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; |
| 24 | 24 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 25 | 25 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| ... | ... | @@ -50,7 +50,6 @@ import org.springframework.stereotype.Component; |
| 50 | 50 | |
| 51 | 51 | import javax.sdp.*; |
| 52 | 52 | import javax.sip.*; |
| 53 | -import javax.sip.address.SipURI; | |
| 54 | 53 | import javax.sip.header.CallIdHeader; |
| 55 | 54 | import javax.sip.message.Request; |
| 56 | 55 | import javax.sip.message.Response; |
| ... | ... | @@ -337,7 +336,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 337 | 336 | |
| 338 | 337 | Long finalStartTime = startTime; |
| 339 | 338 | Long finalStopTime = stopTime; |
| 340 | - ZLMHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON) -> { | |
| 339 | + ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON) -> { | |
| 341 | 340 | String app = responseJSON.getString("app"); |
| 342 | 341 | String stream = responseJSON.getString("stream"); |
| 343 | 342 | logger.info("[上级点播]下级已经开始推流。 回复200OK(SDP), {}/{}", app, stream); |
| ... | ... | @@ -440,6 +439,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 440 | 439 | streamId = String.format("%s_%s", device.getDeviceId(), channelId); |
| 441 | 440 | } |
| 442 | 441 | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false); |
| 442 | + logger.info(JSONObject.toJSONString(ssrcInfo)); | |
| 443 | 443 | sendRtpItem.setStreamId(ssrcInfo.getStream()); |
| 444 | 444 | // 写入redis, 超时时回复 |
| 445 | 445 | redisCatchStorage.updateSendRTPSever(sendRtpItem); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java
| ... | ... | @@ -180,7 +180,6 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme |
| 180 | 180 | |
| 181 | 181 | private void processNotifyCatalogList(RequestEvent evt, Element rootElement) throws SipException { |
| 182 | 182 | |
| 183 | - System.out.println(evt.getRequest().toString()); | |
| 184 | 183 | String platformId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); |
| 185 | 184 | String deviceId = XmlUtil.getText(rootElement, "DeviceID"); |
| 186 | 185 | ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java
| ... | ... | @@ -164,7 +164,7 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme |
| 164 | 164 | } |
| 165 | 165 | } |
| 166 | 166 | |
| 167 | - if (channelId.equals(sipConfig.getId())) { | |
| 167 | + if ("7".equals(deviceAlarm.getAlarmMethod()) ) { | |
| 168 | 168 | // 发送给平台的报警信息。 发送redis通知 |
| 169 | 169 | AlarmChannelMessage alarmChannelMessage = new AlarmChannelMessage(); |
| 170 | 170 | alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod())); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java
| ... | ... | @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; |
| 6 | 6 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 7 | 7 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| 8 | 8 | import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract; |
| 9 | +import com.genersoft.iot.vmp.gb28181.utils.HeaderUtils; | |
| 9 | 10 | import gov.nist.javax.sip.ResponseEventExt; |
| 10 | 11 | import gov.nist.javax.sip.message.SIPResponse; |
| 11 | 12 | import gov.nist.javax.sip.stack.SIPDialog; |
| ... | ... | @@ -103,15 +104,7 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract { |
| 103 | 104 | } |
| 104 | 105 | requestURI.setPort(event.getRemotePort()); |
| 105 | 106 | reqAck.setRequestURI(requestURI); |
| 106 | - List<String> agentParam = new ArrayList<>(); | |
| 107 | - agentParam.add("wvp-pro"); | |
| 108 | - // TODO 添加版本信息以及日期 | |
| 109 | - UserAgentHeader userAgentHeader = null; | |
| 110 | - try { | |
| 111 | - userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); | |
| 112 | - } catch (ParseException e) { | |
| 113 | - throw new RuntimeException(e); | |
| 114 | - } | |
| 107 | + UserAgentHeader userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory); | |
| 115 | 108 | reqAck.addHeader(userAgentHeader); |
| 116 | 109 | Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort())); |
| 117 | 110 | reqAck.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java
| ... | ... | @@ -6,8 +6,10 @@ import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; |
| 6 | 6 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| 7 | 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 8 | 8 | import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract; |
| 9 | +import com.genersoft.iot.vmp.service.IPlatformService; | |
| 9 | 10 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 10 | 11 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 12 | +import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; | |
| 11 | 13 | import org.slf4j.Logger; |
| 12 | 14 | import org.slf4j.LoggerFactory; |
| 13 | 15 | import org.springframework.beans.factory.annotation.Autowired; |
| ... | ... | @@ -44,6 +46,9 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { |
| 44 | 46 | @Autowired |
| 45 | 47 | private SubscribeHolder subscribeHolder; |
| 46 | 48 | |
| 49 | + @Autowired | |
| 50 | + private IPlatformService platformService; | |
| 51 | + | |
| 47 | 52 | @Override |
| 48 | 53 | public void afterPropertiesSet() throws Exception { |
| 49 | 54 | // 添加消息处理的订阅 |
| ... | ... | @@ -60,48 +65,39 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { |
| 60 | 65 | Response response = evt.getResponse(); |
| 61 | 66 | CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME); |
| 62 | 67 | String callId = callIdHeader.getCallId(); |
| 63 | - | |
| 64 | - String platformGBId = redisCatchStorage.queryPlatformRegisterInfo(callId); | |
| 65 | - if (platformGBId == null) { | |
| 66 | - logger.info(String.format("未找到callId: %s 的注册/注销平台id", callId )); | |
| 68 | + PlatformRegisterInfo platformRegisterInfo = redisCatchStorage.queryPlatformRegisterInfo(callId); | |
| 69 | + if (platformRegisterInfo == null) { | |
| 70 | + logger.info(String.format("[国标级联]未找到callId: %s 的注册/注销平台id", callId )); | |
| 67 | 71 | return; |
| 68 | 72 | } |
| 69 | 73 | |
| 70 | - ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(platformGBId); | |
| 74 | + ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(platformRegisterInfo.getPlatformId()); | |
| 71 | 75 | if (parentPlatformCatch == null) { |
| 72 | - logger.warn(String.format("[收到注册/注销%S请求]平台:%s,但是平台缓存信息未查询到!!!", response.getStatusCode(),platformGBId)); | |
| 76 | + logger.warn(String.format("[国标级联]收到注册/注销%S请求,平台:%s,但是平台缓存信息未查询到!!!", response.getStatusCode(),platformRegisterInfo.getPlatformId())); | |
| 73 | 77 | return; |
| 74 | 78 | } |
| 75 | - String action = parentPlatformCatch.getParentPlatform().getExpires().equals("0") ? "注销" : "注册"; | |
| 76 | - logger.info(String.format("[%s %S响应]%s ", action, response.getStatusCode(), platformGBId )); | |
| 79 | + | |
| 80 | + String action = platformRegisterInfo.isRegister() ? "注册" : "注销"; | |
| 81 | + logger.info(String.format("[国标级联]%s %S响应,%s ", action, response.getStatusCode(), platformRegisterInfo.getPlatformId() )); | |
| 77 | 82 | ParentPlatform parentPlatform = parentPlatformCatch.getParentPlatform(); |
| 78 | 83 | if (parentPlatform == null) { |
| 79 | - logger.warn(String.format("收到 %s %s的%S请求, 但是平台信息未查询到!!!", platformGBId, action, response.getStatusCode())); | |
| 84 | + logger.warn(String.format("[国标级联]收到 %s %s的%S请求, 但是平台信息未查询到!!!", platformRegisterInfo.getPlatformId(), action, response.getStatusCode())); | |
| 80 | 85 | return; |
| 81 | 86 | } |
| 82 | 87 | |
| 83 | - if (response.getStatusCode() == 401) { | |
| 88 | + if (response.getStatusCode() == Response.UNAUTHORIZED) { | |
| 84 | 89 | WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME); |
| 85 | - sipCommanderForPlatform.register(parentPlatform, callId, www, null, null, true); | |
| 86 | - }else if (response.getStatusCode() == 200){ | |
| 87 | - // 注册/注销成功 | |
| 88 | - logger.info(String.format("%s %s成功", platformGBId, action)); | |
| 89 | - redisCatchStorage.delPlatformRegisterInfo(callId); | |
| 90 | - redisCatchStorage.delPlatformCatchInfo(platformGBId); | |
| 91 | - // 取回Expires设置,避免注销过程中被置为0 | |
| 92 | - ParentPlatform parentPlatformTmp = storager.queryParentPlatByServerGBId(platformGBId); | |
| 93 | - if (parentPlatformTmp != null) { | |
| 94 | - parentPlatformTmp.setStatus("注册".equals(action)); | |
| 95 | - redisCatchStorage.updatePlatformRegister(parentPlatformTmp); | |
| 96 | - redisCatchStorage.updatePlatformKeepalive(parentPlatformTmp); | |
| 97 | - parentPlatformCatch.setParentPlatform(parentPlatformTmp); | |
| 98 | - } | |
| 99 | - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | |
| 100 | - storager.updateParentPlatformStatus(platformGBId, "注册".equals(action)); | |
| 101 | - if ("注销".equals(action)) { | |
| 102 | - subscribeHolder.removeCatalogSubscribe(platformGBId); | |
| 103 | - subscribeHolder.removeMobilePositionSubscribe(platformGBId); | |
| 90 | + sipCommanderForPlatform.register(parentPlatform, callId, www, null, null, true, platformRegisterInfo.isRegister()); | |
| 91 | + }else if (response.getStatusCode() == Response.OK){ | |
| 92 | + | |
| 93 | + if (platformRegisterInfo.isRegister()) { | |
| 94 | + platformService.online(parentPlatform); | |
| 95 | + }else { | |
| 96 | + platformService.offline(parentPlatform); | |
| 104 | 97 | } |
| 98 | + | |
| 99 | + // 注册/注销成功移除缓存的信息 | |
| 100 | + redisCatchStorage.delPlatformRegisterInfo(callId); | |
| 105 | 101 | } |
| 106 | 102 | } |
| 107 | 103 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/utils/HeaderUtils.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.gb28181.utils; | |
| 2 | + | |
| 3 | +import javax.sip.PeerUnavailableException; | |
| 4 | +import javax.sip.SipFactory; | |
| 5 | +import javax.sip.header.UserAgentHeader; | |
| 6 | +import java.text.ParseException; | |
| 7 | +import java.util.ArrayList; | |
| 8 | +import java.util.List; | |
| 9 | + | |
| 10 | +/** | |
| 11 | + * 生成header的工具类 | |
| 12 | + * @author lin | |
| 13 | + */ | |
| 14 | +public class HeaderUtils { | |
| 15 | + | |
| 16 | + public static UserAgentHeader createUserAgentHeader(SipFactory sipFactory) throws PeerUnavailableException, ParseException { | |
| 17 | + List<String> agentParam = new ArrayList<>(); | |
| 18 | + agentParam.add("WVP PRO"); | |
| 19 | + // TODO 添加版本信息以及日期 | |
| 20 | + return sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); | |
| 21 | + } | |
| 22 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java
| ... | ... | @@ -50,7 +50,7 @@ public class AssistRESTfulUtils { |
| 50 | 50 | if (mediaServerItem == null) { |
| 51 | 51 | return null; |
| 52 | 52 | } |
| 53 | - if (ObjectUtils.isEmpty(mediaServerItem.getRecordAssistPort())) { | |
| 53 | + if (mediaServerItem.getRecordAssistPort() > 0) { | |
| 54 | 54 | logger.warn("未启用Assist服务"); |
| 55 | 55 | return null; |
| 56 | 56 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
| ... | ... | @@ -7,12 +7,10 @@ import java.util.Map; |
| 7 | 7 | import com.alibaba.fastjson.JSON; |
| 8 | 8 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 9 | 9 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 10 | -import com.genersoft.iot.vmp.gb28181.bean.Device; | |
| 11 | -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | |
| 12 | -import com.genersoft.iot.vmp.gb28181.bean.GbStream; | |
| 13 | -import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; | |
| 10 | +import com.genersoft.iot.vmp.gb28181.bean.*; | |
| 14 | 11 | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| 15 | 12 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 13 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; | |
| 16 | 14 | import com.genersoft.iot.vmp.media.zlm.dto.*; |
| 17 | 15 | import com.genersoft.iot.vmp.service.*; |
| 18 | 16 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| ... | ... | @@ -20,10 +18,11 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 20 | 18 | import org.slf4j.Logger; |
| 21 | 19 | import org.slf4j.LoggerFactory; |
| 22 | 20 | import org.springframework.beans.factory.annotation.Autowired; |
| 21 | +import org.springframework.beans.factory.annotation.Qualifier; | |
| 23 | 22 | import org.springframework.http.HttpStatus; |
| 24 | 23 | import org.springframework.http.ResponseEntity; |
| 24 | +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; | |
| 25 | 25 | import org.springframework.util.ObjectUtils; |
| 26 | -import org.springframework.util.StringUtils; | |
| 27 | 26 | import org.springframework.web.bind.annotation.PostMapping; |
| 28 | 27 | import org.springframework.web.bind.annotation.RequestBody; |
| 29 | 28 | import org.springframework.web.bind.annotation.RequestMapping; |
| ... | ... | @@ -50,6 +49,9 @@ public class ZLMHttpHookListener { |
| 50 | 49 | private SIPCommander cmder; |
| 51 | 50 | |
| 52 | 51 | @Autowired |
| 52 | + private SIPCommanderFroPlatform commanderFroPlatform; | |
| 53 | + | |
| 54 | + @Autowired | |
| 53 | 55 | private IPlayService playService; |
| 54 | 56 | |
| 55 | 57 | @Autowired |
| ... | ... | @@ -77,7 +79,7 @@ public class ZLMHttpHookListener { |
| 77 | 79 | private ZLMMediaListManager zlmMediaListManager; |
| 78 | 80 | |
| 79 | 81 | @Autowired |
| 80 | - private ZLMHttpHookSubscribe subscribe; | |
| 82 | + private ZlmHttpHookSubscribe subscribe; | |
| 81 | 83 | |
| 82 | 84 | @Autowired |
| 83 | 85 | private UserSetting userSetting; |
| ... | ... | @@ -91,6 +93,10 @@ public class ZLMHttpHookListener { |
| 91 | 93 | @Autowired |
| 92 | 94 | private AssistRESTfulUtils assistRESTfulUtils; |
| 93 | 95 | |
| 96 | + @Qualifier("taskExecutor") | |
| 97 | + @Autowired | |
| 98 | + private ThreadPoolTaskExecutor taskExecutor; | |
| 99 | + | |
| 94 | 100 | /** |
| 95 | 101 | * 服务器定时上报时间,上报间隔可配置,默认10s上报一次 |
| 96 | 102 | * |
| ... | ... | @@ -101,9 +107,9 @@ public class ZLMHttpHookListener { |
| 101 | 107 | |
| 102 | 108 | logger.info("[ ZLM HOOK ] on_server_keepalive API调用,参数:" + json.toString()); |
| 103 | 109 | String mediaServerId = json.getString("mediaServerId"); |
| 104 | - List<ZLMHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive); | |
| 110 | + List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive); | |
| 105 | 111 | if (subscribes != null && subscribes.size() > 0) { |
| 106 | - for (ZLMHttpHookSubscribe.Event subscribe : subscribes) { | |
| 112 | + for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { | |
| 107 | 113 | subscribe.response(null, json); |
| 108 | 114 | } |
| 109 | 115 | } |
| ... | ... | @@ -167,7 +173,7 @@ public class ZLMHttpHookListener { |
| 167 | 173 | logger.debug("[ ZLM HOOK ]on_play API调用,参数:" + JSON.toJSONString(param)); |
| 168 | 174 | } |
| 169 | 175 | String mediaServerId = param.getMediaServerId(); |
| 170 | - ZLMHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_play, json); | |
| 176 | + ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_play, json); | |
| 171 | 177 | if (subscribe != null ) { |
| 172 | 178 | MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); |
| 173 | 179 | if (mediaInfo != null) { |
| ... | ... | @@ -237,9 +243,11 @@ public class ZLMHttpHookListener { |
| 237 | 243 | // 鉴权通过 |
| 238 | 244 | redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo); |
| 239 | 245 | // 通知assist新的callId |
| 240 | - if (mediaInfo != null && mediaInfo.getRecordAssistPort() > 0) { | |
| 241 | - assistRESTfulUtils.addStreamCallInfo(mediaInfo, param.getApp(), param.getStream(), callId, null); | |
| 242 | - } | |
| 246 | + taskExecutor.execute(()->{ | |
| 247 | + if (mediaInfo != null && mediaInfo.getRecordAssistPort() > 0) { | |
| 248 | + assistRESTfulUtils.addStreamCallInfo(mediaInfo, param.getApp(), param.getStream(), callId, null); | |
| 249 | + } | |
| 250 | + }); | |
| 243 | 251 | }else { |
| 244 | 252 | zlmMediaListManager.sendStreamEvent(param.getApp(),param.getStream(), param.getMediaServerId()); |
| 245 | 253 | } |
| ... | ... | @@ -252,7 +260,7 @@ public class ZLMHttpHookListener { |
| 252 | 260 | } |
| 253 | 261 | |
| 254 | 262 | |
| 255 | - ZLMHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); | |
| 263 | + ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); | |
| 256 | 264 | if (subscribe != null) { |
| 257 | 265 | if (mediaInfo != null) { |
| 258 | 266 | subscribe.response(mediaInfo, json); |
| ... | ... | @@ -376,7 +384,7 @@ public class ZLMHttpHookListener { |
| 376 | 384 | logger.debug("[ ZLM HOOK ]on_shell_login API调用,参数:" + json.toString()); |
| 377 | 385 | } |
| 378 | 386 | String mediaServerId = json.getString("mediaServerId"); |
| 379 | - ZLMHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_shell_login, json); | |
| 387 | + ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_shell_login, json); | |
| 380 | 388 | if (subscribe != null ) { |
| 381 | 389 | MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); |
| 382 | 390 | if (mediaInfo != null) { |
| ... | ... | @@ -402,7 +410,7 @@ public class ZLMHttpHookListener { |
| 402 | 410 | logger.info("[ ZLM HOOK ]on_stream_changed API调用,参数:" + JSONObject.toJSONString(item)); |
| 403 | 411 | String mediaServerId = item.getMediaServerId(); |
| 404 | 412 | JSONObject json = (JSONObject) JSON.toJSON(item); |
| 405 | - ZLMHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json); | |
| 413 | + ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json); | |
| 406 | 414 | if (subscribe != null ) { |
| 407 | 415 | MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); |
| 408 | 416 | if (mediaInfo != null) { |
| ... | ... | @@ -415,19 +423,24 @@ public class ZLMHttpHookListener { |
| 415 | 423 | String schema = item.getSchema(); |
| 416 | 424 | List<MediaItem.MediaTrack> tracks = item.getTracks(); |
| 417 | 425 | boolean regist = item.isRegist(); |
| 418 | - if (regist) { | |
| 419 | - StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); | |
| 420 | - if (streamAuthorityInfo == null) { | |
| 421 | - streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(item); | |
| 426 | + if (item.getOriginType() == OriginType.RTMP_PUSH.ordinal() | |
| 427 | + || item.getOriginType() == OriginType.RTSP_PUSH.ordinal() | |
| 428 | + || item.getOriginType() == OriginType.RTC_PUSH.ordinal()) { | |
| 429 | + if (regist) { | |
| 430 | + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); | |
| 431 | + if (streamAuthorityInfo == null) { | |
| 432 | + streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(item); | |
| 433 | + }else { | |
| 434 | + streamAuthorityInfo.setOriginType(item.getOriginType()); | |
| 435 | + streamAuthorityInfo.setOriginTypeStr(item.getOriginTypeStr()); | |
| 436 | + } | |
| 437 | + redisCatchStorage.updateStreamAuthorityInfo(app, stream, streamAuthorityInfo); | |
| 422 | 438 | }else { |
| 423 | - streamAuthorityInfo.setOriginType(item.getOriginType()); | |
| 424 | - streamAuthorityInfo.setOriginTypeStr(item.getOriginTypeStr()); | |
| 439 | + redisCatchStorage.removeStreamAuthorityInfo(app, stream); | |
| 425 | 440 | } |
| 426 | - redisCatchStorage.updateStreamAuthorityInfo(app, stream, streamAuthorityInfo); | |
| 427 | - }else { | |
| 428 | - redisCatchStorage.removeStreamAuthorityInfo(app, stream); | |
| 429 | 441 | } |
| 430 | - if ("rtmp".equals(schema)){ | |
| 442 | + | |
| 443 | + if ("rtsp".equals(schema)){ | |
| 431 | 444 | logger.info("on_stream_changed:注册->{}, app->{}, stream->{}", regist, app, stream); |
| 432 | 445 | if (regist) { |
| 433 | 446 | mediaServerService.addCount(mediaServerId); |
| ... | ... | @@ -523,17 +536,21 @@ public class ZLMHttpHookListener { |
| 523 | 536 | if ("rtp".equals(app)){ |
| 524 | 537 | ret.put("close", true); |
| 525 | 538 | StreamInfo streamInfoForPlayCatch = redisCatchStorage.queryPlayByStreamId(streamId); |
| 526 | - SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransaction(null, null, null, streamId); | |
| 527 | 539 | if (streamInfoForPlayCatch != null) { |
| 528 | - // 如果在给上级推流,也不停止。 | |
| 540 | + // 收到无人观看说明流也没有在往上级推送 | |
| 529 | 541 | if (redisCatchStorage.isChannelSendingRTP(streamInfoForPlayCatch.getChannelId())) { |
| 530 | - ret.put("close", false); | |
| 531 | - } else { | |
| 532 | - cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId(), | |
| 533 | - streamInfoForPlayCatch.getStream(), null); | |
| 534 | - redisCatchStorage.stopPlay(streamInfoForPlayCatch); | |
| 535 | - storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId()); | |
| 542 | + List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByChnnelId(streamInfoForPlayCatch.getChannelId()); | |
| 543 | + if (sendRtpItems.size() > 0) { | |
| 544 | + for (SendRtpItem sendRtpItem : sendRtpItems) { | |
| 545 | + ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); | |
| 546 | + commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId()); | |
| 547 | + } | |
| 548 | + } | |
| 536 | 549 | } |
| 550 | + cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId(), | |
| 551 | + streamInfoForPlayCatch.getStream(), null); | |
| 552 | + redisCatchStorage.stopPlay(streamInfoForPlayCatch); | |
| 553 | + storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId()); | |
| 537 | 554 | }else{ |
| 538 | 555 | StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlayback(null, null, streamId, null); |
| 539 | 556 | if (streamInfoForPlayBackCatch != null) { |
| ... | ... | @@ -615,9 +632,9 @@ public class ZLMHttpHookListener { |
| 615 | 632 | } |
| 616 | 633 | String remoteAddr = request.getRemoteAddr(); |
| 617 | 634 | jsonObject.put("ip", remoteAddr); |
| 618 | - List<ZLMHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_started); | |
| 635 | + List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_started); | |
| 619 | 636 | if (subscribes != null && subscribes.size() > 0) { |
| 620 | - for (ZLMHttpHookSubscribe.Event subscribe : subscribes) { | |
| 637 | + for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { | |
| 621 | 638 | subscribe.response(null, jsonObject); |
| 622 | 639 | } |
| 623 | 640 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
| 1 | 1 | package com.genersoft.iot.vmp.media.zlm; |
| 2 | 2 | |
| 3 | -import com.alibaba.fastjson.JSONObject; | |
| 4 | 3 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 5 | 4 | import com.genersoft.iot.vmp.gb28181.bean.GbStream; |
| 6 | 5 | import com.genersoft.iot.vmp.media.zlm.dto.*; |
| 7 | 6 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 8 | 7 | import com.genersoft.iot.vmp.service.IStreamProxyService; |
| 9 | 8 | import com.genersoft.iot.vmp.service.IStreamPushService; |
| 10 | -import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; | |
| 11 | 9 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 12 | 10 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 13 | 11 | import com.genersoft.iot.vmp.storager.dao.GbStreamMapper; |
| 14 | 12 | import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper; |
| 15 | 13 | import com.genersoft.iot.vmp.storager.dao.StreamPushMapper; |
| 16 | 14 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 17 | -import org.checkerframework.checker.units.qual.C; | |
| 18 | 15 | import org.slf4j.Logger; |
| 19 | 16 | import org.slf4j.LoggerFactory; |
| 20 | 17 | import org.springframework.beans.factory.annotation.Autowired; |
| 21 | 18 | import org.springframework.stereotype.Component; |
| 22 | -import org.springframework.util.StringUtils; | |
| 23 | 19 | |
| 24 | 20 | import java.util.*; |
| 25 | 21 | import java.util.concurrent.ConcurrentHashMap; |
| 26 | -import java.util.regex.Matcher; | |
| 27 | -import java.util.regex.Pattern; | |
| 28 | 22 | |
| 29 | 23 | /** |
| 30 | 24 | * @author lin |
| ... | ... | @@ -59,7 +53,7 @@ public class ZLMMediaListManager { |
| 59 | 53 | private StreamPushMapper streamPushMapper; |
| 60 | 54 | |
| 61 | 55 | @Autowired |
| 62 | - private ZLMHttpHookSubscribe subscribe; | |
| 56 | + private ZlmHttpHookSubscribe subscribe; | |
| 63 | 57 | |
| 64 | 58 | @Autowired |
| 65 | 59 | private UserSetting userSetting; | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
| ... | ... | @@ -92,6 +92,7 @@ public class ZLMRTPServerFactory { |
| 92 | 92 | int result = -1; |
| 93 | 93 | // 查询此rtp server 是否已经存在 |
| 94 | 94 | JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaServerItem, streamId); |
| 95 | + logger.info(JSONObject.toJSONString(rtpInfo)); | |
| 95 | 96 | if(rtpInfo.getInteger("code") == 0){ |
| 96 | 97 | if (rtpInfo.getBoolean("exist")) { |
| 97 | 98 | result = rtpInfo.getInteger("local_port"); |
| ... | ... | @@ -113,7 +114,7 @@ public class ZLMRTPServerFactory { |
| 113 | 114 | } |
| 114 | 115 | param.put("ssrc", ssrc); |
| 115 | 116 | JSONObject openRtpServerResultJson = zlmresTfulUtils.openRtpServer(mediaServerItem, param); |
| 116 | - | |
| 117 | + logger.info(JSONObject.toJSONString(openRtpServerResultJson)); | |
| 117 | 118 | if (openRtpServerResultJson != null) { |
| 118 | 119 | if (openRtpServerResultJson.getInteger("code") == 0) { |
| 119 | 120 | result= openRtpServerResultJson.getInteger("port"); |
| ... | ... | @@ -277,7 +278,7 @@ public class ZLMRTPServerFactory { |
| 277 | 278 | * 查询待转推的流是否就绪 |
| 278 | 279 | */ |
| 279 | 280 | public Boolean isRtpReady(MediaServerItem mediaServerItem, String streamId) { |
| 280 | - JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem,"rtp", "rtmp", streamId); | |
| 281 | + JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem,"rtp", "rtsp", streamId); | |
| 281 | 282 | return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")); |
| 282 | 283 | } |
| 283 | 284 | |
| ... | ... | @@ -297,7 +298,7 @@ public class ZLMRTPServerFactory { |
| 297 | 298 | * @return |
| 298 | 299 | */ |
| 299 | 300 | public int totalReaderCount(MediaServerItem mediaServerItem, String app, String streamId) { |
| 300 | - JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId); | |
| 301 | + JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtsp", streamId); | |
| 301 | 302 | if (mediaInfo == null) { |
| 302 | 303 | return 0; |
| 303 | 304 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
| ... | ... | @@ -8,7 +8,6 @@ import com.genersoft.iot.vmp.conf.MediaConfig; |
| 8 | 8 | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| 9 | 9 | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; |
| 10 | 10 | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForServerStarted; |
| 11 | -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; | |
| 12 | 11 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 13 | 12 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 14 | 13 | import org.slf4j.Logger; |
| ... | ... | @@ -19,9 +18,7 @@ import org.springframework.core.annotation.Order; |
| 19 | 18 | import org.springframework.scheduling.annotation.Async; |
| 20 | 19 | import org.springframework.stereotype.Component; |
| 21 | 20 | |
| 22 | -import java.time.Instant; | |
| 23 | 21 | import java.util.*; |
| 24 | -import java.util.concurrent.TimeUnit; | |
| 25 | 22 | |
| 26 | 23 | @Component |
| 27 | 24 | @Order(value=1) |
| ... | ... | @@ -35,7 +32,7 @@ public class ZLMRunner implements CommandLineRunner { |
| 35 | 32 | private ZLMRESTfulUtils zlmresTfulUtils; |
| 36 | 33 | |
| 37 | 34 | @Autowired |
| 38 | - private ZLMHttpHookSubscribe hookSubscribe; | |
| 35 | + private ZlmHttpHookSubscribe hookSubscribe; | |
| 39 | 36 | |
| 40 | 37 | @Autowired |
| 41 | 38 | private EventPublisher publisher; |
| ... | ... | @@ -62,8 +59,6 @@ public class ZLMRunner implements CommandLineRunner { |
| 62 | 59 | } |
| 63 | 60 | mediaServerService.syncCatchFromDatabase(); |
| 64 | 61 | HookSubscribeForServerStarted hookSubscribeForServerStarted = HookSubscribeFactory.on_server_started(); |
| 65 | -// Instant expiresInstant = Instant.now().plusSeconds(TimeUnit.SECONDS.toSeconds(60)); | |
| 66 | -// hookSubscribeForStreamChange.setExpires(expiresInstant); | |
| 67 | 62 | // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 |
| 68 | 63 | hookSubscribe.addSubscribe(hookSubscribeForServerStarted, |
| 69 | 64 | (MediaServerItem mediaServerItem, JSONObject response)->{ | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java renamed to src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java
| ... | ... | @@ -4,6 +4,9 @@ import com.alibaba.fastjson.JSONObject; |
| 4 | 4 | import com.genersoft.iot.vmp.media.zlm.dto.HookType; |
| 5 | 5 | import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; |
| 6 | 6 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 7 | +import org.slf4j.Logger; | |
| 8 | +import org.slf4j.LoggerFactory; | |
| 9 | +import org.springframework.scheduling.annotation.Scheduled; | |
| 7 | 10 | import org.springframework.stereotype.Component; |
| 8 | 11 | import org.springframework.util.CollectionUtils; |
| 9 | 12 | |
| ... | ... | @@ -13,21 +16,22 @@ import java.util.concurrent.ConcurrentHashMap; |
| 13 | 16 | import java.util.concurrent.TimeUnit; |
| 14 | 17 | |
| 15 | 18 | /** |
| 16 | - * @description:针对 ZLMediaServer的hook事件订阅 | |
| 17 | - * @author: pan | |
| 18 | - * @date: 2020年12月2日 21:17:32 | |
| 19 | + * ZLMediaServer的hook事件订阅 | |
| 20 | + * @author lin | |
| 19 | 21 | */ |
| 20 | 22 | @Component |
| 21 | -public class ZLMHttpHookSubscribe { | |
| 23 | +public class ZlmHttpHookSubscribe { | |
| 24 | + | |
| 25 | + private final static Logger logger = LoggerFactory.getLogger(ZlmHttpHookSubscribe.class); | |
| 22 | 26 | |
| 23 | 27 | @FunctionalInterface |
| 24 | 28 | public interface Event{ |
| 25 | 29 | void response(MediaServerItem mediaServerItem, JSONObject response); |
| 26 | 30 | } |
| 27 | 31 | |
| 28 | - private Map<HookType, Map<IHookSubscribe, ZLMHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>(); | |
| 32 | + private Map<HookType, Map<IHookSubscribe, ZlmHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>(); | |
| 29 | 33 | |
| 30 | - public void addSubscribe(IHookSubscribe hookSubscribe, ZLMHttpHookSubscribe.Event event) { | |
| 34 | + public void addSubscribe(IHookSubscribe hookSubscribe, ZlmHttpHookSubscribe.Event event) { | |
| 31 | 35 | if (hookSubscribe.getExpires() == null) { |
| 32 | 36 | // 默认5分钟过期 |
| 33 | 37 | Instant expiresInstant = Instant.now().plusSeconds(TimeUnit.MINUTES.toSeconds(5)); |
| ... | ... | @@ -36,8 +40,8 @@ public class ZLMHttpHookSubscribe { |
| 36 | 40 | allSubscribes.computeIfAbsent(hookSubscribe.getHookType(), k -> new ConcurrentHashMap<>()).put(hookSubscribe, event); |
| 37 | 41 | } |
| 38 | 42 | |
| 39 | - public ZLMHttpHookSubscribe.Event sendNotify(HookType type, JSONObject hookResponse) { | |
| 40 | - ZLMHttpHookSubscribe.Event event= null; | |
| 43 | + public ZlmHttpHookSubscribe.Event sendNotify(HookType type, JSONObject hookResponse) { | |
| 44 | + ZlmHttpHookSubscribe.Event event= null; | |
| 41 | 45 | Map<IHookSubscribe, Event> eventMap = allSubscribes.get(type); |
| 42 | 46 | if (eventMap == null) { |
| 43 | 47 | return null; |
| ... | ... | @@ -69,8 +73,8 @@ public class ZLMHttpHookSubscribe { |
| 69 | 73 | |
| 70 | 74 | Set<Map.Entry<IHookSubscribe, Event>> entries = eventMap.entrySet(); |
| 71 | 75 | if (entries.size() > 0) { |
| 72 | - List<Map.Entry<IHookSubscribe, ZLMHttpHookSubscribe.Event>> entriesToRemove = new ArrayList<>(); | |
| 73 | - for (Map.Entry<IHookSubscribe, ZLMHttpHookSubscribe.Event> entry : entries) { | |
| 76 | + List<Map.Entry<IHookSubscribe, ZlmHttpHookSubscribe.Event>> entriesToRemove = new ArrayList<>(); | |
| 77 | + for (Map.Entry<IHookSubscribe, ZlmHttpHookSubscribe.Event> entry : entries) { | |
| 74 | 78 | JSONObject content = entry.getKey().getContent(); |
| 75 | 79 | if (content == null || content.size() == 0) { |
| 76 | 80 | entriesToRemove.add(entry); |
| ... | ... | @@ -87,13 +91,13 @@ public class ZLMHttpHookSubscribe { |
| 87 | 91 | result = result && content.getString(s).equals(hookSubscribe.getContent().getString(s)); |
| 88 | 92 | } |
| 89 | 93 | } |
| 90 | - if (null != result && result){ | |
| 94 | + if (result){ | |
| 91 | 95 | entriesToRemove.add(entry); |
| 92 | 96 | } |
| 93 | 97 | } |
| 94 | 98 | |
| 95 | 99 | if (!CollectionUtils.isEmpty(entriesToRemove)) { |
| 96 | - for (Map.Entry<IHookSubscribe, ZLMHttpHookSubscribe.Event> entry : entriesToRemove) { | |
| 100 | + for (Map.Entry<IHookSubscribe, ZlmHttpHookSubscribe.Event> entry : entriesToRemove) { | |
| 97 | 101 | entries.remove(entry); |
| 98 | 102 | } |
| 99 | 103 | } |
| ... | ... | @@ -106,12 +110,12 @@ public class ZLMHttpHookSubscribe { |
| 106 | 110 | * @param type |
| 107 | 111 | * @return |
| 108 | 112 | */ |
| 109 | - public List<ZLMHttpHookSubscribe.Event> getSubscribes(HookType type) { | |
| 113 | + public List<ZlmHttpHookSubscribe.Event> getSubscribes(HookType type) { | |
| 110 | 114 | Map<IHookSubscribe, Event> eventMap = allSubscribes.get(type); |
| 111 | 115 | if (eventMap == null) { |
| 112 | 116 | return null; |
| 113 | 117 | } |
| 114 | - List<ZLMHttpHookSubscribe.Event> result = new ArrayList<>(); | |
| 118 | + List<ZlmHttpHookSubscribe.Event> result = new ArrayList<>(); | |
| 115 | 119 | for (IHookSubscribe key : eventMap.keySet()) { |
| 116 | 120 | result.add(eventMap.get(key)); |
| 117 | 121 | } |
| ... | ... | @@ -127,5 +131,28 @@ public class ZLMHttpHookSubscribe { |
| 127 | 131 | return result; |
| 128 | 132 | } |
| 129 | 133 | |
| 134 | + /** | |
| 135 | + * 对订阅数据进行过期清理 | |
| 136 | + */ | |
| 137 | + @Scheduled(cron="0 0/5 * * * ?") //每5分钟执行一次 | |
| 138 | + public void execute(){ | |
| 130 | 139 | |
| 140 | + logger.info("[hook订阅] 清理"); | |
| 141 | + | |
| 142 | + Instant instant = Instant.now().minusMillis(TimeUnit.MINUTES.toMillis(5)); | |
| 143 | + int total = 0; | |
| 144 | + for (HookType hookType : allSubscribes.keySet()) { | |
| 145 | + Map<IHookSubscribe, Event> hookSubscribeEventMap = allSubscribes.get(hookType); | |
| 146 | + if (hookSubscribeEventMap.size() > 0) { | |
| 147 | + for (IHookSubscribe hookSubscribe : hookSubscribeEventMap.keySet()) { | |
| 148 | + if (hookSubscribe.getExpires().isBefore(instant)) { | |
| 149 | + // 过期的 | |
| 150 | + hookSubscribeEventMap.remove(hookSubscribe); | |
| 151 | + total ++; | |
| 152 | + } | |
| 153 | + } | |
| 154 | + } | |
| 155 | + } | |
| 156 | + logger.info("[hook订阅] 清理结束,共清理{}条过期数据", total); | |
| 157 | + } | |
| 131 | 158 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMKeepliveTimeoutListener.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.media.zlm.event; | |
| 2 | - | |
| 3 | -import com.alibaba.fastjson.JSONObject; | |
| 4 | -import com.genersoft.iot.vmp.common.VideoManagerConstants; | |
| 5 | -import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener; | |
| 6 | -import com.genersoft.iot.vmp.conf.UserSetting; | |
| 7 | -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | |
| 8 | -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; | |
| 9 | -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | |
| 10 | -import com.genersoft.iot.vmp.service.IMediaServerService; | |
| 11 | -import org.slf4j.Logger; | |
| 12 | -import org.slf4j.LoggerFactory; | |
| 13 | -import org.springframework.beans.factory.annotation.Autowired; | |
| 14 | -import org.springframework.data.redis.connection.Message; | |
| 15 | -import org.springframework.data.redis.listener.RedisMessageListenerContainer; | |
| 16 | -import org.springframework.stereotype.Component; | |
| 17 | - | |
| 18 | -/** | |
| 19 | - * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件 | |
| 20 | - * @author: swwheihei | |
| 21 | - * @date: 2020年5月6日 上午11:35:46 | |
| 22 | - */ | |
| 23 | -@Component | |
| 24 | -public class ZLMKeepliveTimeoutListener extends RedisKeyExpirationEventMessageListener { | |
| 25 | - | |
| 26 | - private Logger logger = LoggerFactory.getLogger(ZLMKeepliveTimeoutListener.class); | |
| 27 | - | |
| 28 | - @Autowired | |
| 29 | - private EventPublisher publisher; | |
| 30 | - | |
| 31 | - @Autowired | |
| 32 | - private ZLMRESTfulUtils zlmresTfulUtils; | |
| 33 | - | |
| 34 | - @Autowired | |
| 35 | - private UserSetting userSetting; | |
| 36 | - | |
| 37 | - @Autowired | |
| 38 | - private IMediaServerService mediaServerService; | |
| 39 | - | |
| 40 | - public ZLMKeepliveTimeoutListener(RedisMessageListenerContainer listenerContainer, UserSetting userSetting) { | |
| 41 | - super(listenerContainer, userSetting); | |
| 42 | - } | |
| 43 | - | |
| 44 | - | |
| 45 | - /** | |
| 46 | - * 监听失效的key,key格式为keeplive_deviceId | |
| 47 | - * @param message | |
| 48 | - * @param pattern | |
| 49 | - */ | |
| 50 | - @Override | |
| 51 | - public void onMessage(Message message, byte[] pattern) { | |
| 52 | - // 获取失效的key | |
| 53 | - String expiredKey = message.toString(); | |
| 54 | - String KEEPLIVEKEY_PREFIX = VideoManagerConstants.MEDIA_SERVER_KEEPALIVE_PREFIX + userSetting.getServerId() + "_"; | |
| 55 | - if(!expiredKey.startsWith(KEEPLIVEKEY_PREFIX)){ | |
| 56 | - return; | |
| 57 | - } | |
| 58 | - | |
| 59 | - String mediaServerId = expiredKey.substring(KEEPLIVEKEY_PREFIX.length(),expiredKey.length()); | |
| 60 | - logger.info("[zlm心跳到期]:" + mediaServerId); | |
| 61 | - // 发起http请求验证zlm是否确实无法连接,如果确实无法连接则发送离线事件,否则不作处理 | |
| 62 | - MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); | |
| 63 | - JSONObject mediaServerConfig = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); | |
| 64 | - if (mediaServerConfig != null && mediaServerConfig.getInteger("code") == 0) { | |
| 65 | - logger.info("[zlm心跳到期]:{}验证后zlm仍在线,恢复心跳信息", mediaServerId); | |
| 66 | - // 添加zlm信息 | |
| 67 | - mediaServerService.updateMediaServerKeepalive(mediaServerId, mediaServerConfig); | |
| 68 | - }else { | |
| 69 | - publisher.zlmOfflineEventPublish(mediaServerId); | |
| 70 | - } | |
| 71 | - } | |
| 72 | -} |
src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.service; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 4 | +import com.github.pagehelper.PageInfo; | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * 国标平台的业务类 | |
| 8 | + * @author lin | |
| 9 | + */ | |
| 10 | +public interface IPlatformService { | |
| 11 | + | |
| 12 | + ParentPlatform queryPlatformByServerGBId(String platformGbId); | |
| 13 | + | |
| 14 | + /** | |
| 15 | + * 分页获取上级平台 | |
| 16 | + * @param page | |
| 17 | + * @param count | |
| 18 | + * @return | |
| 19 | + */ | |
| 20 | + PageInfo<ParentPlatform> queryParentPlatformList(int page, int count); | |
| 21 | + | |
| 22 | + /** | |
| 23 | + * 添加级联平台 | |
| 24 | + * @param parentPlatform 级联平台 | |
| 25 | + */ | |
| 26 | + boolean add(ParentPlatform parentPlatform); | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * 平台上线 | |
| 30 | + * @param parentPlatform 平台信息 | |
| 31 | + */ | |
| 32 | + void online(ParentPlatform parentPlatform); | |
| 33 | + | |
| 34 | + /** | |
| 35 | + * 平台离线 | |
| 36 | + * @param parentPlatform 平台信息 | |
| 37 | + */ | |
| 38 | + void offline(ParentPlatform parentPlatform); | |
| 39 | + | |
| 40 | + /** | |
| 41 | + * 向上级平台发起注册 | |
| 42 | + * @param parentPlatform | |
| 43 | + */ | |
| 44 | + void login(ParentPlatform parentPlatform); | |
| 45 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
| ... | ... | @@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 6 | 6 | import com.genersoft.iot.vmp.gb28181.bean.InviteStreamCallback; |
| 7 | 7 | import com.genersoft.iot.vmp.gb28181.bean.InviteStreamInfo; |
| 8 | 8 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 9 | -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | |
| 9 | +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; | |
| 10 | 10 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 11 | 11 | import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; |
| 12 | 12 | import com.genersoft.iot.vmp.service.bean.PlayBackCallback; |
| ... | ... | @@ -14,7 +14,6 @@ import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| 14 | 14 | import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.AudioBroadcastEvent; |
| 15 | 15 | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| 16 | 16 | import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; |
| 17 | -import org.springframework.http.ResponseEntity; | |
| 18 | 17 | import org.springframework.web.context.request.async.DeferredResult; |
| 19 | 18 | |
| 20 | 19 | /** |
| ... | ... | @@ -25,9 +24,9 @@ public interface IPlayService { |
| 25 | 24 | void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid); |
| 26 | 25 | |
| 27 | 26 | void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, |
| 28 | - ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, | |
| 27 | + ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, | |
| 29 | 28 | InviteTimeOutCallback timeoutCallback, String uuid); |
| 30 | - PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent, Runnable timeoutCallback); | |
| 29 | + PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent, Runnable timeoutCallback); | |
| 31 | 30 | |
| 32 | 31 | MediaServerItem getNewMediaServerItem(Device device); |
| 33 | 32 | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
| ... | ... | @@ -11,6 +11,7 @@ import java.util.Set; |
| 11 | 11 | import com.genersoft.iot.vmp.media.zlm.ZLMRunner; |
| 12 | 12 | import com.genersoft.iot.vmp.service.IStreamProxyService; |
| 13 | 13 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 14 | +import com.genersoft.iot.vmp.conf.DynamicTask; | |
| 14 | 15 | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| 15 | 16 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 16 | 17 | import org.slf4j.Logger; |
| ... | ... | @@ -22,7 +23,6 @@ import org.springframework.stereotype.Service; |
| 22 | 23 | import org.springframework.transaction.TransactionDefinition; |
| 23 | 24 | import org.springframework.transaction.TransactionStatus; |
| 24 | 25 | import org.springframework.util.ObjectUtils; |
| 25 | -import org.springframework.util.StringUtils; | |
| 26 | 26 | |
| 27 | 27 | import com.alibaba.fastjson.JSON; |
| 28 | 28 | import com.alibaba.fastjson.JSONArray; |
| ... | ... | @@ -42,7 +42,6 @@ import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| 42 | 42 | import com.genersoft.iot.vmp.storager.dao.MediaServerMapper; |
| 43 | 43 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 44 | 44 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| 45 | -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; | |
| 46 | 45 | |
| 47 | 46 | import okhttp3.OkHttpClient; |
| 48 | 47 | import okhttp3.Request; |
| ... | ... | @@ -58,6 +57,8 @@ public class MediaServerServiceImpl implements IMediaServerService { |
| 58 | 57 | |
| 59 | 58 | private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class); |
| 60 | 59 | |
| 60 | + private final String zlmKeepaliveKeyPrefix = "zlm-keepalive_"; | |
| 61 | + | |
| 61 | 62 | @Autowired |
| 62 | 63 | private SipConfig sipConfig; |
| 63 | 64 | |
| ... | ... | @@ -88,10 +89,12 @@ public class MediaServerServiceImpl implements IMediaServerService { |
| 88 | 89 | @Autowired |
| 89 | 90 | private ZLMRTPServerFactory zlmrtpServerFactory; |
| 90 | 91 | |
| 91 | - | |
| 92 | 92 | @Autowired |
| 93 | 93 | private EventPublisher publisher; |
| 94 | 94 | |
| 95 | + @Autowired | |
| 96 | + private DynamicTask dynamicTask; | |
| 97 | + | |
| 95 | 98 | /** |
| 96 | 99 | * 初始化 |
| 97 | 100 | */ |
| ... | ... | @@ -135,7 +138,7 @@ public class MediaServerServiceImpl implements IMediaServerService { |
| 135 | 138 | logger.info("media server [ {} ] ssrcConfig is null", mediaServerItem.getId()); |
| 136 | 139 | return null; |
| 137 | 140 | }else { |
| 138 | - String ssrc = null; | |
| 141 | + String ssrc; | |
| 139 | 142 | if (presetSsrc != null) { |
| 140 | 143 | ssrc = presetSsrc; |
| 141 | 144 | }else { |
| ... | ... | @@ -404,15 +407,43 @@ public class MediaServerServiceImpl implements IMediaServerService { |
| 404 | 407 | if (serverItem.isAutoConfig()) { |
| 405 | 408 | setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable())); |
| 406 | 409 | } |
| 410 | + final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + serverItem.getId(); | |
| 411 | + dynamicTask.stop(zlmKeepaliveKey); | |
| 412 | + dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(serverItem), (serverItem.getHookAliveInterval() + 5) * 1000); | |
| 407 | 413 | publisher.zlmOnlineEventPublish(serverItem.getId()); |
| 408 | 414 | logger.info("[ZLM] 连接成功 {} - {}:{} ", |
| 409 | 415 | zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); |
| 410 | 416 | } |
| 411 | 417 | |
| 418 | + class KeepAliveTimeoutRunnable implements Runnable{ | |
| 419 | + | |
| 420 | + private MediaServerItem serverItem; | |
| 421 | + | |
| 422 | + public KeepAliveTimeoutRunnable(MediaServerItem serverItem) { | |
| 423 | + this.serverItem = serverItem; | |
| 424 | + } | |
| 425 | + | |
| 426 | + @Override | |
| 427 | + public void run() { | |
| 428 | + logger.info("[zlm心跳到期]:" + serverItem.getId()); | |
| 429 | + // 发起http请求验证zlm是否确实无法连接,如果确实无法连接则发送离线事件,否则不作处理 | |
| 430 | + JSONObject mediaServerConfig = zlmresTfulUtils.getMediaServerConfig(serverItem); | |
| 431 | + if (mediaServerConfig != null && mediaServerConfig.getInteger("code") == 0) { | |
| 432 | + logger.info("[zlm心跳到期]:{}验证后zlm仍在线,恢复心跳信息,请检查zlm是否可以正常向wvp发送心跳", serverItem.getId()); | |
| 433 | + // 添加zlm信息 | |
| 434 | + updateMediaServerKeepalive(serverItem.getId(), mediaServerConfig); | |
| 435 | + }else { | |
| 436 | + publisher.zlmOfflineEventPublish(serverItem.getId()); | |
| 437 | + } | |
| 438 | + } | |
| 439 | + } | |
| 440 | + | |
| 412 | 441 | |
| 413 | 442 | @Override |
| 414 | 443 | public void zlmServerOffline(String mediaServerId) { |
| 415 | 444 | delete(mediaServerId); |
| 445 | + final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + mediaServerId; | |
| 446 | + dynamicTask.stop(zlmKeepaliveKey); | |
| 416 | 447 | } |
| 417 | 448 | |
| 418 | 449 | @Override |
| ... | ... | @@ -423,7 +454,7 @@ public class MediaServerServiceImpl implements IMediaServerService { |
| 423 | 454 | if (RedisUtil.zScore(key, serverItem.getId()) == null) { // 不存在则设置默认值 已存在则重置 |
| 424 | 455 | RedisUtil.zAdd(key, serverItem.getId(), 0L); |
| 425 | 456 | // 查询服务流数量 |
| 426 | - zlmresTfulUtils.getMediaList(serverItem, null, null, "rtmp",(mediaList ->{ | |
| 457 | + zlmresTfulUtils.getMediaList(serverItem, null, null, "rtsp",(mediaList ->{ | |
| 427 | 458 | Integer code = mediaList.getInteger("code"); |
| 428 | 459 | if (code == 0) { |
| 429 | 460 | JSONArray data = mediaList.getJSONArray("data"); |
| ... | ... | @@ -435,7 +466,6 @@ public class MediaServerServiceImpl implements IMediaServerService { |
| 435 | 466 | }else { |
| 436 | 467 | clearRTPServer(serverItem); |
| 437 | 468 | } |
| 438 | - | |
| 439 | 469 | } |
| 440 | 470 | |
| 441 | 471 | |
| ... | ... | @@ -471,7 +501,7 @@ public class MediaServerServiceImpl implements IMediaServerService { |
| 471 | 501 | } |
| 472 | 502 | |
| 473 | 503 | // 获取分数最低的,及并发最低的 |
| 474 | - Set<Object> objects = RedisUtil.ZRange(key, 0, -1); | |
| 504 | + Set<Object> objects = RedisUtil.zRange(key, 0, -1); | |
| 475 | 505 | ArrayList<Object> mediaServerObjectS = new ArrayList<>(objects); |
| 476 | 506 | |
| 477 | 507 | String mediaServerId = (String)mediaServerObjectS.get(0); |
| ... | ... | @@ -489,10 +519,7 @@ public class MediaServerServiceImpl implements IMediaServerService { |
| 489 | 519 | mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); |
| 490 | 520 | String protocol = sslEnabled ? "https" : "http"; |
| 491 | 521 | String hookPrex = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort); |
| 492 | - String recordHookPrex = null; | |
| 493 | - if (mediaServerItem.getRecordAssistPort() != 0) { | |
| 494 | - recordHookPrex = String.format("http://127.0.0.1:%s/api/record", mediaServerItem.getRecordAssistPort()); | |
| 495 | - } | |
| 522 | + | |
| 496 | 523 | Map<String, Object> param = new HashMap<>(); |
| 497 | 524 | param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline |
| 498 | 525 | param.put("ffmpeg.cmd","%s -fflags nobuffer -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s"); |
| ... | ... | @@ -501,7 +528,6 @@ public class MediaServerServiceImpl implements IMediaServerService { |
| 501 | 528 | param.put("hook.on_play",String.format("%s/on_play", hookPrex)); |
| 502 | 529 | param.put("hook.on_http_access",String.format("%s/on_http_access", hookPrex)); |
| 503 | 530 | param.put("hook.on_publish", String.format("%s/on_publish", hookPrex)); |
| 504 | - param.put("hook.on_record_mp4",recordHookPrex != null? String.format("%s/on_record_mp4", recordHookPrex): ""); | |
| 505 | 531 | param.put("hook.on_record_ts",String.format("%s/on_record_ts", hookPrex)); |
| 506 | 532 | param.put("hook.on_rtsp_auth",String.format("%s/on_rtsp_auth", hookPrex)); |
| 507 | 533 | param.put("hook.on_rtsp_realm",String.format("%s/on_rtsp_realm", hookPrex)); |
| ... | ... | @@ -511,6 +537,11 @@ public class MediaServerServiceImpl implements IMediaServerService { |
| 511 | 537 | param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrex)); |
| 512 | 538 | param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex)); |
| 513 | 539 | param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrex)); |
| 540 | + if (mediaServerItem.getRecordAssistPort() > 0) { | |
| 541 | + param.put("hook.on_record_mp4",String.format("http://127.0.0.1:%s/api/record/on_record_mp4", mediaServerItem.getRecordAssistPort())); | |
| 542 | + }else { | |
| 543 | + param.put("hook.on_record_mp4",""); | |
| 544 | + } | |
| 514 | 545 | param.put("hook.timeoutSec","20"); |
| 515 | 546 | param.put("general.streamNoneReaderDelayMS",mediaServerItem.getStreamNoneReaderDelayMS()==-1?"3600000":mediaServerItem.getStreamNoneReaderDelayMS() ); |
| 516 | 547 | // 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 |
| ... | ... | @@ -631,9 +662,9 @@ public class MediaServerServiceImpl implements IMediaServerService { |
| 631 | 662 | return; |
| 632 | 663 | } |
| 633 | 664 | } |
| 634 | - String key = VideoManagerConstants.MEDIA_SERVER_KEEPALIVE_PREFIX + userSetting.getServerId() + "_" + mediaServerId; | |
| 635 | - int hookAliveInterval = mediaServerItem.getHookAliveInterval() + 2; | |
| 636 | - RedisUtil.set(key, data, hookAliveInterval); | |
| 665 | + final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + mediaServerItem.getId(); | |
| 666 | + dynamicTask.stop(zlmKeepaliveKey); | |
| 667 | + dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(mediaServerItem), (mediaServerItem.getHookAliveInterval() + 5) * 1000); | |
| 637 | 668 | } |
| 638 | 669 | |
| 639 | 670 | private MediaServerItem getOneFromDatabase(String mediaServerId) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
| ... | ... | @@ -108,6 +108,7 @@ public class MediaServiceImpl implements IMediaService { |
| 108 | 108 | streamInfoResult.setWs_fmp4(String.format("ws://%s:%s/%s/%s.live.mp4%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam)); |
| 109 | 109 | streamInfoResult.setTs(String.format("http://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam)); |
| 110 | 110 | streamInfoResult.setWs_ts(String.format("ws://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam)); |
| 111 | + streamInfoResult.setRtc(String.format("http://%s:%s/index/api/webrtc?app=%s&stream=%s&type=play%s", mediaInfo.getStreamIp(), mediaInfo.getHttpPort(), app, stream, ObjectUtils.isEmpty(callId)?"":"&callId=" + callId)); | |
| 111 | 112 | if (mediaInfo.getHttpSSlPort() != 0) { |
| 112 | 113 | streamInfoResult.setHttps_flv(String.format("https://%s:%s/%s/%s.live.flv%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); |
| 113 | 114 | streamInfoResult.setWss_flv(String.format("wss://%s:%s/%s/%s.live.flv%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); |
| ... | ... | @@ -118,7 +119,7 @@ public class MediaServiceImpl implements IMediaService { |
| 118 | 119 | streamInfoResult.setHttps_ts(String.format("https://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); |
| 119 | 120 | streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); |
| 120 | 121 | streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); |
| 121 | - streamInfoResult.setRtc(String.format("https://%s:%s/index/api/webrtc?app=%s&stream=%s&type=%s%s", mediaInfo.getStreamIp(), mediaInfo.getHttpSSlPort(), app, stream, isPlay?"play":"push", ObjectUtils.isEmpty(callId)?"":"&callId=" + callId)); | |
| 122 | + streamInfoResult.setRtcs(String.format("https://%s:%s/index/api/webrtc?app=%s&stream=%s&type=play%s", mediaInfo.getStreamIp(), mediaInfo.getHttpSSlPort(), app, stream, ObjectUtils.isEmpty(callId)?"":"&callId=" + callId)); | |
| 122 | 123 | } |
| 123 | 124 | |
| 124 | 125 | streamInfoResult.setTracks(tracks); | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.service.impl; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.conf.DynamicTask; | |
| 4 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 5 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; | |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | |
| 7 | +import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; | |
| 8 | +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | |
| 9 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; | |
| 10 | +import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | |
| 11 | +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | |
| 12 | +import com.genersoft.iot.vmp.service.IMediaServerService; | |
| 13 | +import com.genersoft.iot.vmp.service.IPlatformService; | |
| 14 | +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | |
| 15 | +import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; | |
| 16 | +import com.github.pagehelper.PageHelper; | |
| 17 | +import com.github.pagehelper.PageInfo; | |
| 18 | +import org.slf4j.Logger; | |
| 19 | +import org.slf4j.LoggerFactory; | |
| 20 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 21 | +import org.springframework.stereotype.Service; | |
| 22 | + | |
| 23 | +import javax.sip.TimeoutEvent; | |
| 24 | +import java.util.HashMap; | |
| 25 | +import java.util.List; | |
| 26 | +import java.util.Map; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * @author lin | |
| 30 | + */ | |
| 31 | +@Service | |
| 32 | +public class PlatformServiceImpl implements IPlatformService { | |
| 33 | + | |
| 34 | + private final static String REGISTER_KEY_PREFIX = "platform_register_"; | |
| 35 | + private final static String KEEPALIVE_KEY_PREFIX = "platform_keepalive_"; | |
| 36 | + | |
| 37 | + private final static Logger logger = LoggerFactory.getLogger(PlatformServiceImpl.class); | |
| 38 | + | |
| 39 | + @Autowired | |
| 40 | + private ParentPlatformMapper platformMapper; | |
| 41 | + | |
| 42 | + @Autowired | |
| 43 | + private IRedisCatchStorage redisCatchStorage; | |
| 44 | + | |
| 45 | + @Autowired | |
| 46 | + private IMediaServerService mediaServerService; | |
| 47 | + | |
| 48 | + @Autowired | |
| 49 | + private SIPCommanderFroPlatform commanderForPlatform; | |
| 50 | + | |
| 51 | + @Autowired | |
| 52 | + private DynamicTask dynamicTask; | |
| 53 | + | |
| 54 | + @Autowired | |
| 55 | + private ZLMRTPServerFactory zlmrtpServerFactory; | |
| 56 | + | |
| 57 | + @Autowired | |
| 58 | + private SubscribeHolder subscribeHolder; | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + @Override | |
| 63 | + public ParentPlatform queryPlatformByServerGBId(String platformGbId) { | |
| 64 | + return platformMapper.getParentPlatByServerGBId(platformGbId); | |
| 65 | + } | |
| 66 | + | |
| 67 | + @Override | |
| 68 | + public PageInfo<ParentPlatform> queryParentPlatformList(int page, int count) { | |
| 69 | + PageHelper.startPage(page, count); | |
| 70 | + List<ParentPlatform> all = platformMapper.getParentPlatformList(); | |
| 71 | + return new PageInfo<>(all); | |
| 72 | + } | |
| 73 | + | |
| 74 | + @Override | |
| 75 | + public boolean add(ParentPlatform parentPlatform) { | |
| 76 | + | |
| 77 | + if (parentPlatform.getCatalogGroup() == 0) { | |
| 78 | + // 每次发送目录的数量默认为1 | |
| 79 | + parentPlatform.setCatalogGroup(1); | |
| 80 | + } | |
| 81 | + if (parentPlatform.getAdministrativeDivision() == null) { | |
| 82 | + // 行政区划默认去编号的前6位 | |
| 83 | + parentPlatform.setAdministrativeDivision(parentPlatform.getServerGBId().substring(0,6)); | |
| 84 | + } | |
| 85 | + parentPlatform.setCatalogId(parentPlatform.getDeviceGBId()); | |
| 86 | + int result = platformMapper.addParentPlatform(parentPlatform); | |
| 87 | + // 添加缓存 | |
| 88 | + ParentPlatformCatch parentPlatformCatch = new ParentPlatformCatch(); | |
| 89 | + parentPlatformCatch.setParentPlatform(parentPlatform); | |
| 90 | + parentPlatformCatch.setId(parentPlatform.getServerGBId()); | |
| 91 | + parentPlatformCatch.setParentPlatform(parentPlatform); | |
| 92 | + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | |
| 93 | + if (parentPlatform.isEnable()) { | |
| 94 | + // 保存时启用就发送注册 | |
| 95 | + // 注册成功时由程序直接调用了online方法 | |
| 96 | + commanderForPlatform.register(parentPlatform, eventResult -> { | |
| 97 | + logger.info("[国标级联] {},添加向上级注册失败,请确定上级平台可用时重新保存", parentPlatform.getServerGBId()); | |
| 98 | + }, null); | |
| 99 | + } | |
| 100 | + return result > 0; | |
| 101 | + } | |
| 102 | + | |
| 103 | + @Override | |
| 104 | + public void online(ParentPlatform parentPlatform) { | |
| 105 | + logger.info("[国标级联]:{}, 平台上线/更新注册", parentPlatform.getServerGBId()); | |
| 106 | + platformMapper.updateParentPlatformStatus(parentPlatform.getServerGBId(), true); | |
| 107 | + ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); | |
| 108 | + if (parentPlatformCatch != null) { | |
| 109 | + parentPlatformCatch.getParentPlatform().setStatus(true); | |
| 110 | + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | |
| 111 | + }else { | |
| 112 | + parentPlatformCatch = new ParentPlatformCatch(); | |
| 113 | + parentPlatformCatch.setParentPlatform(parentPlatform); | |
| 114 | + parentPlatformCatch.setId(parentPlatform.getServerGBId()); | |
| 115 | + parentPlatform.setStatus(true); | |
| 116 | + parentPlatformCatch.setParentPlatform(parentPlatform); | |
| 117 | + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | |
| 118 | + } | |
| 119 | + | |
| 120 | + final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId(); | |
| 121 | + if (dynamicTask.contains(registerTaskKey)) { | |
| 122 | + dynamicTask.stop(registerTaskKey); | |
| 123 | + } | |
| 124 | + // 添加注册任务 | |
| 125 | + dynamicTask.startDelay(registerTaskKey, | |
| 126 | + // 注册失败(注册成功时由程序直接调用了online方法) | |
| 127 | + ()->commanderForPlatform.register(parentPlatform, eventResult -> offline(parentPlatform),null), | |
| 128 | + parentPlatform.getExpires()*1000); | |
| 129 | + | |
| 130 | + final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId(); | |
| 131 | + if (!dynamicTask.contains(keepaliveTaskKey)) { | |
| 132 | + // 添加心跳任务 | |
| 133 | + dynamicTask.startCron(keepaliveTaskKey, | |
| 134 | + ()-> commanderForPlatform.keepalive(parentPlatform, eventResult -> { | |
| 135 | + // 心跳失败 | |
| 136 | + if (eventResult.type == SipSubscribe.EventResultType.timeout) { | |
| 137 | + // 心跳超时 | |
| 138 | + ParentPlatformCatch platformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); | |
| 139 | + // 此时是第三次心跳超时, 平台离线 | |
| 140 | + if (platformCatch.getKeepAliveReply() == 2) { | |
| 141 | + // 设置平台离线,并重新注册 | |
| 142 | + offline(parentPlatform); | |
| 143 | + logger.info("[国标级联] {},三次心跳超时后再次发起注册", parentPlatform.getServerGBId()); | |
| 144 | + commanderForPlatform.register(parentPlatform, eventResult1 -> { | |
| 145 | + logger.info("[国标级联] {},三次心跳超时后再次发起注册仍然失败,开始定时发起注册,间隔为1分钟", parentPlatform.getServerGBId()); | |
| 146 | + // 添加注册任务 | |
| 147 | + dynamicTask.startCron(registerTaskKey, | |
| 148 | + // 注册失败(注册成功时由程序直接调用了online方法) | |
| 149 | + ()->logger.info("[国标级联] {},平台离线后持续发起注册,失败", parentPlatform.getServerGBId()), | |
| 150 | + 60*1000); | |
| 151 | + }, null); | |
| 152 | + } | |
| 153 | + | |
| 154 | + }else { | |
| 155 | + logger.warn("[国标级联]发送心跳收到错误,code: {}, msg: {}", eventResult.statusCode, eventResult.msg); | |
| 156 | + } | |
| 157 | + | |
| 158 | + }, eventResult -> { | |
| 159 | + // 心跳成功 | |
| 160 | + // 清空之前的心跳超时计数 | |
| 161 | + ParentPlatformCatch platformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); | |
| 162 | + if (platformCatch.getKeepAliveReply() > 0) { | |
| 163 | + platformCatch.setKeepAliveReply(0); | |
| 164 | + redisCatchStorage.updatePlatformCatchInfo(platformCatch); | |
| 165 | + } | |
| 166 | + }), | |
| 167 | + parentPlatform.getExpires()*1000); | |
| 168 | + } | |
| 169 | + } | |
| 170 | + | |
| 171 | + @Override | |
| 172 | + public void offline(ParentPlatform parentPlatform) { | |
| 173 | + logger.info("[平台离线]:{}", parentPlatform.getServerGBId()); | |
| 174 | + ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); | |
| 175 | + parentPlatformCatch.setKeepAliveReply(0); | |
| 176 | + parentPlatformCatch.setRegisterAliveReply(0); | |
| 177 | + ParentPlatform parentPlatformInCatch = parentPlatformCatch.getParentPlatform(); | |
| 178 | + parentPlatformInCatch.setStatus(false); | |
| 179 | + parentPlatformCatch.setParentPlatform(parentPlatformInCatch); | |
| 180 | + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | |
| 181 | + platformMapper.updateParentPlatformStatus(parentPlatform.getServerGBId(), false); | |
| 182 | + | |
| 183 | + // 停止所有推流 | |
| 184 | + logger.info("[平台离线] {}, 停止所有推流", parentPlatform.getServerGBId()); | |
| 185 | + stopAllPush(parentPlatform.getServerGBId()); | |
| 186 | + // 清除注册定时 | |
| 187 | + logger.info("[平台离线] {}, 停止定时注册任务", parentPlatform.getServerGBId()); | |
| 188 | + final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId(); | |
| 189 | + if (dynamicTask.contains(registerTaskKey)) { | |
| 190 | + dynamicTask.stop(registerTaskKey); | |
| 191 | + } | |
| 192 | + // 清除心跳定时 | |
| 193 | + logger.info("[平台离线] {}, 停止定时发送心跳任务", parentPlatform.getServerGBId()); | |
| 194 | + final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId(); | |
| 195 | + if (dynamicTask.contains(keepaliveTaskKey)) { | |
| 196 | + // 添加心跳任务 | |
| 197 | + dynamicTask.stop(keepaliveTaskKey); | |
| 198 | + } | |
| 199 | + // 停止目录订阅回复 | |
| 200 | + logger.info("[平台离线] {}, 停止订阅回复", parentPlatform.getServerGBId()); | |
| 201 | + subscribeHolder.removeAllSubscribe(parentPlatform.getServerGBId()); | |
| 202 | + } | |
| 203 | + | |
| 204 | + private void stopAllPush(String platformId) { | |
| 205 | + List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServer(platformId); | |
| 206 | + if (sendRtpItems != null && sendRtpItems.size() > 0) { | |
| 207 | + for (SendRtpItem sendRtpItem : sendRtpItems) { | |
| 208 | + redisCatchStorage.deleteSendRTPServer(platformId, sendRtpItem.getChannelId(), null, null); | |
| 209 | + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | |
| 210 | + Map<String, Object> param = new HashMap<>(3); | |
| 211 | + param.put("vhost", "__defaultVhost__"); | |
| 212 | + param.put("app", sendRtpItem.getApp()); | |
| 213 | + param.put("stream", sendRtpItem.getStreamId()); | |
| 214 | + zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); | |
| 215 | + } | |
| 216 | + | |
| 217 | + } | |
| 218 | + } | |
| 219 | + | |
| 220 | + @Override | |
| 221 | + public void login(ParentPlatform parentPlatform) { | |
| 222 | + final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId(); | |
| 223 | + commanderForPlatform.register(parentPlatform, eventResult1 -> { | |
| 224 | + logger.info("[国标级联] {},开始定时发起注册,间隔为1分钟", parentPlatform.getServerGBId()); | |
| 225 | + // 添加注册任务 | |
| 226 | + dynamicTask.startCron(registerTaskKey, | |
| 227 | + // 注册失败(注册成功时由程序直接调用了online方法) | |
| 228 | + ()->logger.info("[国标级联] {},平台离线后持续发起注册,失败", parentPlatform.getServerGBId()), | |
| 229 | + 60*1000); | |
| 230 | + }, null); | |
| 231 | + } | |
| 232 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
| ... | ... | @@ -37,7 +37,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; |
| 37 | 37 | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; |
| 38 | 38 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 39 | 39 | import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils; |
| 40 | -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | |
| 40 | +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; | |
| 41 | 41 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 42 | 42 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 43 | 43 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| ... | ... | @@ -128,7 +128,7 @@ public class PlayServiceImpl implements IPlayService { |
| 128 | 128 | private DynamicTask dynamicTask; |
| 129 | 129 | |
| 130 | 130 | @Autowired |
| 131 | - private ZLMHttpHookSubscribe subscribe; | |
| 131 | + private ZlmHttpHookSubscribe subscribe; | |
| 132 | 132 | |
| 133 | 133 | |
| 134 | 134 | @Qualifier("taskExecutor") |
| ... | ... | @@ -139,7 +139,7 @@ public class PlayServiceImpl implements IPlayService { |
| 139 | 139 | |
| 140 | 140 | @Override |
| 141 | 141 | public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, |
| 142 | - ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, | |
| 142 | + ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, | |
| 143 | 143 | Runnable timeoutCallback) { |
| 144 | 144 | if (mediaServerItem == null) { |
| 145 | 145 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的zlm"); |
| ... | ... | @@ -222,6 +222,7 @@ public class PlayServiceImpl implements IPlayService { |
| 222 | 222 | streamId = String.format("%s_%s", device.getDeviceId(), channelId); |
| 223 | 223 | } |
| 224 | 224 | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, device.isSsrcCheck(), false); |
| 225 | + logger.info(JSONObject.toJSONString(ssrcInfo)); | |
| 225 | 226 | play(mediaServerItem, ssrcInfo, device, channelId, (mediaServerItemInUse, response)->{ |
| 226 | 227 | if (hookEvent != null) { |
| 227 | 228 | hookEvent.response(mediaServerItem, response); |
| ... | ... | @@ -257,8 +258,8 @@ public class PlayServiceImpl implements IPlayService { |
| 257 | 258 | |
| 258 | 259 | @Override |
| 259 | 260 | public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, |
| 260 | - ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, | |
| 261 | - InviteTimeOutCallback timeoutCallback, String uuid) { | |
| 261 | + ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, | |
| 262 | + InviteTimeOutCallback timeoutCallback, String uuid) { | |
| 262 | 263 | |
| 263 | 264 | String streamId = null; |
| 264 | 265 | if (mediaServerItem.isRtpEnable()) { |
| ... | ... | @@ -333,7 +334,7 @@ public class PlayServiceImpl implements IPlayService { |
| 333 | 334 | // 单端口模式streamId也有变化,需要重新设置监听 |
| 334 | 335 | if (!mediaServerItem.isRtpEnable()) { |
| 335 | 336 | // 添加订阅 |
| 336 | - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtmp", mediaServerItem.getId()); | |
| 337 | + HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId()); | |
| 337 | 338 | subscribe.removeSubscribe(hookSubscribe); |
| 338 | 339 | hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase()); |
| 339 | 340 | subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response)->{ |
| ... | ... | @@ -609,7 +610,7 @@ public class PlayServiceImpl implements IPlayService { |
| 609 | 610 | logger.warn("查询录像信息时发现节点已离线"); |
| 610 | 611 | return null; |
| 611 | 612 | } |
| 612 | - if (mediaServerItem.getRecordAssistPort() != 0) { | |
| 613 | + if (mediaServerItem.getRecordAssistPort() > 0) { | |
| 613 | 614 | JSONObject jsonObject = assistRESTfulUtils.fileDuration(mediaServerItem, streamInfo.getApp(), streamInfo.getStream(), null); |
| 614 | 615 | if (jsonObject != null && jsonObject.getInteger("code") == 0) { |
| 615 | 616 | long duration = jsonObject.getLong("data"); |
| ... | ... | @@ -802,7 +803,7 @@ public class PlayServiceImpl implements IPlayService { |
| 802 | 803 | // for (SendRtpItem sendRtpItem : sendRtpItems) { |
| 803 | 804 | // if (sendRtpItem.getMediaServerId().equals(mediaServerId)) { |
| 804 | 805 | // if (mediaListMap.get(sendRtpItem.getStreamId()) == null) { |
| 805 | -// ParentPlatform platform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); | |
| 806 | +// ParentPlatform platform = storager.queryPlatformByServerGBId(sendRtpItem.getPlatformId()); | |
| 806 | 807 | // sipCommanderFroPlatform.streamByeCmd(platform, sendRtpItem.getCallId()); |
| 807 | 808 | // } |
| 808 | 809 | // } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java
| ... | ... | @@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSON; |
| 4 | 4 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
| 6 | 6 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 7 | +import com.genersoft.iot.vmp.service.IPlatformChannelService; | |
| 8 | +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | |
| 7 | 9 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 8 | 10 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 9 | 11 | import org.slf4j.Logger; |
| ... | ... | @@ -12,6 +14,9 @@ import org.springframework.beans.factory.annotation.Autowired; |
| 12 | 14 | import org.springframework.data.redis.connection.Message; |
| 13 | 15 | import org.springframework.data.redis.connection.MessageListener; |
| 14 | 16 | import org.springframework.stereotype.Component; |
| 17 | +import org.springframework.util.ObjectUtils; | |
| 18 | + | |
| 19 | +import java.util.List; | |
| 15 | 20 | |
| 16 | 21 | |
| 17 | 22 | @Component |
| ... | ... | @@ -37,8 +42,6 @@ public class RedisAlarmMsgListener implements MessageListener { |
| 37 | 42 | return; |
| 38 | 43 | } |
| 39 | 44 | String gbId = alarmChannelMessage.getGbId(); |
| 40 | - Device device = storage.queryVideoDevice(gbId); | |
| 41 | - ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId); | |
| 42 | 45 | |
| 43 | 46 | DeviceAlarm deviceAlarm = new DeviceAlarm(); |
| 44 | 47 | deviceAlarm.setCreateTime(DateUtil.getNow()); |
| ... | ... | @@ -46,18 +49,29 @@ public class RedisAlarmMsgListener implements MessageListener { |
| 46 | 49 | deviceAlarm.setAlarmDescription(alarmChannelMessage.getAlarmDescription()); |
| 47 | 50 | deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn()); |
| 48 | 51 | deviceAlarm.setAlarmPriority("1"); |
| 49 | - deviceAlarm.setAlarmTime(DateUtil.getNow()); | |
| 52 | + deviceAlarm.setAlarmTime(DateUtil.getNowForISO8601()); | |
| 50 | 53 | deviceAlarm.setAlarmType("1"); |
| 51 | 54 | deviceAlarm.setLongitude(0); |
| 52 | 55 | deviceAlarm.setLatitude(0); |
| 53 | 56 | |
| 54 | - | |
| 55 | - if (device != null && platform == null) { | |
| 56 | - commander.sendAlarmMessage(device, deviceAlarm); | |
| 57 | - }else if (device == null && platform != null){ | |
| 58 | - commanderForPlatform.sendAlarmMessage(platform, deviceAlarm); | |
| 57 | + if (ObjectUtils.isEmpty(gbId)) { | |
| 58 | + // 发送给所有的上级 | |
| 59 | + List<ParentPlatform> parentPlatforms = storage.queryEnableParentPlatformList(true); | |
| 60 | + if (parentPlatforms.size() > 0) { | |
| 61 | + for (ParentPlatform parentPlatform : parentPlatforms) { | |
| 62 | + commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm); | |
| 63 | + } | |
| 64 | + } | |
| 59 | 65 | }else { |
| 60 | - logger.warn("无法确定" + gbId + "是平台还是设备"); | |
| 66 | + Device device = storage.queryVideoDevice(gbId); | |
| 67 | + ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId); | |
| 68 | + if (device != null && platform == null) { | |
| 69 | + commander.sendAlarmMessage(device, deviceAlarm); | |
| 70 | + }else if (device == null && platform != null){ | |
| 71 | + commanderForPlatform.sendAlarmMessage(platform, deviceAlarm); | |
| 72 | + }else { | |
| 73 | + logger.warn("无法确定" + gbId + "是平台还是设备"); | |
| 74 | + } | |
| 61 | 75 | } |
| 62 | 76 | } |
| 63 | 77 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java
| ... | ... | @@ -5,12 +5,11 @@ import com.alibaba.fastjson.JSONObject; |
| 5 | 5 | import com.genersoft.iot.vmp.conf.DynamicTask; |
| 6 | 6 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 7 | 7 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| 8 | -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | |
| 8 | +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; | |
| 9 | 9 | import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; |
| 10 | 10 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 11 | 11 | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; |
| 12 | 12 | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; |
| 13 | -import com.genersoft.iot.vmp.media.zlm.dto.HookType; | |
| 14 | 13 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 15 | 14 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 16 | 15 | import com.genersoft.iot.vmp.service.bean.*; |
| ... | ... | @@ -24,9 +23,6 @@ import org.springframework.data.redis.connection.Message; |
| 24 | 23 | import org.springframework.data.redis.connection.MessageListener; |
| 25 | 24 | import org.springframework.stereotype.Component; |
| 26 | 25 | |
| 27 | -import javax.sip.InvalidArgumentException; | |
| 28 | -import javax.sip.SipException; | |
| 29 | -import java.text.ParseException; | |
| 30 | 26 | import java.util.HashMap; |
| 31 | 27 | import java.util.Map; |
| 32 | 28 | import java.util.UUID; |
| ... | ... | @@ -86,7 +82,7 @@ public class RedisGbPlayMsgListener implements MessageListener { |
| 86 | 82 | private ZLMMediaListManager mediaListManager; |
| 87 | 83 | |
| 88 | 84 | @Autowired |
| 89 | - private ZLMHttpHookSubscribe subscribe; | |
| 85 | + private ZlmHttpHookSubscribe subscribe; | |
| 90 | 86 | |
| 91 | 87 | |
| 92 | 88 | public interface PlayMsgCallback{ |
| ... | ... | @@ -271,7 +267,7 @@ public class RedisGbPlayMsgListener implements MessageListener { |
| 271 | 267 | }, userSetting.getPlatformPlayTimeout()); |
| 272 | 268 | |
| 273 | 269 | // 添加订阅 |
| 274 | - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(content.getApp(), content.getStream(), true, "rtmp", mediaServerItem.getId()); | |
| 270 | + HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(content.getApp(), content.getStream(), true, "rtsp", mediaServerItem.getId()); | |
| 275 | 271 | |
| 276 | 272 | subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json)->{ |
| 277 | 273 | dynamicTask.stop(taskKey); | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
| ... | ... | @@ -295,7 +295,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService { |
| 295 | 295 | if (jsonObject == null) { |
| 296 | 296 | return false; |
| 297 | 297 | } |
| 298 | - System.out.println(jsonObject); | |
| 299 | 298 | if (jsonObject.getInteger("code") == 0) { |
| 300 | 299 | result = true; |
| 301 | 300 | streamProxy.setEnable(true); |
| ... | ... | @@ -421,7 +420,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { |
| 421 | 420 | if(data != null && data.size() > 0) { |
| 422 | 421 | for (int i = 0; i < data.size(); i++) { |
| 423 | 422 | JSONObject streamJSONObj = data.getJSONObject(i); |
| 424 | - if ("rtmp".equals(streamJSONObj.getString("schema"))) { | |
| 423 | + if ("rtsp".equals(streamJSONObj.getString("schema"))) { | |
| 425 | 424 | StreamInfo streamInfo = new StreamInfo(); |
| 426 | 425 | String app = streamJSONObj.getString("app"); |
| 427 | 426 | String stream = streamJSONObj.getString("stream"); | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
| ... | ... | @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; |
| 8 | 8 | import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; |
| 9 | 9 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| 10 | 10 | import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; |
| 11 | +import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; | |
| 11 | 12 | |
| 12 | 13 | import java.util.List; |
| 13 | 14 | import java.util.Map; |
| ... | ... | @@ -61,17 +62,13 @@ public interface IRedisCatchStorage { |
| 61 | 62 | |
| 62 | 63 | void delPlatformCatchInfo(String platformGbId); |
| 63 | 64 | |
| 64 | - void updatePlatformKeepalive(ParentPlatform parentPlatform); | |
| 65 | - | |
| 66 | 65 | void delPlatformKeepalive(String platformGbId); |
| 67 | 66 | |
| 68 | - void updatePlatformRegister(ParentPlatform parentPlatform); | |
| 69 | - | |
| 70 | 67 | void delPlatformRegister(String platformGbId); |
| 71 | 68 | |
| 72 | - void updatePlatformRegisterInfo(String callId, String platformGbId); | |
| 69 | + void updatePlatformRegisterInfo(String callId, PlatformRegisterInfo platformRegisterInfo); | |
| 73 | 70 | |
| 74 | - String queryPlatformRegisterInfo(String callId); | |
| 71 | + PlatformRegisterInfo queryPlatformRegisterInfo(String callId); | |
| 75 | 72 | |
| 76 | 73 | void delPlatformRegisterInfo(String callId); |
| 77 | 74 | |
| ... | ... | @@ -237,4 +234,6 @@ public interface IRedisCatchStorage { |
| 237 | 234 | * 发送redis消息 查询所有推流设备的状态 |
| 238 | 235 | */ |
| 239 | 236 | void sendStreamPushRequestedMsgForStatus(); |
| 237 | + | |
| 238 | + List<SendRtpItem> querySendRTPServerByChnnelId(String channelId); | |
| 240 | 239 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java
| ... | ... | @@ -170,15 +170,6 @@ public interface IVideoManagerStorage { |
| 170 | 170 | */ |
| 171 | 171 | boolean deleteParentPlatform(ParentPlatform parentPlatform); |
| 172 | 172 | |
| 173 | - | |
| 174 | - /** | |
| 175 | - * 分页获取上级平台 | |
| 176 | - * @param page | |
| 177 | - * @param count | |
| 178 | - * @return | |
| 179 | - */ | |
| 180 | - PageInfo<ParentPlatform> queryParentPlatformList(int page, int count); | |
| 181 | - | |
| 182 | 173 | /** |
| 183 | 174 | * 获取所有已启用的平台 |
| 184 | 175 | * @return | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/dto/PlatformRegisterInfo.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.storager.dao.dto; | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * 平台发送注册/注销消息时缓存此消息 | |
| 5 | + * @author lin | |
| 6 | + */ | |
| 7 | +public class PlatformRegisterInfo { | |
| 8 | + | |
| 9 | + /** | |
| 10 | + * 平台Id | |
| 11 | + */ | |
| 12 | + private String platformId; | |
| 13 | + | |
| 14 | + /** | |
| 15 | + * 是否时注册,false为注销 | |
| 16 | + */ | |
| 17 | + private boolean register; | |
| 18 | + | |
| 19 | + public static PlatformRegisterInfo getInstance(String platformId, boolean register) { | |
| 20 | + PlatformRegisterInfo platformRegisterInfo = new PlatformRegisterInfo(); | |
| 21 | + platformRegisterInfo.setPlatformId(platformId); | |
| 22 | + platformRegisterInfo.setRegister(register); | |
| 23 | + return platformRegisterInfo; | |
| 24 | + } | |
| 25 | + | |
| 26 | + public String getPlatformId() { | |
| 27 | + return platformId; | |
| 28 | + } | |
| 29 | + | |
| 30 | + public void setPlatformId(String platformId) { | |
| 31 | + this.platformId = platformId; | |
| 32 | + } | |
| 33 | + | |
| 34 | + public boolean isRegister() { | |
| 35 | + return register; | |
| 36 | + } | |
| 37 | + | |
| 38 | + public void setRegister(boolean register) { | |
| 39 | + this.register = register; | |
| 40 | + } | |
| 41 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
| ... | ... | @@ -16,11 +16,13 @@ import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; |
| 16 | 16 | import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; |
| 17 | 17 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 18 | 18 | import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; |
| 19 | +import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; | |
| 19 | 20 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 20 | 21 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| 21 | 22 | import org.slf4j.Logger; |
| 22 | 23 | import org.slf4j.LoggerFactory; |
| 23 | 24 | import org.springframework.beans.factory.annotation.Autowired; |
| 25 | +import org.springframework.context.annotation.DependsOn; | |
| 24 | 26 | import org.springframework.stereotype.Component; |
| 25 | 27 | |
| 26 | 28 | import java.util.*; |
| ... | ... | @@ -290,18 +292,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { |
| 290 | 292 | } |
| 291 | 293 | |
| 292 | 294 | @Override |
| 293 | - public void updatePlatformKeepalive(ParentPlatform parentPlatform) { | |
| 294 | - String key = VideoManagerConstants.PLATFORM_KEEPALIVE_PREFIX + userSetting.getServerId() + "_" + parentPlatform.getServerGBId(); | |
| 295 | - RedisUtil.set(key, "", Integer.parseInt(parentPlatform.getKeepTimeout())); | |
| 296 | - } | |
| 297 | - | |
| 298 | - @Override | |
| 299 | - public void updatePlatformRegister(ParentPlatform parentPlatform) { | |
| 300 | - String key = VideoManagerConstants.PLATFORM_REGISTER_PREFIX + userSetting.getServerId() + "_" + parentPlatform.getServerGBId(); | |
| 301 | - RedisUtil.set(key, "", Integer.parseInt(parentPlatform.getExpires())); | |
| 302 | - } | |
| 303 | - | |
| 304 | - @Override | |
| 305 | 295 | public ParentPlatformCatch queryPlatformCatchInfo(String platformGbId) { |
| 306 | 296 | return (ParentPlatformCatch)RedisUtil.get(VideoManagerConstants.PLATFORM_CATCH_PREFIX + userSetting.getServerId() + "_" + platformGbId); |
| 307 | 297 | } |
| ... | ... | @@ -323,15 +313,15 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { |
| 323 | 313 | |
| 324 | 314 | |
| 325 | 315 | @Override |
| 326 | - public void updatePlatformRegisterInfo(String callId, String platformGbId) { | |
| 316 | + public void updatePlatformRegisterInfo(String callId, PlatformRegisterInfo platformRegisterInfo) { | |
| 327 | 317 | String key = VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_" + callId; |
| 328 | - RedisUtil.set(key, platformGbId, 30); | |
| 318 | + RedisUtil.set(key, platformRegisterInfo, 30); | |
| 329 | 319 | } |
| 330 | 320 | |
| 331 | 321 | |
| 332 | 322 | @Override |
| 333 | - public String queryPlatformRegisterInfo(String callId) { | |
| 334 | - return (String)RedisUtil.get(VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_" + callId); | |
| 323 | + public PlatformRegisterInfo queryPlatformRegisterInfo(String callId) { | |
| 324 | + return (PlatformRegisterInfo)RedisUtil.get(VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_" + callId); | |
| 335 | 325 | } |
| 336 | 326 | |
| 337 | 327 | @Override |
| ... | ... | @@ -380,6 +370,24 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { |
| 380 | 370 | } |
| 381 | 371 | |
| 382 | 372 | @Override |
| 373 | + public List<SendRtpItem> querySendRTPServerByChnnelId(String channelId) { | |
| 374 | + if (channelId == null) { | |
| 375 | + return null; | |
| 376 | + } | |
| 377 | + String platformGbId = "*"; | |
| 378 | + String callId = "*"; | |
| 379 | + String streamId = "*"; | |
| 380 | + String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetting.getServerId() + "_" + platformGbId | |
| 381 | + + "_" + channelId + "_" + streamId + "_" + callId; | |
| 382 | + List<Object> scan = RedisUtil.scan(key); | |
| 383 | + List<SendRtpItem> result = new ArrayList<>(); | |
| 384 | + for (Object o : scan) { | |
| 385 | + result.add((SendRtpItem) RedisUtil.get((String) o)); | |
| 386 | + } | |
| 387 | + return result; | |
| 388 | + } | |
| 389 | + | |
| 390 | + @Override | |
| 383 | 391 | public List<SendRtpItem> querySendRTPServer(String platformGbId) { |
| 384 | 392 | if (platformGbId == null) { |
| 385 | 393 | platformGbId = "*"; | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java
| ... | ... | @@ -458,13 +458,6 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { |
| 458 | 458 | } |
| 459 | 459 | |
| 460 | 460 | @Override |
| 461 | - public PageInfo<ParentPlatform> queryParentPlatformList(int page, int count) { | |
| 462 | - PageHelper.startPage(page, count); | |
| 463 | - List<ParentPlatform> all = platformMapper.getParentPlatformList(); | |
| 464 | - return new PageInfo<>(all); | |
| 465 | - } | |
| 466 | - | |
| 467 | - @Override | |
| 468 | 461 | public ParentPlatform queryParentPlatByServerGBId(String platformGbId) { |
| 469 | 462 | return platformMapper.getParentPlatByServerGBId(platformGbId); |
| 470 | 463 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java
src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java
| ... | ... | @@ -33,11 +33,11 @@ public class SpringBeanFactory implements ApplicationContextAware { |
| 33 | 33 | /** |
| 34 | 34 | * 获取对象 这里重写了bean方法,起主要作用 |
| 35 | 35 | */ |
| 36 | - public static Object getBean(String beanId) throws BeansException { | |
| 36 | + public static <T> T getBean(String beanId) throws BeansException { | |
| 37 | 37 | if (applicationContext == null) { |
| 38 | 38 | return null; |
| 39 | 39 | } |
| 40 | - return applicationContext.getBean(beanId); | |
| 40 | + return (T) applicationContext.getBean(beanId); | |
| 41 | 41 | } |
| 42 | 42 | |
| 43 | 43 | /** | ... | ... |
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
| ... | ... | @@ -5,15 +5,14 @@ import java.util.concurrent.TimeUnit; |
| 5 | 5 | |
| 6 | 6 | import com.alibaba.fastjson.JSONObject; |
| 7 | 7 | import com.genersoft.iot.vmp.utils.SpringBeanFactory; |
| 8 | -import org.springframework.beans.factory.annotation.Autowired; | |
| 8 | +import gov.nist.javax.sip.stack.UDPMessageChannel; | |
| 9 | 9 | import org.springframework.data.redis.core.*; |
| 10 | -import org.springframework.stereotype.Component; | |
| 11 | 10 | import org.springframework.util.CollectionUtils; |
| 12 | 11 | |
| 13 | 12 | /** |
| 14 | - * @description:Redis工具类 | |
| 15 | - * @author: swwheihei | |
| 16 | - * @date: 2020年5月6日 下午8:27:29 | |
| 13 | + * Redis工具类 | |
| 14 | + * @author swwheihei | |
| 15 | + * @date 2020年5月6日 下午8:27:29 | |
| 17 | 16 | */ |
| 18 | 17 | @SuppressWarnings(value = {"rawtypes", "unchecked"}) |
| 19 | 18 | public class RedisUtil { |
| ... | ... | @@ -21,9 +20,9 @@ public class RedisUtil { |
| 21 | 20 | private static RedisTemplate redisTemplate; |
| 22 | 21 | |
| 23 | 22 | static { |
| 24 | - redisTemplate = (RedisTemplate)SpringBeanFactory.getBean("redisTemplate"); | |
| 23 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 25 | 24 | } |
| 26 | - | |
| 25 | + | |
| 27 | 26 | /** |
| 28 | 27 | * 指定缓存失效时间 |
| 29 | 28 | * @param key 键 |
| ... | ... | @@ -31,6 +30,9 @@ public class RedisUtil { |
| 31 | 30 | * @return true / false |
| 32 | 31 | */ |
| 33 | 32 | public static boolean expire(String key, long time) { |
| 33 | + if (redisTemplate == null) { | |
| 34 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 35 | + } | |
| 34 | 36 | try { |
| 35 | 37 | if (time > 0) { |
| 36 | 38 | redisTemplate.expire(key, time, TimeUnit.SECONDS); |
| ... | ... | @@ -45,9 +47,11 @@ public class RedisUtil { |
| 45 | 47 | /** |
| 46 | 48 | * 根据 key 获取过期时间 |
| 47 | 49 | * @param key 键 |
| 48 | - * @return | |
| 49 | 50 | */ |
| 50 | 51 | public static long getExpire(String key) { |
| 52 | + if (redisTemplate == null) { | |
| 53 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 54 | + } | |
| 51 | 55 | return redisTemplate.getExpire(key, TimeUnit.SECONDS); |
| 52 | 56 | } |
| 53 | 57 | |
| ... | ... | @@ -57,6 +61,9 @@ public class RedisUtil { |
| 57 | 61 | * @return true / false |
| 58 | 62 | */ |
| 59 | 63 | public static boolean hasKey(String key) { |
| 64 | + if (redisTemplate == null) { | |
| 65 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 66 | + } | |
| 60 | 67 | try { |
| 61 | 68 | return redisTemplate.hasKey(key); |
| 62 | 69 | } catch (Exception e) { |
| ... | ... | @@ -71,6 +78,9 @@ public class RedisUtil { |
| 71 | 78 | * @param key 键(一个或者多个) |
| 72 | 79 | */ |
| 73 | 80 | public static boolean del(String... key) { |
| 81 | + if (redisTemplate == null) { | |
| 82 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 83 | + } | |
| 74 | 84 | try { |
| 75 | 85 | if (key != null && key.length > 0) { |
| 76 | 86 | if (key.length == 1) { |
| ... | ... | @@ -95,6 +105,9 @@ public class RedisUtil { |
| 95 | 105 | * @return 值 |
| 96 | 106 | */ |
| 97 | 107 | public static Object get(String key) { |
| 108 | + if (redisTemplate == null) { | |
| 109 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 110 | + } | |
| 98 | 111 | return key == null ? null : redisTemplate.opsForValue().get(key); |
| 99 | 112 | } |
| 100 | 113 | |
| ... | ... | @@ -105,6 +118,9 @@ public class RedisUtil { |
| 105 | 118 | * @return true / false |
| 106 | 119 | */ |
| 107 | 120 | public static boolean set(String key, Object value) { |
| 121 | + if (redisTemplate == null) { | |
| 122 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 123 | + } | |
| 108 | 124 | try { |
| 109 | 125 | redisTemplate.opsForValue().set(key, value); |
| 110 | 126 | return true; |
| ... | ... | @@ -122,6 +138,9 @@ public class RedisUtil { |
| 122 | 138 | * @return true / false |
| 123 | 139 | */ |
| 124 | 140 | public static boolean set(String key, Object value, long time) { |
| 141 | + if (redisTemplate == null) { | |
| 142 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 143 | + } | |
| 125 | 144 | try { |
| 126 | 145 | if (time > 0) { |
| 127 | 146 | redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); |
| ... | ... | @@ -142,6 +161,9 @@ public class RedisUtil { |
| 142 | 161 | * @return |
| 143 | 162 | */ |
| 144 | 163 | public static long incr(String key, long delta) { |
| 164 | + if (redisTemplate == null) { | |
| 165 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 166 | + } | |
| 145 | 167 | if (delta < 0) { |
| 146 | 168 | throw new RuntimeException("递增因子必须大于 0"); |
| 147 | 169 | } |
| ... | ... | @@ -155,6 +177,9 @@ public class RedisUtil { |
| 155 | 177 | * @return |
| 156 | 178 | */ |
| 157 | 179 | public static long decr(String key, long delta) { |
| 180 | + if (redisTemplate == null) { | |
| 181 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 182 | + } | |
| 158 | 183 | if (delta < 0) { |
| 159 | 184 | throw new RuntimeException("递减因子必须大于 0"); |
| 160 | 185 | } |
| ... | ... | @@ -170,6 +195,9 @@ public class RedisUtil { |
| 170 | 195 | * @return 值 |
| 171 | 196 | */ |
| 172 | 197 | public static Object hget(String key, String item) { |
| 198 | + if (redisTemplate == null) { | |
| 199 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 200 | + } | |
| 173 | 201 | return redisTemplate.opsForHash().get(key, item); |
| 174 | 202 | } |
| 175 | 203 | |
| ... | ... | @@ -179,6 +207,9 @@ public class RedisUtil { |
| 179 | 207 | * @return 对应的多个键值 |
| 180 | 208 | */ |
| 181 | 209 | public static Map<Object, Object> hmget(String key) { |
| 210 | + if (redisTemplate == null) { | |
| 211 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 212 | + } | |
| 182 | 213 | return redisTemplate.opsForHash().entries(key); |
| 183 | 214 | } |
| 184 | 215 | |
| ... | ... | @@ -189,6 +220,9 @@ public class RedisUtil { |
| 189 | 220 | * @return true / false |
| 190 | 221 | */ |
| 191 | 222 | public static boolean hmset(String key, Map<Object, Object> map) { |
| 223 | + if (redisTemplate == null) { | |
| 224 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 225 | + } | |
| 192 | 226 | try { |
| 193 | 227 | redisTemplate.opsForHash().putAll(key, map); |
| 194 | 228 | return true; |
| ... | ... | @@ -206,6 +240,9 @@ public class RedisUtil { |
| 206 | 240 | * @return true / false |
| 207 | 241 | */ |
| 208 | 242 | public static boolean hmset(String key, Map<Object, Object> map, long time) { |
| 243 | + if (redisTemplate == null) { | |
| 244 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 245 | + } | |
| 209 | 246 | try { |
| 210 | 247 | redisTemplate.opsForHash().putAll(key, map); |
| 211 | 248 | if (time > 0) { |
| ... | ... | @@ -226,6 +263,9 @@ public class RedisUtil { |
| 226 | 263 | * @return true / false |
| 227 | 264 | */ |
| 228 | 265 | public static boolean hset(String key, String item, Object value) { |
| 266 | + if (redisTemplate == null) { | |
| 267 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 268 | + } | |
| 229 | 269 | try { |
| 230 | 270 | redisTemplate.opsForHash().put(key, item, value); |
| 231 | 271 | return true; |
| ... | ... | @@ -244,6 +284,9 @@ public class RedisUtil { |
| 244 | 284 | * @return true / false |
| 245 | 285 | */ |
| 246 | 286 | public static boolean hset(String key, String item, Object value, long time) { |
| 287 | + if (redisTemplate == null) { | |
| 288 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 289 | + } | |
| 247 | 290 | try { |
| 248 | 291 | redisTemplate.opsForHash().put(key, item, value); |
| 249 | 292 | if (time > 0) { |
| ... | ... | @@ -262,6 +305,9 @@ public class RedisUtil { |
| 262 | 305 | * @param item 项(可以多个,no null) |
| 263 | 306 | */ |
| 264 | 307 | public static void hdel(String key, Object... item) { |
| 308 | + if (redisTemplate == null) { | |
| 309 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 310 | + } | |
| 265 | 311 | redisTemplate.opsForHash().delete(key, item); |
| 266 | 312 | } |
| 267 | 313 | |
| ... | ... | @@ -272,6 +318,9 @@ public class RedisUtil { |
| 272 | 318 | * @return true / false |
| 273 | 319 | */ |
| 274 | 320 | public static boolean hHasKey(String key, String item) { |
| 321 | + if (redisTemplate == null) { | |
| 322 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 323 | + } | |
| 275 | 324 | return redisTemplate.opsForHash().hasKey(key, item); |
| 276 | 325 | } |
| 277 | 326 | |
| ... | ... | @@ -283,6 +332,9 @@ public class RedisUtil { |
| 283 | 332 | * @return |
| 284 | 333 | */ |
| 285 | 334 | public static Double hincr(String key, String item, Double by) { |
| 335 | + if (redisTemplate == null) { | |
| 336 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 337 | + } | |
| 286 | 338 | return redisTemplate.opsForHash().increment(key, item, by); |
| 287 | 339 | } |
| 288 | 340 | |
| ... | ... | @@ -294,6 +346,9 @@ public class RedisUtil { |
| 294 | 346 | * @return |
| 295 | 347 | */ |
| 296 | 348 | public static Double hdecr(String key, String item, Double by) { |
| 349 | + if (redisTemplate == null) { | |
| 350 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 351 | + } | |
| 297 | 352 | return redisTemplate.opsForHash().increment(key, item, -by); |
| 298 | 353 | } |
| 299 | 354 | |
| ... | ... | @@ -305,6 +360,9 @@ public class RedisUtil { |
| 305 | 360 | * @return 值 |
| 306 | 361 | */ |
| 307 | 362 | public static Set<Object> sGet(String key) { |
| 363 | + if (redisTemplate == null) { | |
| 364 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 365 | + } | |
| 308 | 366 | try { |
| 309 | 367 | return redisTemplate.opsForSet().members(key); |
| 310 | 368 | } catch (Exception e) { |
| ... | ... | @@ -320,6 +378,9 @@ public class RedisUtil { |
| 320 | 378 | * @return true / false |
| 321 | 379 | */ |
| 322 | 380 | public static boolean sHasKey(String key, Object value) { |
| 381 | + if (redisTemplate == null) { | |
| 382 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 383 | + } | |
| 323 | 384 | try { |
| 324 | 385 | return redisTemplate.opsForSet().isMember(key, value); |
| 325 | 386 | } catch (Exception e) { |
| ... | ... | @@ -335,6 +396,9 @@ public class RedisUtil { |
| 335 | 396 | * @return 成功个数 |
| 336 | 397 | */ |
| 337 | 398 | public static long sSet(String key, Object... values) { |
| 399 | + if (redisTemplate == null) { | |
| 400 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 401 | + } | |
| 338 | 402 | try { |
| 339 | 403 | return redisTemplate.opsForSet().add(key, values); |
| 340 | 404 | } catch (Exception e) { |
| ... | ... | @@ -351,6 +415,9 @@ public class RedisUtil { |
| 351 | 415 | * @return 成功放入个数 |
| 352 | 416 | */ |
| 353 | 417 | public static long sSet(String key, long time, Object... values) { |
| 418 | + if (redisTemplate == null) { | |
| 419 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 420 | + } | |
| 354 | 421 | try { |
| 355 | 422 | long count = redisTemplate.opsForSet().add(key, values); |
| 356 | 423 | if (time > 0) { |
| ... | ... | @@ -369,6 +436,9 @@ public class RedisUtil { |
| 369 | 436 | * @return 长度 |
| 370 | 437 | */ |
| 371 | 438 | public static long sGetSetSize(String key) { |
| 439 | + if (redisTemplate == null) { | |
| 440 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 441 | + } | |
| 372 | 442 | try { |
| 373 | 443 | return redisTemplate.opsForSet().size(key); |
| 374 | 444 | } catch (Exception e) { |
| ... | ... | @@ -384,6 +454,9 @@ public class RedisUtil { |
| 384 | 454 | * @return 成功移除个数 |
| 385 | 455 | */ |
| 386 | 456 | public static long setRemove(String key, Object... values) { |
| 457 | + if (redisTemplate == null) { | |
| 458 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 459 | + } | |
| 387 | 460 | try { |
| 388 | 461 | return redisTemplate.opsForSet().remove(key, values); |
| 389 | 462 | } catch (Exception e) { |
| ... | ... | @@ -401,6 +474,9 @@ public class RedisUtil { |
| 401 | 474 | * @param score |
| 402 | 475 | */ |
| 403 | 476 | public static void zAdd(Object key, Object value, double score) { |
| 477 | + if (redisTemplate == null) { | |
| 478 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 479 | + } | |
| 404 | 480 | redisTemplate.opsForZSet().add(key, value, score); |
| 405 | 481 | } |
| 406 | 482 | |
| ... | ... | @@ -411,6 +487,9 @@ public class RedisUtil { |
| 411 | 487 | * @param value |
| 412 | 488 | */ |
| 413 | 489 | public static void zRemove(Object key, Object value) { |
| 490 | + if (redisTemplate == null) { | |
| 491 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 492 | + } | |
| 414 | 493 | redisTemplate.opsForZSet().remove(key, value); |
| 415 | 494 | } |
| 416 | 495 | |
| ... | ... | @@ -422,6 +501,9 @@ public class RedisUtil { |
| 422 | 501 | * @param delta -1 表示减 1 表示加1 |
| 423 | 502 | */ |
| 424 | 503 | public static Double zIncrScore(Object key, Object value, double delta) { |
| 504 | + if (redisTemplate == null) { | |
| 505 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 506 | + } | |
| 425 | 507 | return redisTemplate.opsForZSet().incrementScore(key, value, delta); |
| 426 | 508 | } |
| 427 | 509 | |
| ... | ... | @@ -433,6 +515,9 @@ public class RedisUtil { |
| 433 | 515 | * @return |
| 434 | 516 | */ |
| 435 | 517 | public static Double zScore(Object key, Object value) { |
| 518 | + if (redisTemplate == null) { | |
| 519 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 520 | + } | |
| 436 | 521 | return redisTemplate.opsForZSet().score(key, value); |
| 437 | 522 | } |
| 438 | 523 | |
| ... | ... | @@ -444,6 +529,9 @@ public class RedisUtil { |
| 444 | 529 | * @return |
| 445 | 530 | */ |
| 446 | 531 | public static Long zRank(Object key, Object value) { |
| 532 | + if (redisTemplate == null) { | |
| 533 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 534 | + } | |
| 447 | 535 | return redisTemplate.opsForZSet().rank(key, value); |
| 448 | 536 | } |
| 449 | 537 | |
| ... | ... | @@ -454,6 +542,9 @@ public class RedisUtil { |
| 454 | 542 | * @return |
| 455 | 543 | */ |
| 456 | 544 | public static Long zSize(Object key) { |
| 545 | + if (redisTemplate == null) { | |
| 546 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 547 | + } | |
| 457 | 548 | return redisTemplate.opsForZSet().zCard(key); |
| 458 | 549 | } |
| 459 | 550 | |
| ... | ... | @@ -467,7 +558,10 @@ public class RedisUtil { |
| 467 | 558 | * @param end |
| 468 | 559 | * @return |
| 469 | 560 | */ |
| 470 | - public static Set<Object> ZRange(Object key, int start, int end) { | |
| 561 | + public static Set<Object> zRange(Object key, int start, int end) { | |
| 562 | + if (redisTemplate == null) { | |
| 563 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 564 | + } | |
| 471 | 565 | return redisTemplate.opsForZSet().range(key, start, end); |
| 472 | 566 | } |
| 473 | 567 | /** |
| ... | ... | @@ -479,6 +573,9 @@ public class RedisUtil { |
| 479 | 573 | * @return |
| 480 | 574 | */ |
| 481 | 575 | public static Set<ZSetOperations.TypedTuple<String>> zRangeWithScore(Object key, int start, int end) { |
| 576 | + if (redisTemplate == null) { | |
| 577 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 578 | + } | |
| 482 | 579 | return redisTemplate.opsForZSet().rangeWithScores(key, start, end); |
| 483 | 580 | } |
| 484 | 581 | /** |
| ... | ... | @@ -492,6 +589,9 @@ public class RedisUtil { |
| 492 | 589 | * @return |
| 493 | 590 | */ |
| 494 | 591 | public static Set<String> zRevRange(Object key, int start, int end) { |
| 592 | + if (redisTemplate == null) { | |
| 593 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 594 | + } | |
| 495 | 595 | return redisTemplate.opsForZSet().reverseRange(key, start, end); |
| 496 | 596 | } |
| 497 | 597 | /** |
| ... | ... | @@ -503,6 +603,9 @@ public class RedisUtil { |
| 503 | 603 | * @return |
| 504 | 604 | */ |
| 505 | 605 | public static Set<String> zSortRange(Object key, int min, int max) { |
| 606 | + if (redisTemplate == null) { | |
| 607 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 608 | + } | |
| 506 | 609 | return redisTemplate.opsForZSet().rangeByScore(key, min, max); |
| 507 | 610 | } |
| 508 | 611 | |
| ... | ... | @@ -517,6 +620,9 @@ public class RedisUtil { |
| 517 | 620 | * @return |
| 518 | 621 | */ |
| 519 | 622 | public static List<Object> lGet(String key, long start, long end) { |
| 623 | + if (redisTemplate == null) { | |
| 624 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 625 | + } | |
| 520 | 626 | try { |
| 521 | 627 | return redisTemplate.opsForList().range(key, start, end); |
| 522 | 628 | } catch (Exception e) { |
| ... | ... | @@ -531,6 +637,9 @@ public class RedisUtil { |
| 531 | 637 | * @return 长度 |
| 532 | 638 | */ |
| 533 | 639 | public static long lGetListSize(String key) { |
| 640 | + if (redisTemplate == null) { | |
| 641 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 642 | + } | |
| 534 | 643 | try { |
| 535 | 644 | return redisTemplate.opsForList().size(key); |
| 536 | 645 | } catch (Exception e) { |
| ... | ... | @@ -548,6 +657,9 @@ public class RedisUtil { |
| 548 | 657 | * @return 值 |
| 549 | 658 | */ |
| 550 | 659 | public static Object lGetIndex(String key, long index) { |
| 660 | + if (redisTemplate == null) { | |
| 661 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 662 | + } | |
| 551 | 663 | try { |
| 552 | 664 | return redisTemplate.opsForList().index(key, index); |
| 553 | 665 | } catch (Exception e) { |
| ... | ... | @@ -563,6 +675,9 @@ public class RedisUtil { |
| 563 | 675 | * @return true / false |
| 564 | 676 | */ |
| 565 | 677 | public static boolean lSet(String key, Object value) { |
| 678 | + if (redisTemplate == null) { | |
| 679 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 680 | + } | |
| 566 | 681 | try { |
| 567 | 682 | redisTemplate.opsForList().rightPush(key, value); |
| 568 | 683 | return true; |
| ... | ... | @@ -580,6 +695,9 @@ public class RedisUtil { |
| 580 | 695 | * @return true / false |
| 581 | 696 | */ |
| 582 | 697 | public static boolean lSet(String key, Object value, long time) { |
| 698 | + if (redisTemplate == null) { | |
| 699 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 700 | + } | |
| 583 | 701 | try { |
| 584 | 702 | redisTemplate.opsForList().rightPush(key, value); |
| 585 | 703 | if (time > 0) { |
| ... | ... | @@ -599,6 +717,9 @@ public class RedisUtil { |
| 599 | 717 | * @return true / false |
| 600 | 718 | */ |
| 601 | 719 | public static boolean lSetList(String key, List<Object> values) { |
| 720 | + if (redisTemplate == null) { | |
| 721 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 722 | + } | |
| 602 | 723 | try { |
| 603 | 724 | redisTemplate.opsForList().rightPushAll(key, values); |
| 604 | 725 | return true; |
| ... | ... | @@ -616,6 +737,9 @@ public class RedisUtil { |
| 616 | 737 | * @return true / false |
| 617 | 738 | */ |
| 618 | 739 | public static boolean lSetList(String key, List<Object> values, long time) { |
| 740 | + if (redisTemplate == null) { | |
| 741 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 742 | + } | |
| 619 | 743 | try { |
| 620 | 744 | redisTemplate.opsForList().rightPushAll(key, values); |
| 621 | 745 | if (time > 0) { |
| ... | ... | @@ -636,6 +760,9 @@ public class RedisUtil { |
| 636 | 760 | * @return true / false |
| 637 | 761 | */ |
| 638 | 762 | public static boolean lUpdateIndex(String key, long index, Object value) { |
| 763 | + if (redisTemplate == null) { | |
| 764 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 765 | + } | |
| 639 | 766 | try { |
| 640 | 767 | redisTemplate.opsForList().set(key, index, value); |
| 641 | 768 | return true; |
| ... | ... | @@ -655,6 +782,9 @@ public class RedisUtil { |
| 655 | 782 | * @return |
| 656 | 783 | */ |
| 657 | 784 | public static long lRemove(String key, long count, Object value) { |
| 785 | + if (redisTemplate == null) { | |
| 786 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 787 | + } | |
| 658 | 788 | try { |
| 659 | 789 | return redisTemplate.opsForList().remove(key, count, value); |
| 660 | 790 | } catch (Exception e) { |
| ... | ... | @@ -669,6 +799,9 @@ public class RedisUtil { |
| 669 | 799 | * @return |
| 670 | 800 | */ |
| 671 | 801 | public static Object lLeftPop(String key) { |
| 802 | + if (redisTemplate == null) { | |
| 803 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 804 | + } | |
| 672 | 805 | return redisTemplate.opsForList().leftPop(key); |
| 673 | 806 | } |
| 674 | 807 | |
| ... | ... | @@ -678,6 +811,9 @@ public class RedisUtil { |
| 678 | 811 | * @return |
| 679 | 812 | */ |
| 680 | 813 | public static Object lrightPop(String key) { |
| 814 | + if (redisTemplate == null) { | |
| 815 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 816 | + } | |
| 681 | 817 | return redisTemplate.opsForList().rightPop(key); |
| 682 | 818 | } |
| 683 | 819 | |
| ... | ... | @@ -687,6 +823,9 @@ public class RedisUtil { |
| 687 | 823 | * @return true / false |
| 688 | 824 | */ |
| 689 | 825 | public static List<Object> keys(String key) { |
| 826 | + if (redisTemplate == null) { | |
| 827 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 828 | + } | |
| 690 | 829 | try { |
| 691 | 830 | Set<String> set = redisTemplate.keys(key); |
| 692 | 831 | return new ArrayList<>(set); |
| ... | ... | @@ -727,6 +866,9 @@ public class RedisUtil { |
| 727 | 866 | * @return |
| 728 | 867 | */ |
| 729 | 868 | public static List<Object> scan(String query) { |
| 869 | + if (redisTemplate == null) { | |
| 870 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 871 | + } | |
| 730 | 872 | Set<String> resultKeys = (Set<String>) redisTemplate.execute((RedisCallback<Set<String>>) connection -> { |
| 731 | 873 | ScanOptions scanOptions = ScanOptions.scanOptions().match("*" + query + "*").count(1000).build(); |
| 732 | 874 | Cursor<byte[]> scan = connection.scan(scanOptions); |
| ... | ... | @@ -743,9 +885,10 @@ public class RedisUtil { |
| 743 | 885 | |
| 744 | 886 | // ============================== 消息发送与订阅 ============================== |
| 745 | 887 | public static void convertAndSend(String channel, JSONObject msg) { |
| 746 | -// redisTemplate.convertAndSend(channel, msg); | |
| 888 | + if (redisTemplate == null) { | |
| 889 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | |
| 890 | + } | |
| 747 | 891 | redisTemplate.convertAndSend(channel, msg); |
| 748 | - | |
| 749 | 892 | } |
| 750 | 893 | |
| 751 | 894 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java
| ... | ... | @@ -9,14 +9,13 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| 9 | 9 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 10 | 10 | import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog; |
| 11 | 11 | import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; |
| 12 | -import com.genersoft.iot.vmp.gb28181.bean.TreeType; | |
| 13 | 12 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 14 | 13 | import com.genersoft.iot.vmp.service.IPlatformChannelService; |
| 14 | +import com.genersoft.iot.vmp.service.IPlatformService; | |
| 15 | 15 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 16 | 16 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 17 | 17 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 18 | 18 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 19 | -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; | |
| 20 | 19 | import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; |
| 21 | 20 | import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.UpdateChannelParam; |
| 22 | 21 | import com.github.pagehelper.PageInfo; |
| ... | ... | @@ -26,10 +25,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; |
| 26 | 25 | import org.slf4j.Logger; |
| 27 | 26 | import org.slf4j.LoggerFactory; |
| 28 | 27 | import org.springframework.beans.factory.annotation.Autowired; |
| 29 | -import org.springframework.http.HttpStatus; | |
| 30 | -import org.springframework.http.ResponseEntity; | |
| 31 | 28 | import org.springframework.util.ObjectUtils; |
| 32 | -import org.springframework.util.StringUtils; | |
| 33 | 29 | import org.springframework.web.bind.annotation.*; |
| 34 | 30 | import com.genersoft.iot.vmp.conf.SipConfig; |
| 35 | 31 | |
| ... | ... | @@ -70,6 +66,9 @@ public class PlatformController { |
| 70 | 66 | @Autowired |
| 71 | 67 | private DynamicTask dynamicTask; |
| 72 | 68 | |
| 69 | + @Autowired | |
| 70 | + private IPlatformService platformService; | |
| 71 | + | |
| 73 | 72 | /** |
| 74 | 73 | * 获取国标服务的配置 |
| 75 | 74 | * |
| ... | ... | @@ -95,8 +94,7 @@ public class PlatformController { |
| 95 | 94 | @Parameter(name = "id", description = "平台国标编号", required = true) |
| 96 | 95 | @GetMapping("/info/{id}") |
| 97 | 96 | public ParentPlatform getPlatform(@PathVariable String id) { |
| 98 | - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(id); | |
| 99 | - WVPResult<ParentPlatform> wvpResult = new WVPResult<>(); | |
| 97 | + ParentPlatform parentPlatform = platformService.queryPlatformByServerGBId(id); | |
| 100 | 98 | if (parentPlatform != null) { |
| 101 | 99 | return parentPlatform; |
| 102 | 100 | } else { |
| ... | ... | @@ -117,7 +115,7 @@ public class PlatformController { |
| 117 | 115 | @Parameter(name = "count", description = "每页条数", required = true) |
| 118 | 116 | public PageInfo<ParentPlatform> platforms(@PathVariable int page, @PathVariable int count) { |
| 119 | 117 | |
| 120 | - PageInfo<ParentPlatform> parentPlatformPageInfo = storager.queryParentPlatformList(page, count); | |
| 118 | + PageInfo<ParentPlatform> parentPlatformPageInfo = platformService.queryParentPlatformList(page, count); | |
| 121 | 119 | if (parentPlatformPageInfo.getList().size() > 0) { |
| 122 | 120 | for (ParentPlatform platform : parentPlatformPageInfo.getList()) { |
| 123 | 121 | platform.setMobilePositionSubscribe(subscribeHolder.getMobilePositionSubscribe(platform.getServerGBId()) != null); |
| ... | ... | @@ -136,7 +134,7 @@ public class PlatformController { |
| 136 | 134 | @Operation(summary = "添加上级平台信息") |
| 137 | 135 | @PostMapping("/add") |
| 138 | 136 | @ResponseBody |
| 139 | - public String addPlatform(@RequestBody ParentPlatform parentPlatform) { | |
| 137 | + public void addPlatform(@RequestBody ParentPlatform parentPlatform) { | |
| 140 | 138 | |
| 141 | 139 | if (logger.isDebugEnabled()) { |
| 142 | 140 | logger.debug("保存上级平台信息API调用"); |
| ... | ... | @@ -158,32 +156,16 @@ public class PlatformController { |
| 158 | 156 | throw new ControllerException(ErrorCode.ERROR400.getCode(), "error severPort"); |
| 159 | 157 | } |
| 160 | 158 | |
| 159 | + | |
| 161 | 160 | ParentPlatform parentPlatformOld = storager.queryParentPlatByServerGBId(parentPlatform.getServerGBId()); |
| 162 | 161 | if (parentPlatformOld != null) { |
| 163 | 162 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台 " + parentPlatform.getServerGBId() + " 已存在"); |
| 164 | 163 | } |
| 165 | 164 | parentPlatform.setCreateTime(DateUtil.getNow()); |
| 166 | 165 | parentPlatform.setUpdateTime(DateUtil.getNow()); |
| 167 | - boolean updateResult = storager.updateParentPlatform(parentPlatform); | |
| 168 | - | |
| 169 | - if (updateResult) { | |
| 170 | - // 保存时启用就发送注册 | |
| 171 | - if (parentPlatform.isEnable()) { | |
| 172 | - if (parentPlatformOld != null && parentPlatformOld.isStatus()) { | |
| 173 | - commanderForPlatform.unregister(parentPlatformOld, null, eventResult -> { | |
| 174 | - // 只要保存就发送注册 | |
| 175 | - commanderForPlatform.register(parentPlatform, null, null); | |
| 176 | - }); | |
| 177 | - } else { | |
| 178 | - // 只要保存就发送注册 | |
| 179 | - commanderForPlatform.register(parentPlatform, null, null); | |
| 180 | - } | |
| 166 | + boolean updateResult = platformService.add(parentPlatform); | |
| 181 | 167 | |
| 182 | - } else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()) { // 关闭启用时注销 | |
| 183 | - commanderForPlatform.unregister(parentPlatform, null, null); | |
| 184 | - } | |
| 185 | - return null; | |
| 186 | - } else { | |
| 168 | + if (!updateResult) { | |
| 187 | 169 | throw new ControllerException(ErrorCode.ERROR100.getCode(),"写入数据库失败"); |
| 188 | 170 | } |
| 189 | 171 | } |
| ... | ... | @@ -197,7 +179,7 @@ public class PlatformController { |
| 197 | 179 | @Operation(summary = "保存上级平台信息") |
| 198 | 180 | @PostMapping("/save") |
| 199 | 181 | @ResponseBody |
| 200 | - public String savePlatform(@RequestBody ParentPlatform parentPlatform) { | |
| 182 | + public void savePlatform(@RequestBody ParentPlatform parentPlatform) { | |
| 201 | 183 | |
| 202 | 184 | if (logger.isDebugEnabled()) { |
| 203 | 185 | logger.debug("保存上级平台信息API调用"); |
| ... | ... | @@ -247,7 +229,6 @@ public class PlatformController { |
| 247 | 229 | // 停止订阅相关的定时任务 |
| 248 | 230 | subscribeHolder.removeAllSubscribe(parentPlatform.getServerGBId()); |
| 249 | 231 | } |
| 250 | - return null; | |
| 251 | 232 | } else { |
| 252 | 233 | throw new ControllerException(ErrorCode.ERROR100.getCode(),"写入数据库失败"); |
| 253 | 234 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
| ... | ... | @@ -8,24 +8,21 @@ import com.genersoft.iot.vmp.conf.SipConfig; |
| 8 | 8 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 9 | 9 | import com.genersoft.iot.vmp.conf.VersionInfo; |
| 10 | 10 | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| 11 | -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | |
| 11 | +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; | |
| 12 | 12 | import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; |
| 13 | 13 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 14 | 14 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 15 | 15 | import com.genersoft.iot.vmp.utils.SpringBeanFactory; |
| 16 | 16 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 17 | -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; | |
| 18 | 17 | import gov.nist.javax.sip.SipStackImpl; |
| 19 | 18 | |
| 20 | 19 | import io.swagger.v3.oas.annotations.Operation; |
| 21 | 20 | import io.swagger.v3.oas.annotations.Parameter; |
| 22 | 21 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 23 | -import org.ehcache.xml.model.ThreadPoolsType; | |
| 24 | 22 | import org.springframework.beans.factory.annotation.Autowired; |
| 25 | 23 | import org.springframework.beans.factory.annotation.Value; |
| 26 | 24 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
| 27 | 25 | import org.springframework.util.ObjectUtils; |
| 28 | -import org.springframework.util.StringUtils; | |
| 29 | 26 | import org.springframework.web.bind.annotation.*; |
| 30 | 27 | |
| 31 | 28 | import javax.sip.ListeningPoint; |
| ... | ... | @@ -42,7 +39,7 @@ import java.util.List; |
| 42 | 39 | public class ServerController { |
| 43 | 40 | |
| 44 | 41 | @Autowired |
| 45 | - private ZLMHttpHookSubscribe zlmHttpHookSubscribe; | |
| 42 | + private ZlmHttpHookSubscribe zlmHttpHookSubscribe; | |
| 46 | 43 | |
| 47 | 44 | @Autowired |
| 48 | 45 | private IMediaServerService mediaServerService; | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java
| ... | ... | @@ -5,6 +5,7 @@ import com.alibaba.excel.ExcelReader; |
| 5 | 5 | import com.alibaba.excel.read.metadata.ReadSheet; |
| 6 | 6 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 7 | 7 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 8 | +import com.genersoft.iot.vmp.conf.exception.ControllerException; | |
| 8 | 9 | import com.genersoft.iot.vmp.conf.security.SecurityUtils; |
| 9 | 10 | import com.genersoft.iot.vmp.conf.security.dto.LoginUser; |
| 10 | 11 | import com.genersoft.iot.vmp.gb28181.bean.GbStream; |
| ... | ... | @@ -17,6 +18,7 @@ import com.genersoft.iot.vmp.service.IMediaService; |
| 17 | 18 | import com.genersoft.iot.vmp.service.IStreamPushService; |
| 18 | 19 | import com.genersoft.iot.vmp.service.impl.StreamPushUploadFileHandler; |
| 19 | 20 | import com.genersoft.iot.vmp.vmanager.bean.BatchGBStreamParam; |
| 21 | +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; | |
| 20 | 22 | import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto; |
| 21 | 23 | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| 22 | 24 | import com.github.pagehelper.PageInfo; |
| ... | ... | @@ -95,11 +97,9 @@ public class StreamPushController { |
| 95 | 97 | @PostMapping(value = "/save_to_gb") |
| 96 | 98 | @ResponseBody |
| 97 | 99 | @Operation(summary = "将推流添加到国标") |
| 98 | - public Object saveToGB(@RequestBody GbStream stream){ | |
| 99 | - if (streamPushService.saveToGB(stream)){ | |
| 100 | - return "success"; | |
| 101 | - }else { | |
| 102 | - return "fail"; | |
| 100 | + public void saveToGB(@RequestBody GbStream stream){ | |
| 101 | + if (!streamPushService.saveToGB(stream)){ | |
| 102 | + throw new ControllerException(ErrorCode.ERROR100); | |
| 103 | 103 | } |
| 104 | 104 | } |
| 105 | 105 | |
| ... | ... | @@ -107,11 +107,9 @@ public class StreamPushController { |
| 107 | 107 | @DeleteMapping(value = "/remove_form_gb") |
| 108 | 108 | @ResponseBody |
| 109 | 109 | @Operation(summary = "将推流移出到国标") |
| 110 | - public Object removeFormGB(@RequestBody GbStream stream){ | |
| 111 | - if (streamPushService.removeFromGB(stream)){ | |
| 112 | - return "success"; | |
| 113 | - }else { | |
| 114 | - return "fail"; | |
| 110 | + public void removeFormGB(@RequestBody GbStream stream){ | |
| 111 | + if (!streamPushService.removeFromGB(stream)){ | |
| 112 | + throw new ControllerException(ErrorCode.ERROR100); | |
| 115 | 113 | } |
| 116 | 114 | } |
| 117 | 115 | |
| ... | ... | @@ -121,25 +119,21 @@ public class StreamPushController { |
| 121 | 119 | @Operation(summary = "中止一个推流") |
| 122 | 120 | @Parameter(name = "app", description = "应用名", required = true) |
| 123 | 121 | @Parameter(name = "stream", description = "流id", required = true) |
| 124 | - public Object stop(String app, String streamId){ | |
| 125 | - if (streamPushService.stop(app, streamId)){ | |
| 126 | - return "success"; | |
| 127 | - }else { | |
| 128 | - return "fail"; | |
| 122 | + public void stop(String app, String streamId){ | |
| 123 | + if (!streamPushService.stop(app, streamId)){ | |
| 124 | + throw new ControllerException(ErrorCode.ERROR100); | |
| 129 | 125 | } |
| 130 | 126 | } |
| 131 | 127 | |
| 132 | 128 | @DeleteMapping(value = "/batchStop") |
| 133 | 129 | @ResponseBody |
| 134 | 130 | @Operation(summary = "中止多个推流") |
| 135 | - public Object batchStop(@RequestBody BatchGBStreamParam batchGBStreamParam){ | |
| 131 | + public void batchStop(@RequestBody BatchGBStreamParam batchGBStreamParam){ | |
| 136 | 132 | if (batchGBStreamParam.getGbStreams().size() == 0) { |
| 137 | - return "fail"; | |
| 133 | + throw new ControllerException(ErrorCode.ERROR100); | |
| 138 | 134 | } |
| 139 | - if (streamPushService.batchStop(batchGBStreamParam.getGbStreams())){ | |
| 140 | - return "success"; | |
| 141 | - }else { | |
| 142 | - return "fail"; | |
| 135 | + if (!streamPushService.batchStop(batchGBStreamParam.getGbStreams())){ | |
| 136 | + throw new ControllerException(ErrorCode.ERROR100); | |
| 143 | 137 | } |
| 144 | 138 | } |
| 145 | 139 | |
| ... | ... | @@ -249,7 +243,7 @@ public class StreamPushController { |
| 249 | 243 | @Parameter(name = "app", description = "应用名", required = true) |
| 250 | 244 | @Parameter(name = "stream", description = "流id", required = true) |
| 251 | 245 | @Parameter(name = "mediaServerId", description = "媒体服务器id") |
| 252 | - public WVPResult<StreamInfo> getPlayUrl(@RequestParam String app,@RequestParam String stream, | |
| 246 | + public StreamInfo getPlayUrl(@RequestParam String app,@RequestParam String stream, | |
| 253 | 247 | @RequestParam(required = false) String mediaServerId){ |
| 254 | 248 | boolean authority = false; |
| 255 | 249 | // 是否登陆用户, 登陆用户返回完整信息 |
| ... | ... | @@ -257,52 +251,38 @@ public class StreamPushController { |
| 257 | 251 | if (userInfo!= null) { |
| 258 | 252 | authority = true; |
| 259 | 253 | } |
| 260 | - WVPResult<StreamInfo> result = new WVPResult<>(); | |
| 261 | 254 | StreamPushItem push = streamPushService.getPush(app, stream); |
| 262 | 255 | if (push != null && !push.isSelf()) { |
| 263 | - result.setCode(-1); | |
| 264 | - result.setMsg("来自其他平台的推流信息"); | |
| 265 | - return result; | |
| 256 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "来自其他平台的推流信息"); | |
| 266 | 257 | } |
| 267 | 258 | StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority); |
| 268 | - if (streamInfo != null){ | |
| 269 | - result.setCode(0); | |
| 270 | - result.setMsg("success"); | |
| 271 | - result.setData(streamInfo); | |
| 272 | - }else { | |
| 273 | - result.setCode(-1); | |
| 274 | - result.setMsg("获取播放地址失败"); | |
| 259 | + if (streamInfo == null){ | |
| 260 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "获取播放地址失败"); | |
| 275 | 261 | } |
| 276 | - | |
| 277 | - return result; | |
| 262 | + return streamInfo; | |
| 278 | 263 | } |
| 279 | 264 | |
| 280 | 265 | /** |
| 281 | - * 获取推流播放地址 | |
| 266 | + * 添加推流信息 | |
| 282 | 267 | * @param stream 推流信息 |
| 283 | 268 | * @return |
| 284 | 269 | */ |
| 285 | 270 | @PostMapping(value = "/add") |
| 286 | 271 | @ResponseBody |
| 287 | - @Operation(summary = "停止视频回放") | |
| 288 | - public WVPResult<StreamInfo> add(@RequestBody StreamPushItem stream){ | |
| 272 | + @Operation(summary = "添加推流信息") | |
| 273 | + public void add(@RequestBody StreamPushItem stream){ | |
| 289 | 274 | if (ObjectUtils.isEmpty(stream.getGbId())) { |
| 290 | - | |
| 291 | - return new WVPResult<>(400, "国标ID不可为空", null); | |
| 275 | + throw new ControllerException(ErrorCode.ERROR400.getCode(), "国标ID不可为空"); | |
| 292 | 276 | } |
| 293 | 277 | if (ObjectUtils.isEmpty(stream.getApp()) && ObjectUtils.isEmpty(stream.getStream())) { |
| 294 | - return new WVPResult<>(400, "app或stream不可为空", null); | |
| 278 | + throw new ControllerException(ErrorCode.ERROR400.getCode(), "app或stream不可为空"); | |
| 295 | 279 | } |
| 296 | 280 | stream.setStatus(false); |
| 297 | 281 | stream.setPushIng(false); |
| 298 | 282 | stream.setAliveSecond(0L); |
| 299 | 283 | stream.setTotalReaderCount("0"); |
| 300 | - boolean result = streamPushService.add(stream); | |
| 301 | - | |
| 302 | - if (result) { | |
| 303 | - return new WVPResult<>(0, "success", null); | |
| 304 | - }else { | |
| 305 | - return new WVPResult<>(-1, "fail", null); | |
| 284 | + if (!streamPushService.add(stream)) { | |
| 285 | + throw new ControllerException(ErrorCode.ERROR100); | |
| 306 | 286 | } |
| 307 | 287 | } |
| 308 | 288 | } | ... | ... |
src/main/resources/all-application.yml
| ... | ... | @@ -179,8 +179,6 @@ user-settings: |
| 179 | 179 | platform-play-timeout: 60000 |
| 180 | 180 | # 是否开启接口鉴权 |
| 181 | 181 | interface-authentication: true |
| 182 | - # 自动配置redis 可以过期事件 | |
| 183 | - redis-config: true | |
| 184 | 182 | # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 |
| 185 | 183 | interface-authentication-excludes: |
| 186 | 184 | - /api/v1/** | ... | ... |
src/main/resources/logback-spring-local.xml
| ... | ... | @@ -77,25 +77,35 @@ |
| 77 | 77 | </encoder> |
| 78 | 78 | </appender> |
| 79 | 79 | |
| 80 | + <!-- 生成 SIP日志追加 --> | |
| 81 | + <appender name="sipRollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |
| 82 | + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> | |
| 83 | + <!--历史日志文件输出的文件名 --> | |
| 84 | + <FileNamePattern>${LOG_HOME}/sip-%d{yyyy-MM-dd}.%i.log</FileNamePattern> | |
| 85 | + <!--日志文件保留天数 --> | |
| 86 | + <MaxHistory>30</MaxHistory> | |
| 87 | + <maxFileSize>50MB</maxFileSize> | |
| 88 | + </rollingPolicy> | |
| 89 | + <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> | |
| 90 | + <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 --> | |
| 91 | + <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern> | |
| 92 | + </encoder> | |
| 93 | + </appender> | |
| 94 | + | |
| 80 | 95 | |
| 81 | 96 | <!-- 日志输出级别 --> |
| 82 | 97 | <root level="INFO"> |
| 83 | 98 | <appender-ref ref="STDOUT" /> |
| 84 | - <appender-ref ref="RollingFile" /> | |
| 85 | - <appender-ref ref="RollingFileError" /> | |
| 86 | 99 | </root> |
| 87 | 100 | |
| 88 | -<!-- <logger name="com.genersoft.iot.vmp.storager.dao" level="INFO">--> | |
| 89 | -<!-- <appender-ref ref="STDOUT"/>--> | |
| 90 | -<!-- </logger>--> | |
| 91 | -<!-- <logger name="com.genersoft.iot.vmp.gb28181" level="INFO">--> | |
| 92 | -<!-- <appender-ref ref="STDOUT"/>--> | |
| 93 | -<!-- </logger>--> | |
| 101 | + <logger name="GB28181_SIP" level="debug" additivity="true"> | |
| 102 | + <appender-ref ref="RollingFileError"/> | |
| 103 | + <appender-ref ref="sipRollingFile"/> | |
| 104 | + </logger> | |
| 94 | 105 | |
| 95 | 106 | <!--记录druid-sql的记录--> |
| 96 | - <logger name="druid.sql.Statement" level="debug" additivity="true"> | |
| 107 | + <logger name="com.genersoft.iot.vmp.storager.dao" level="info" additivity="true"> | |
| 97 | 108 | <!--AppenderRef ref="Console"/--> |
| 98 | - <!-- <appender-ref ref="RollingFile"/>--> | |
| 99 | 109 | <appender-ref ref="RollingFileError"/> |
| 100 | 110 | <appender-ref ref="druidSqlRollingFile"/> |
| 101 | 111 | </logger> | ... | ... |
web_src/src/components/CloudRecord.vue
| 1 | 1 | <template> |
| 2 | 2 | <div id="app" style="width: 100%"> |
| 3 | 3 | <div class="page-header"> |
| 4 | - <div class="page-title">云端录像</div> | |
| 4 | + <div class="page-title"> | |
| 5 | + <el-page-header v-if="recordDetail" @back="backToList" content="云端录像"></el-page-header> | |
| 6 | + <div v-if="!recordDetail">云端录像</div> | |
| 7 | + </div> | |
| 8 | + | |
| 5 | 9 | <div class="page-header-btn"> |
| 6 | 10 | 节点选择: |
| 7 | 11 | <el-select size="mini" @change="chooseMediaChange" style="width: 16rem; margin-right: 1rem;" v-model="mediaServerId" placeholder="请选择" :disabled="recordDetail"> |
| ... | ... | @@ -183,7 +187,7 @@ |
| 183 | 187 | }).catch(function (error) { |
| 184 | 188 | console.log(error); |
| 185 | 189 | }); |
| 186 | - } | |
| 190 | + }, | |
| 187 | 191 | |
| 188 | 192 | |
| 189 | 193 | } | ... | ... |
web_src/src/components/CloudRecordDetail.vue
| 1 | 1 | <template> |
| 2 | 2 | <div id="recordDetail"> |
| 3 | 3 | <el-container> |
| 4 | + | |
| 4 | 5 | <el-aside width="300px"> |
| 6 | + | |
| 5 | 7 | <div class="record-list-box-box"> |
| 6 | 8 | <el-date-picker size="mini" v-model="chooseDate" :picker-options="pickerOptions" type="date" value-format="yyyy-MM-dd" placeholder="日期" @change="dateChange()"></el-date-picker> |
| 7 | 9 | <div class="record-list-box" :style="recordListStyle"> |
| ... | ... | @@ -423,6 +425,9 @@ |
| 423 | 425 | }).catch(function (error) { |
| 424 | 426 | console.log(error); |
| 425 | 427 | }); |
| 428 | + }, | |
| 429 | + goBack(){ | |
| 430 | + this.$router.push('/cloudRecord'); | |
| 426 | 431 | } |
| 427 | 432 | } |
| 428 | 433 | }; | ... | ... |
web_src/src/components/Login.vue
| ... | ... | @@ -66,10 +66,6 @@ export default { |
| 66 | 66 | |
| 67 | 67 | //登录请求 |
| 68 | 68 | toLogin(){ |
| 69 | - | |
| 70 | - //一般要跟后端了解密码的加密规则 | |
| 71 | - //这里例子用的哈希算法来自./js/sha1.min.js | |
| 72 | - | |
| 73 | 69 | //需要想后端发送的登录参数 |
| 74 | 70 | let loginParam = { |
| 75 | 71 | username: this.username, |
| ... | ... | @@ -78,12 +74,17 @@ export default { |
| 78 | 74 | var that = this; |
| 79 | 75 | //设置在登录状态 |
| 80 | 76 | this.isLoging = true; |
| 77 | + let timeoutTask = setTimeout(()=>{ | |
| 78 | + that.$message.error("登录超时"); | |
| 79 | + that.isLoging = false; | |
| 80 | + }, 1000) | |
| 81 | 81 | |
| 82 | 82 | this.$axios({ |
| 83 | 83 | method: 'get', |
| 84 | 84 | url:"/api/user/login", |
| 85 | 85 | params: loginParam |
| 86 | 86 | }).then(function (res) { |
| 87 | + window.clearTimeout(timeoutTask) | |
| 87 | 88 | console.log(JSON.stringify(res)); |
| 88 | 89 | if (res.data.code === 0 ) { |
| 89 | 90 | that.$cookies.set("session", {"username": that.username,"roleId":res.data.data.role.id}) ; |
| ... | ... | @@ -99,6 +100,8 @@ export default { |
| 99 | 100 | }); |
| 100 | 101 | } |
| 101 | 102 | }).catch(function (error) { |
| 103 | + console.log(error) | |
| 104 | + window.clearTimeout(timeoutTask) | |
| 102 | 105 | that.$message.error(error.response.data.msg); |
| 103 | 106 | that.isLoging = false; |
| 104 | 107 | }); | ... | ... |
web_src/src/components/dialog/MediaServerEdit.vue
web_src/src/components/dialog/StreamProxyEdit.vue
web_src/src/components/dialog/devicePlayer.vue
| ... | ... | @@ -386,7 +386,7 @@ export default { |
| 386 | 386 | if (tab.name === "codec") { |
| 387 | 387 | this.$axios({ |
| 388 | 388 | method: 'get', |
| 389 | - url: '/zlm/' +this.mediaServerId+ '/index/api/getMediaInfo?vhost=__defaultVhost__&schema=rtmp&app='+ this.app +'&stream='+ this.streamId | |
| 389 | + url: '/zlm/' +this.mediaServerId+ '/index/api/getMediaInfo?vhost=__defaultVhost__&schema=rtsp&app='+ this.app +'&stream='+ this.streamId | |
| 390 | 390 | }).then(function (res) { |
| 391 | 391 | that.tracksLoading = false; |
| 392 | 392 | if (res.data.code == 0 && res.data.tracks) { | ... | ... |
web_src/src/components/dialog/platformEdit.vue
| ... | ... | @@ -268,30 +268,29 @@ export default { |
| 268 | 268 | } |
| 269 | 269 | }, |
| 270 | 270 | saveForm: function (){ |
| 271 | - var that = this; | |
| 272 | - that.$axios({ | |
| 271 | + this.$axios({ | |
| 273 | 272 | method: 'post', |
| 274 | 273 | url: this.saveUrl, |
| 275 | - data: that.platform | |
| 276 | - }).then(function (res) { | |
| 274 | + data: this.platform | |
| 275 | + }).then((res) =>{ | |
| 277 | 276 | if (res.data.code === 0) { |
| 278 | - that.$message({ | |
| 277 | + this.$message({ | |
| 279 | 278 | showClose: true, |
| 280 | 279 | message: "保存成功", |
| 281 | 280 | type: "success", |
| 282 | 281 | }); |
| 283 | - that.showDialog = false; | |
| 284 | - if (that.listChangeCallback != null) { | |
| 285 | - that.listChangeCallback(); | |
| 282 | + this.showDialog = false; | |
| 283 | + if (this.listChangeCallback != null) { | |
| 284 | + this.listChangeCallback(); | |
| 286 | 285 | } |
| 287 | 286 | }else { |
| 288 | - that.$message({ | |
| 287 | + this.$message({ | |
| 289 | 288 | showClose: true, |
| 290 | 289 | message: res.data.msg, |
| 291 | 290 | type: "error", |
| 292 | 291 | }); |
| 293 | 292 | } |
| 294 | - }).catch(function (error) { | |
| 293 | + }).catch((error)=> { | |
| 295 | 294 | console.log(error); |
| 296 | 295 | }); |
| 297 | 296 | }, |
| ... | ... | @@ -328,7 +327,7 @@ export default { |
| 328 | 327 | var result = false; |
| 329 | 328 | var that = this; |
| 330 | 329 | await that.$axios({ |
| 331 | - method: 'post', | |
| 330 | + method: 'get', | |
| 332 | 331 | url:`/api/platform/exit/${deviceGbId}`}) |
| 333 | 332 | .then(function (res) { |
| 334 | 333 | if (res.data.code === 0) { | ... | ... |
web_src/src/components/dialog/pushStreamEdit.vue