Commit 03d6ad289baddf8feed64ffca5f1b13828bea710

Authored by 648540858
2 parents 8f7e8efc 703c2e29

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
... ... @@ -29,5 +29,4 @@
29 29 - [设备注册不上来的解决办法](_content/qa/regiser_error.md)
30 30 - [点播超时/报错的解决办法](_content/qa/play_error.md)
31 31 * [**免责声明**](_content/disclaimers.md)
32   -* [**捐赠**](_content/donation.md)
33 32 * [**关于本文档**](_content/about_doc.md)
... ...
... ... @@ -11,7 +11,7 @@
11 11  
12 12 <groupId>com.genersoft</groupId>
13 13 <artifactId>wvp-pro</artifactId>
14   - <version>2.3.1</version>
  14 + <version>2.3.2</version>
15 15 <name>web video platform</name>
16 16 <description>国标28181视频平台</description>
17 17  
... ...
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
... ... @@ -4,7 +4,9 @@ public class ParentPlatformCatch {
4 4  
5 5 private String id;
6 6  
7   - // 心跳未回复次数
  7 + /**
  8 + * 心跳未回复次数
  9 + */
8 10 private int keepAliveReply;
9 11  
10 12 // 注册未回复次数
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java
... ... @@ -14,6 +14,9 @@ import java.util.ArrayList;
14 14 import java.util.List;
15 15 import java.util.concurrent.ConcurrentHashMap;
16 16  
  17 +/**
  18 + * @author lin
  19 + */
17 20 @Component
18 21 public class SubscribeHolder {
19 22  
... ...
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&lt;CatalogEvent&gt; {
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
... ... @@ -82,4 +82,9 @@ public class DateUtil {
82 82 return false;
83 83 }
84 84 }
  85 +
  86 + public static String getNowForISO8601() {
  87 + LocalDateTime nowDateTime = LocalDateTime.now();
  88 + return formatterISO8601.format(nowDateTime);
  89 + }
85 90 }
... ...
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
... ... @@ -357,7 +357,7 @@ export default {
357 357 var result = false;
358 358 var that = this;
359 359 await that.$axios({
360   - method: 'post',
  360 + method: 'get',
361 361 url:`/api/platform/exit/${deviceGbId}`
362 362 }).then(function (res) {
363 363 result = res.data;
... ...
web_src/src/components/dialog/StreamProxyEdit.vue
... ... @@ -263,7 +263,7 @@ export default {
263 263 var result = false;
264 264 var that = this;
265 265 await that.$axios({
266   - method: 'post',
  266 + method: 'get',
267 267 url:`/api/platform/exit/${deviceGbId}`
268 268 }).then(function (res) {
269 269 result = res.data;
... ...
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
... ... @@ -158,7 +158,7 @@ export default {
158 158 var result = false;
159 159 var that = this;
160 160 await that.$axios({
161   - method:"post",
  161 + method:"get",
162 162 url:`/api/platform/exit/${deviceGbId}`
163 163 }).then(function (res) {
164 164 result = res.data;
... ...