Commit ab81136765f1b641223b982b2baef13e06307fe4

Authored by 648540858
1 parent 9b1af8ef

优化适配zlm的hook保活

Showing 20 changed files with 440 additions and 78 deletions
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
1 package com.genersoft.iot.vmp.gb28181; 1 package com.genersoft.iot.vmp.gb28181;
2 2
3 import com.genersoft.iot.vmp.conf.SipConfig; 3 import com.genersoft.iot.vmp.conf.SipConfig;
4 -import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;  
5 import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver; 4 import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver;
6 -import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;  
7 import gov.nist.javax.sip.SipProviderImpl; 5 import gov.nist.javax.sip.SipProviderImpl;
8 import gov.nist.javax.sip.SipStackImpl; 6 import gov.nist.javax.sip.SipStackImpl;
9 import org.slf4j.Logger; 7 import org.slf4j.Logger;
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
@@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.gb28181.event.offline.OfflineEvent; @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.gb28181.event.offline.OfflineEvent;
5 import com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire.PlatformKeepaliveExpireEvent; 5 import com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire.PlatformKeepaliveExpireEvent;
6 import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformNotRegisterEvent; 6 import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformNotRegisterEvent;
7 import com.genersoft.iot.vmp.media.zlm.event.ZLMOfflineEvent; 7 import com.genersoft.iot.vmp.media.zlm.event.ZLMOfflineEvent;
  8 +import com.genersoft.iot.vmp.media.zlm.event.ZLMOnlineEvent;
8 import org.springframework.beans.factory.annotation.Autowired; 9 import org.springframework.beans.factory.annotation.Autowired;
9 import org.springframework.context.ApplicationEventPublisher; 10 import org.springframework.context.ApplicationEventPublisher;
10 import org.springframework.stereotype.Component; 11 import org.springframework.stereotype.Component;
@@ -73,5 +74,10 @@ public class EventPublisher { @@ -73,5 +74,10 @@ public class EventPublisher {
73 outEvent.setMediaServerId(mediaServerId); 74 outEvent.setMediaServerId(mediaServerId);
74 applicationEventPublisher.publishEvent(outEvent); 75 applicationEventPublisher.publishEvent(outEvent);
75 } 76 }
76 - 77 +
  78 + public void zlmOnlineEventPublish(String mediaServerId) {
  79 + ZLMOnlineEvent outEvent = new ZLMOnlineEvent(this);
  80 + outEvent.setMediaServerId(mediaServerId);
  81 + applicationEventPublisher.publishEvent(outEvent);
  82 + }
77 } 83 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -179,29 +179,33 @@ public class ZLMHttpHookListener { @@ -179,29 +179,33 @@ public class ZLMHttpHookListener {
179 public ResponseEntity<String> onPublish(@RequestBody JSONObject json) { 179 public ResponseEntity<String> onPublish(@RequestBody JSONObject json) {
180 180
181 logger.debug("[ ZLM HOOK ]on_publish API调用,参数:" + json.toString()); 181 logger.debug("[ ZLM HOOK ]on_publish API调用,参数:" + json.toString());
182 - 182 + JSONObject ret = new JSONObject();
  183 + ret.put("code", 0);
  184 + ret.put("msg", "success");
  185 + ret.put("enableHls", true);
  186 + ret.put("enableMP4", userSetup.isRecordPushLive());
183 String mediaServerId = json.getString("mediaServerId"); 187 String mediaServerId = json.getString("mediaServerId");
184 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json); 188 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json);
185 if (subscribe != null) { 189 if (subscribe != null) {
186 MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); 190 MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
187 if (mediaInfo != null) { 191 if (mediaInfo != null) {
188 subscribe.response(mediaInfo, json); 192 subscribe.response(mediaInfo, json);
  193 + }else {
  194 + ret.put("code", 1);
  195 + ret.put("msg", "zlm not register");
189 } 196 }
190 } 197 }
191 String app = json.getString("app"); 198 String app = json.getString("app");
192 String stream = json.getString("stream"); 199 String stream = json.getString("stream");
193 StreamInfo streamInfo = redisCatchStorage.queryPlaybackByStreamId(stream); 200 StreamInfo streamInfo = redisCatchStorage.queryPlaybackByStreamId(stream);
194 - JSONObject ret = new JSONObject(); 201 +
195 // 录像回放时不进行录像下载 202 // 录像回放时不进行录像下载
196 if (streamInfo != null) { 203 if (streamInfo != null) {
197 ret.put("enableMP4", false); 204 ret.put("enableMP4", false);
198 }else { 205 }else {
199 ret.put("enableMP4", userSetup.isRecordPushLive()); 206 ret.put("enableMP4", userSetup.isRecordPushLive());
200 } 207 }
201 - ret.put("code", 0);  
202 - ret.put("msg", "success");  
203 - ret.put("enableHls", true);  
204 - ret.put("enableMP4", userSetup.isRecordPushLive()); 208 +
205 return new ResponseEntity<String>(ret.toString(), HttpStatus.OK); 209 return new ResponseEntity<String>(ret.toString(), HttpStatus.OK);
206 } 210 }
207 211
@@ -340,37 +344,38 @@ public class ZLMHttpHookListener { @@ -340,37 +344,38 @@ public class ZLMHttpHookListener {
340 if (!"rtp".equals(app)){ 344 if (!"rtp".equals(app)){
341 String type = OriginType.values()[item.getOriginType()].getType(); 345 String type = OriginType.values()[item.getOriginType()].getType();
342 MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); 346 MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
343 - if (regist) {  
344 - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem, app, streamId, tracks);  
345 - redisCatchStorage.addStream(mediaServerItem, type, app, streamId, streamInfo);  
346 - if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal()  
347 - || item.getOriginType() == OriginType.RTMP_PUSH.ordinal()  
348 - || item.getOriginType() == OriginType.RTC_PUSH.ordinal() ) {  
349 - zlmMediaListManager.addPush(item);  
350 - }  
351 - }else {  
352 - // 兼容流注销时类型错误的问题,等zlm更新后删除  
353 - StreamPushItem streamPushItem = streamPushService.getPush(app, streamId);  
354 - if (streamPushItem != null) {  
355 - type = "PUSH"; 347 + if (mediaServerItem != null){
  348 + if (regist) {
  349 + StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem, app, streamId, tracks);
  350 + redisCatchStorage.addStream(mediaServerItem, type, app, streamId, streamInfo);
  351 + if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal()
  352 + || item.getOriginType() == OriginType.RTMP_PUSH.ordinal()
  353 + || item.getOriginType() == OriginType.RTC_PUSH.ordinal() ) {
  354 + zlmMediaListManager.addPush(item);
  355 + }
356 }else { 356 }else {
357 - StreamProxyItem streamProxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(app, streamId);  
358 - if (streamProxyByAppAndStream != null) {  
359 - type = "PULL"; 357 + // 兼容流注销时类型错误的问题,等zlm更新后删除
  358 + StreamPushItem streamPushItem = streamPushService.getPush(app, streamId);
  359 + if (streamPushItem != null) {
  360 + type = "PUSH";
  361 + }else {
  362 + StreamProxyItem streamProxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(app, streamId);
  363 + if (streamProxyByAppAndStream != null) {
  364 + type = "PULL";
  365 + }
360 } 366 }
  367 + zlmMediaListManager.removeMedia(app, streamId);
  368 + redisCatchStorage.removeStream(mediaServerItem.getId(), type, app, streamId);
361 } 369 }
362 - zlmMediaListManager.removeMedia(app, streamId);  
363 - redisCatchStorage.removeStream(mediaServerItem, type, app, streamId); 370 + // 发送流变化redis消息
  371 + JSONObject jsonObject = new JSONObject();
  372 + jsonObject.put("serverId", userSetup.getServerId());
  373 + jsonObject.put("app", app);
  374 + jsonObject.put("stream", streamId);
  375 + jsonObject.put("register", regist);
  376 + jsonObject.put("mediaServerId", mediaServerId);
  377 + redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
364 } 378 }
365 -  
366 - // 发送流变化redis消息  
367 - JSONObject jsonObject = new JSONObject();  
368 - jsonObject.put("serverId", userSetup.getServerId());  
369 - jsonObject.put("app", app);  
370 - jsonObject.put("stream", streamId);  
371 - jsonObject.put("register", regist);  
372 - jsonObject.put("mediaServerId", mediaServerId);  
373 - redisCatchStorage.sendStreamChangeMsg(type, jsonObject);  
374 } 379 }
375 } 380 }
376 } 381 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
@@ -141,7 +141,6 @@ public class ZLMMediaListManager { @@ -141,7 +141,6 @@ public class ZLMMediaListManager {
141 }else { 141 }else {
142 gbStreamMapper.add(transform); 142 gbStreamMapper.add(transform);
143 } 143 }
144 -  
145 } 144 }
146 } 145 }
147 146
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON; @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONArray; 4 import com.alibaba.fastjson.JSONArray;
5 import com.alibaba.fastjson.JSONObject; 5 import com.alibaba.fastjson.JSONObject;
6 import com.genersoft.iot.vmp.conf.MediaConfig; 6 import com.genersoft.iot.vmp.conf.MediaConfig;
  7 +import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 8 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
8 import com.genersoft.iot.vmp.service.IMediaServerService; 9 import com.genersoft.iot.vmp.service.IMediaServerService;
9 import com.genersoft.iot.vmp.service.IStreamProxyService; 10 import com.genersoft.iot.vmp.service.IStreamProxyService;
@@ -17,6 +18,7 @@ import org.springframework.core.annotation.Order; @@ -17,6 +18,7 @@ import org.springframework.core.annotation.Order;
17 import org.springframework.scheduling.annotation.Async; 18 import org.springframework.scheduling.annotation.Async;
18 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 19 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
19 import org.springframework.stereotype.Component; 20 import org.springframework.stereotype.Component;
  21 +import org.springframework.util.StringUtils;
20 22
21 import java.util.*; 23 import java.util.*;
22 24
@@ -38,6 +40,9 @@ public class ZLMRunner implements CommandLineRunner { @@ -38,6 +40,9 @@ public class ZLMRunner implements CommandLineRunner {
38 private IStreamProxyService streamProxyService; 40 private IStreamProxyService streamProxyService;
39 41
40 @Autowired 42 @Autowired
  43 + private EventPublisher publisher;
  44 +
  45 + @Autowired
41 private IMediaServerService mediaServerService; 46 private IMediaServerService mediaServerService;
42 47
43 @Autowired 48 @Autowired
@@ -117,7 +122,7 @@ public class ZLMRunner implements CommandLineRunner { @@ -117,7 +122,7 @@ public class ZLMRunner implements CommandLineRunner {
117 122
118 @Async 123 @Async
119 public void connectZlmServer(MediaServerItem mediaServerItem){ 124 public void connectZlmServer(MediaServerItem mediaServerItem){
120 - ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem); 125 + ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem, 1);
121 if (zlmServerConfig != null) { 126 if (zlmServerConfig != null) {
122 zlmServerConfig.setIp(mediaServerItem.getIp()); 127 zlmServerConfig.setIp(mediaServerItem.getIp());
123 zlmServerConfig.setHttpPort(mediaServerItem.getHttpPort()); 128 zlmServerConfig.setHttpPort(mediaServerItem.getHttpPort());
@@ -126,7 +131,7 @@ public class ZLMRunner implements CommandLineRunner { @@ -126,7 +131,7 @@ public class ZLMRunner implements CommandLineRunner {
126 } 131 }
127 } 132 }
128 133
129 - public ZLMServerConfig getMediaServerConfig(MediaServerItem mediaServerItem) { 134 + public ZLMServerConfig getMediaServerConfig(MediaServerItem mediaServerItem, int index) {
130 if (startGetMedia == null) { return null;} 135 if (startGetMedia == null) { return null;}
131 if (!mediaServerItem.isDefaultServer() && mediaServerService.getOne(mediaServerItem.getId()) == null) { 136 if (!mediaServerItem.isDefaultServer() && mediaServerService.getOne(mediaServerItem.getId()) == null) {
132 return null; 137 return null;
@@ -143,14 +148,19 @@ public class ZLMRunner implements CommandLineRunner { @@ -143,14 +148,19 @@ public class ZLMRunner implements CommandLineRunner {
143 ZLMServerConfig.setIp(mediaServerItem.getIp()); 148 ZLMServerConfig.setIp(mediaServerItem.getIp());
144 } 149 }
145 } else { 150 } else {
146 - logger.error("[ {} ]-[ {}:{} ]主动连接失败失败, 2s后重试",  
147 - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); 151 + logger.error("[ {} ]-[ {}:{} ]第{}次主动连接失败, 2s后重试",
  152 + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort(), index);
  153 + if (index == 1 && !StringUtils.isEmpty(mediaServerItem.getId())) {
  154 + logger.info("[ {} ]-[ {}:{} ]第{}次主动连接失败, 开始清理相关资源",
  155 + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort(), index);
  156 + publisher.zlmOfflineEventPublish(mediaServerItem.getId());
  157 + }
148 try { 158 try {
149 Thread.sleep(2000); 159 Thread.sleep(2000);
150 } catch (InterruptedException e) { 160 } catch (InterruptedException e) {
151 e.printStackTrace(); 161 e.printStackTrace();
152 } 162 }
153 - ZLMServerConfig = getMediaServerConfig(mediaServerItem); 163 + ZLMServerConfig = getMediaServerConfig(mediaServerItem, index += 1);
154 } 164 }
155 return ZLMServerConfig; 165 return ZLMServerConfig;
156 166
src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMKeepliveTimeoutListener.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm.event;
  2 +
  3 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  4 +import com.genersoft.iot.vmp.conf.UserSetup;
  5 +import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
  6 +import org.slf4j.Logger;
  7 +import org.slf4j.LoggerFactory;
  8 +import org.springframework.beans.factory.annotation.Autowired;
  9 +import org.springframework.data.redis.connection.Message;
  10 +import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
  11 +import org.springframework.data.redis.listener.RedisMessageListenerContainer;
  12 +import org.springframework.stereotype.Component;
  13 +
  14 +/**
  15 + * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
  16 + * @author: swwheihei
  17 + * @date: 2020年5月6日 上午11:35:46
  18 + */
  19 +@Component
  20 +public class ZLMKeepliveTimeoutListener extends KeyExpirationEventMessageListener {
  21 +
  22 + private Logger logger = LoggerFactory.getLogger(ZLMKeepliveTimeoutListener.class);
  23 +
  24 + @Autowired
  25 + private EventPublisher publisher;
  26 +
  27 + @Autowired
  28 + private UserSetup userSetup;
  29 +
  30 + public ZLMKeepliveTimeoutListener(RedisMessageListenerContainer listenerContainer) {
  31 + super(listenerContainer);
  32 + }
  33 +
  34 + /**
  35 + * 监听失效的key,key格式为keeplive_deviceId
  36 + * @param message
  37 + * @param pattern
  38 + */
  39 + @Override
  40 + public void onMessage(Message message, byte[] pattern) {
  41 + // 获取失效的key
  42 + String expiredKey = message.toString();
  43 + String KEEPLIVEKEY_PREFIX = VideoManagerConstants.MEDIA_SERVER_KEEPALIVE_PREFIX + userSetup.getServerId() + "_";
  44 + if(!expiredKey.startsWith(KEEPLIVEKEY_PREFIX)){
  45 + return;
  46 + }
  47 +
  48 + String mediaServerId = expiredKey.substring(KEEPLIVEKEY_PREFIX.length(),expiredKey.length());
  49 +
  50 + publisher.zlmOfflineEventPublish(mediaServerId);
  51 + }
  52 +}
src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMOfflineEvent.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm.event;
  2 +
  3 +/**
  4 + * zlm离线事件类
  5 + */
  6 +public class ZLMOfflineEvent extends ZLMEventAbstract {
  7 +
  8 + public ZLMOfflineEvent(Object source) {
  9 + super(source);
  10 + }
  11 +}
src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMOfflineEventListener.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm.event;
  2 +
  3 +import com.genersoft.iot.vmp.conf.UserSetup;
  4 +import com.genersoft.iot.vmp.service.IMediaServerService;
  5 +import com.genersoft.iot.vmp.service.IStreamProxyService;
  6 +import com.genersoft.iot.vmp.service.IStreamPushService;
  7 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  8 +import com.genersoft.iot.vmp.utils.redis.RedisUtil;
  9 +import org.slf4j.Logger;
  10 +import org.slf4j.LoggerFactory;
  11 +import org.springframework.beans.factory.annotation.Autowired;
  12 +import org.springframework.context.ApplicationListener;
  13 +import org.springframework.stereotype.Component;
  14 +
  15 +/**
  16 + *
  17 + */
  18 +@Component
  19 +public class ZLMOfflineEventListener implements ApplicationListener<ZLMOfflineEvent> {
  20 +
  21 + private final static Logger logger = LoggerFactory.getLogger(ZLMOfflineEventListener.class);
  22 +
  23 + @Autowired
  24 + private IMediaServerService mediaServerService;
  25 +
  26 + @Autowired
  27 + private IStreamPushService streamPushService;
  28 +
  29 + @Autowired
  30 + private IStreamProxyService streamProxyService;
  31 +
  32 + @Override
  33 + public void onApplicationEvent(ZLMOfflineEvent event) {
  34 +
  35 + if (logger.isDebugEnabled()) {
  36 + logger.debug("ZLM离线事件触发,ID:" + event.getMediaServerId());
  37 + }
  38 + // 处理ZLM离线
  39 + mediaServerService.zlmServerOffline(event.getMediaServerId());
  40 + streamProxyService.zlmServerOffline(event.getMediaServerId());
  41 + streamPushService.zlmServerOffline(event.getMediaServerId());
  42 + // TODO 处理对国标的影响
  43 + }
  44 +}
src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMOnlineEvent.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm.event;
  2 +
  3 +/**
  4 + * zlm在线事件
  5 + */
  6 +public class ZLMOnlineEvent extends ZLMEventAbstract {
  7 +
  8 + public ZLMOnlineEvent(Object source) {
  9 + super(source);
  10 + }
  11 +}
src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMOnlineEventListener.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm.event;
  2 +
  3 +import com.genersoft.iot.vmp.conf.SipConfig;
  4 +import com.genersoft.iot.vmp.conf.UserSetup;
  5 +import com.genersoft.iot.vmp.service.IMediaServerService;
  6 +import com.genersoft.iot.vmp.service.IStreamProxyService;
  7 +import com.genersoft.iot.vmp.service.IStreamPushService;
  8 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  9 +import com.genersoft.iot.vmp.utils.redis.RedisUtil;
  10 +import org.slf4j.Logger;
  11 +import org.slf4j.LoggerFactory;
  12 +import org.springframework.beans.factory.annotation.Autowired;
  13 +import org.springframework.context.ApplicationListener;
  14 +import org.springframework.stereotype.Component;
  15 +
  16 +import java.text.SimpleDateFormat;
  17 +
  18 +/**
  19 + * @description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源:
  20 + * 1、设备主动注销,发送注销指令
  21 + * 2、设备未知原因离线,心跳超时
  22 + * @author: swwheihei
  23 + * @date: 2020年5月6日 下午1:51:23
  24 + */
  25 +@Component
  26 +public class ZLMOnlineEventListener implements ApplicationListener<ZLMOnlineEvent> {
  27 +
  28 + private final static Logger logger = LoggerFactory.getLogger(ZLMOnlineEventListener.class);
  29 +
  30 + @Autowired
  31 + private IVideoManagerStorager storager;
  32 +
  33 + @Autowired
  34 + private RedisUtil redis;
  35 +
  36 + @Autowired
  37 + private SipConfig sipConfig;
  38 +
  39 + @Autowired
  40 + private UserSetup userSetup;
  41 +
  42 + @Autowired
  43 + private IMediaServerService mediaServerService;
  44 +
  45 + @Autowired
  46 + private IStreamPushService streamPushService;
  47 +
  48 + @Autowired
  49 + private IStreamProxyService streamProxyService;
  50 +
  51 + private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  52 +
  53 + @Override
  54 + public void onApplicationEvent(ZLMOnlineEvent event) {
  55 +
  56 + if (logger.isDebugEnabled()) {
  57 + logger.debug("ZLM上线事件触发,ID:" + event.getMediaServerId());
  58 + }
  59 + streamPushService.zlmServerOnline(event.getMediaServerId());
  60 + streamProxyService.zlmServerOnline(event.getMediaServerId());
  61 +
  62 +
  63 +
  64 + }
  65 +}
src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java
@@ -78,10 +78,10 @@ public interface IStreamProxyService { @@ -78,10 +78,10 @@ public interface IStreamProxyService {
78 78
79 /** 79 /**
80 * 新的节点加入 80 * 新的节点加入
81 - * @param zlmServerConfig 81 + * @param mediaServerId
82 * @return 82 * @return
83 */ 83 */
84 - void zlmServerOnline(ZLMServerConfig zlmServerConfig); 84 + void zlmServerOnline(String mediaServerId);
85 85
86 /** 86 /**
87 * 节点离线 87 * 节点离线
@@ -89,4 +89,6 @@ public interface IStreamProxyService { @@ -89,4 +89,6 @@ public interface IStreamProxyService {
89 * @return 89 * @return
90 */ 90 */
91 void zlmServerOffline(String mediaServerId); 91 void zlmServerOffline(String mediaServerId);
  92 +
  93 + void clean();
92 } 94 }
src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
@@ -34,6 +34,7 @@ public interface IStreamPushService { @@ -34,6 +34,7 @@ public interface IStreamPushService {
34 * @return 34 * @return
35 */ 35 */
36 PageInfo<StreamPushItem> getPushList(Integer page, Integer count); 36 PageInfo<StreamPushItem> getPushList(Integer page, Integer count);
  37 + List<StreamPushItem> getPushList(String mediaSererId);
37 38
38 StreamPushItem transform(MediaItem item); 39 StreamPushItem transform(MediaItem item);
39 40
@@ -49,10 +50,10 @@ public interface IStreamPushService { @@ -49,10 +50,10 @@ public interface IStreamPushService {
49 50
50 /** 51 /**
51 * 新的节点加入 52 * 新的节点加入
52 - * @param zlmServerConfig 53 + * @param mediaServerId
53 * @return 54 * @return
54 */ 55 */
55 - void zlmServerOnline(ZLMServerConfig zlmServerConfig); 56 + void zlmServerOnline(String mediaServerId);
56 57
57 /** 58 /**
58 * 节点离线 59 * 节点离线
@@ -61,4 +62,5 @@ public interface IStreamPushService { @@ -61,4 +62,5 @@ public interface IStreamPushService {
61 */ 62 */
62 void zlmServerOffline(String mediaServerId); 63 void zlmServerOffline(String mediaServerId);
63 64
  65 + void clean();
64 } 66 }
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
@@ -4,10 +4,10 @@ import com.alibaba.fastjson.JSON; @@ -4,10 +4,10 @@ import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONArray; 4 import com.alibaba.fastjson.JSONArray;
5 import com.alibaba.fastjson.JSONObject; 5 import com.alibaba.fastjson.JSONObject;
6 import com.genersoft.iot.vmp.common.VideoManagerConstants; 6 import com.genersoft.iot.vmp.common.VideoManagerConstants;
7 -import com.genersoft.iot.vmp.conf.MediaConfig;  
8 import com.genersoft.iot.vmp.conf.SipConfig; 7 import com.genersoft.iot.vmp.conf.SipConfig;
9 import com.genersoft.iot.vmp.conf.UserSetup; 8 import com.genersoft.iot.vmp.conf.UserSetup;
10 import com.genersoft.iot.vmp.gb28181.bean.Device; 9 import com.genersoft.iot.vmp.gb28181.bean.Device;
  10 +import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
11 import com.genersoft.iot.vmp.gb28181.session.SsrcConfig; 11 import com.genersoft.iot.vmp.gb28181.session.SsrcConfig;
12 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; 12 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
13 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 13 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
@@ -71,6 +71,9 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR @@ -71,6 +71,9 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR
71 private RedisUtil redisUtil; 71 private RedisUtil redisUtil;
72 72
73 @Autowired 73 @Autowired
  74 + private EventPublisher publisher;
  75 +
  76 + @Autowired
74 JedisUtil jedisUtil; 77 JedisUtil jedisUtil;
75 78
76 private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 79 private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -312,8 +315,6 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR @@ -312,8 +315,6 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR
312 return mediaServerMapper.update(mediaSerItem); 315 return mediaServerMapper.update(mediaSerItem);
313 } 316 }
314 317
315 -  
316 -  
317 /** 318 /**
318 * 处理zlm上线 319 * 处理zlm上线
319 * @param zlmServerConfig zlm上线携带的参数 320 * @param zlmServerConfig zlm上线携带的参数
@@ -353,28 +354,31 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR @@ -353,28 +354,31 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR
353 if (serverItem.getRtpProxyPort() == 0) { 354 if (serverItem.getRtpProxyPort() == 0) {
354 serverItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); 355 serverItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort());
355 } 356 }
356 - if (StringUtils.isEmpty(serverItem.getId())) {  
357 - serverItem.setId(zlmServerConfig.getGeneralMediaServerId());  
358 - }  
359 serverItem.setStatus(true); 357 serverItem.setStatus(true);
  358 +
360 if (StringUtils.isEmpty(serverItem.getId())) { 359 if (StringUtils.isEmpty(serverItem.getId())) {
361 serverItem.setId(zlmServerConfig.getGeneralMediaServerId()); 360 serverItem.setId(zlmServerConfig.getGeneralMediaServerId());
362 mediaServerMapper.updateByHostAndPort(serverItem); 361 mediaServerMapper.updateByHostAndPort(serverItem);
363 }else { 362 }else {
364 mediaServerMapper.update(serverItem); 363 mediaServerMapper.update(serverItem);
365 } 364 }
366 - String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetup.getServerId() + "_" + serverItem.getId(); 365 + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetup.getServerId() + "_" + zlmServerConfig.getGeneralMediaServerId();
367 if (redisUtil.get(key) == null) { 366 if (redisUtil.get(key) == null) {
368 - SsrcConfig ssrcConfig = new SsrcConfig(serverItem.getId(), null, sipConfig.getDomain()); 367 + SsrcConfig ssrcConfig = new SsrcConfig(zlmServerConfig.getGeneralMediaServerId(), null, sipConfig.getDomain());
369 serverItem.setSsrcConfig(ssrcConfig); 368 serverItem.setSsrcConfig(ssrcConfig);
370 - redisUtil.set(key, serverItem); 369 + }else {
  370 + MediaServerItem mediaServerItemInRedis = (MediaServerItem)redisUtil.get(key);
  371 + serverItem.setSsrcConfig(mediaServerItemInRedis.getSsrcConfig());
371 } 372 }
372 - 373 + redisUtil.set(key, serverItem);
373 resetOnlineServerItem(serverItem); 374 resetOnlineServerItem(serverItem);
374 updateMediaServerKeepalive(serverItem.getId(), null); 375 updateMediaServerKeepalive(serverItem.getId(), null);
375 setZLMConfig(serverItem); 376 setZLMConfig(serverItem);
  377 + publisher.zlmOnlineEventPublish(serverItem.getId());
  378 +
376 } 379 }
377 380
  381 +
378 @Override 382 @Override
379 public void zlmServerOffline(String mediaServerId) { 383 public void zlmServerOffline(String mediaServerId) {
380 delete(mediaServerId); 384 delete(mediaServerId);
@@ -567,6 +571,10 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR @@ -567,6 +571,10 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR
567 @Override 571 @Override
568 public void updateMediaServerKeepalive(String mediaServerId, JSONObject data) { 572 public void updateMediaServerKeepalive(String mediaServerId, JSONObject data) {
569 MediaServerItem mediaServerItem = getOne(mediaServerId); 573 MediaServerItem mediaServerItem = getOne(mediaServerId);
  574 + if (mediaServerItem == null) {
  575 + logger.warn("[更新ZLM 保活信息]失败,未找到流媒体信息");
  576 + return;
  577 + }
570 String key = VideoManagerConstants.MEDIA_SERVER_KEEPALIVE_PREFIX + userSetup.getServerId() + "_" + mediaServerId; 578 String key = VideoManagerConstants.MEDIA_SERVER_KEEPALIVE_PREFIX + userSetup.getServerId() + "_" + mediaServerId;
571 int hookAliveInterval = mediaServerItem.getHookAliveInterval() + 2; 579 int hookAliveInterval = mediaServerItem.getHookAliveInterval() + 2;
572 redisUtil.set(key, data, hookAliveInterval); 580 redisUtil.set(key, data, hookAliveInterval);
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
@@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.service.impl; @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.service.impl;
2 2
3 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
4 import com.genersoft.iot.vmp.common.StreamInfo; 4 import com.genersoft.iot.vmp.common.StreamInfo;
  5 +import com.genersoft.iot.vmp.conf.UserSetup;
5 import com.genersoft.iot.vmp.gb28181.bean.GbStream; 6 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 7 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
7 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 8 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
@@ -28,8 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired; @@ -28,8 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired;
28 import org.springframework.stereotype.Service; 29 import org.springframework.stereotype.Service;
29 import org.springframework.util.StringUtils; 30 import org.springframework.util.StringUtils;
30 31
31 -import java.util.ArrayList;  
32 -import java.util.List; 32 +import java.util.*;
33 33
34 /** 34 /**
35 * 视频代理业务 35 * 视频代理业务
@@ -55,6 +55,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -55,6 +55,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
55 private IRedisCatchStorage redisCatchStorage; 55 private IRedisCatchStorage redisCatchStorage;
56 56
57 @Autowired 57 @Autowired
  58 + private UserSetup userSetup;
  59 +
  60 + @Autowired
58 private GbStreamMapper gbStreamMapper; 61 private GbStreamMapper gbStreamMapper;
59 62
60 @Autowired 63 @Autowired
@@ -160,6 +163,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -160,6 +163,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
160 }else { 163 }else {
161 mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); 164 mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
162 } 165 }
  166 + if (mediaServerItem == null) {
  167 + return null;
  168 + }
163 if ("default".equals(param.getType())){ 169 if ("default".equals(param.getType())){
164 result = zlmresTfulUtils.addStreamProxy(mediaServerItem, param.getApp(), param.getStream(), param.getUrl(), 170 result = zlmresTfulUtils.addStreamProxy(mediaServerItem, param.getApp(), param.getStream(), param.getUrl(),
165 param.isEnable_hls(), param.isEnable_mp4(), param.getRtp_type()); 171 param.isEnable_hls(), param.isEnable_mp4(), param.getRtp_type());
@@ -244,7 +250,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -244,7 +250,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
244 } 250 }
245 } 251 }
246 } 252 }
247 -  
248 return result; 253 return result;
249 } 254 }
250 255
@@ -255,18 +260,41 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -255,18 +260,41 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
255 } 260 }
256 261
257 @Override 262 @Override
258 - public void zlmServerOnline(ZLMServerConfig zlmServerConfig) {  
259 - 263 + public void zlmServerOnline(String mediaServerId) {
  264 + zlmServerOffline(mediaServerId);
260 } 265 }
261 266
262 @Override 267 @Override
263 public void zlmServerOffline(String mediaServerId) { 268 public void zlmServerOffline(String mediaServerId) {
264 // 移除开启了无人观看自动移除的流 269 // 移除开启了无人观看自动移除的流
  270 + List<StreamProxyItem> streamProxyItemList = streamProxyMapper.selecAutoRemoveItemByMediaServerId(mediaServerId);
  271 + if (streamProxyItemList.size() > 0) {
  272 + gbStreamMapper.batchDel(streamProxyItemList);
  273 + }
265 streamProxyMapper.deleteAutoRemoveItemByMediaServerId(mediaServerId); 274 streamProxyMapper.deleteAutoRemoveItemByMediaServerId(mediaServerId);
266 // 其他的流设置未启用 275 // 其他的流设置未启用
267 streamProxyMapper.updateStatus(false, mediaServerId); 276 streamProxyMapper.updateStatus(false, mediaServerId);
268 - // 移除redis内流的信息  
269 - redisCatchStorage.removeStream(mediaServerId, "PULL"); 277 + String type = "PULL";
  278 +
  279 + // 发送redis消息
  280 + List<StreamInfo> streamInfoList = redisCatchStorage.getStreams(mediaServerId, type);
  281 + if (streamInfoList.size() > 0) {
  282 + for (StreamInfo streamInfo : streamInfoList) {
  283 + JSONObject jsonObject = new JSONObject();
  284 + jsonObject.put("serverId", userSetup.getServerId());
  285 + jsonObject.put("app", streamInfo.getApp());
  286 + jsonObject.put("stream", streamInfo.getStreamId());
  287 + jsonObject.put("register", false);
  288 + jsonObject.put("mediaServerId", mediaServerId);
  289 + redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
  290 + // 移除redis内流的信息
  291 + redisCatchStorage.removeStream(mediaServerId, type, streamInfo.getApp(), streamInfo.getStreamId());
  292 + }
  293 + }
  294 + }
  295 +
  296 + @Override
  297 + public void clean() {
270 298
271 } 299 }
272 } 300 }
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
@@ -3,11 +3,15 @@ package com.genersoft.iot.vmp.service.impl; @@ -3,11 +3,15 @@ package com.genersoft.iot.vmp.service.impl;
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
5 import com.alibaba.fastjson.TypeReference; 5 import com.alibaba.fastjson.TypeReference;
  6 +import com.genersoft.iot.vmp.common.StreamInfo;
  7 +import com.genersoft.iot.vmp.conf.UserSetup;
6 import com.genersoft.iot.vmp.gb28181.bean.GbStream; 8 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  9 +import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
7 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 10 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
8 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; 11 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
9 import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; 12 import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
10 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 13 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  14 +import com.genersoft.iot.vmp.media.zlm.dto.OriginType;
11 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 15 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
12 import com.genersoft.iot.vmp.service.IMediaServerService; 16 import com.genersoft.iot.vmp.service.IMediaServerService;
13 import com.genersoft.iot.vmp.service.IStreamPushService; 17 import com.genersoft.iot.vmp.service.IStreamPushService;
@@ -20,10 +24,7 @@ import com.github.pagehelper.PageInfo; @@ -20,10 +24,7 @@ import com.github.pagehelper.PageInfo;
20 import org.springframework.beans.factory.annotation.Autowired; 24 import org.springframework.beans.factory.annotation.Autowired;
21 import org.springframework.stereotype.Service; 25 import org.springframework.stereotype.Service;
22 26
23 -import java.util.ArrayList;  
24 -import java.util.HashMap;  
25 -import java.util.List;  
26 -import java.util.Map; 27 +import java.util.*;
27 28
28 @Service 29 @Service
29 public class StreamPushServiceImpl implements IStreamPushService { 30 public class StreamPushServiceImpl implements IStreamPushService {
@@ -44,6 +45,9 @@ public class StreamPushServiceImpl implements IStreamPushService { @@ -44,6 +45,9 @@ public class StreamPushServiceImpl implements IStreamPushService {
44 private IRedisCatchStorage redisCatchStorage; 45 private IRedisCatchStorage redisCatchStorage;
45 46
46 @Autowired 47 @Autowired
  48 + private UserSetup userSetup;
  49 +
  50 + @Autowired
47 private IMediaServerService mediaServerService; 51 private IMediaServerService mediaServerService;
48 52
49 @Override 53 @Override
@@ -56,7 +60,9 @@ public class StreamPushServiceImpl implements IStreamPushService { @@ -56,7 +60,9 @@ public class StreamPushServiceImpl implements IStreamPushService {
56 for (MediaItem item : mediaItems) { 60 for (MediaItem item : mediaItems) {
57 61
58 // 不保存国标推理以及拉流代理的流 62 // 不保存国标推理以及拉流代理的流
59 - if (item.getOriginType() == 1 || item.getOriginType() == 2 || item.getOriginType() == 8) { 63 + if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal()
  64 + || item.getOriginType() == OriginType.RTMP_PUSH.ordinal()
  65 + || item.getOriginType() == OriginType.RTC_PUSH.ordinal() ) {
60 String key = item.getApp() + "_" + item.getStream(); 66 String key = item.getApp() + "_" + item.getStream();
61 StreamPushItem streamPushItem = result.get(key); 67 StreamPushItem streamPushItem = result.get(key);
62 if (streamPushItem == null) { 68 if (streamPushItem == null) {
@@ -98,6 +104,11 @@ public class StreamPushServiceImpl implements IStreamPushService { @@ -98,6 +104,11 @@ public class StreamPushServiceImpl implements IStreamPushService {
98 } 104 }
99 105
100 @Override 106 @Override
  107 + public List<StreamPushItem> getPushList(String mediaServerId) {
  108 + return streamPushMapper.selectAllByMediaServerId(mediaServerId);
  109 + }
  110 +
  111 + @Override
101 public boolean saveToGB(GbStream stream) { 112 public boolean saveToGB(GbStream stream) {
102 stream.setStreamType("push"); 113 stream.setStreamType("push");
103 stream.setStatus(true); 114 stream.setStatus(true);
@@ -137,17 +148,84 @@ public class StreamPushServiceImpl implements IStreamPushService { @@ -137,17 +148,84 @@ public class StreamPushServiceImpl implements IStreamPushService {
137 } 148 }
138 149
139 @Override 150 @Override
140 - public void zlmServerOnline(ZLMServerConfig zlmServerConfig) {  
141 - // 似乎没啥需要做的 151 + public void zlmServerOnline(String mediaServerId) {
  152 + // 同步zlm推流信息
  153 + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
  154 + if (mediaServerItem == null) {
  155 + return;
  156 + }
  157 + List<StreamPushItem> pushList = getPushList(mediaServerId);
  158 + if (pushList.size() > 0) {
  159 + Map<String, StreamPushItem> pushItemMap = new HashMap<>();
  160 + for (StreamPushItem streamPushItem : pushList) {
  161 + pushItemMap.put(streamPushItem.getApp() + streamPushItem.getStream(), streamPushItem);
  162 + }
  163 + zlmresTfulUtils.getMediaList(mediaServerItem, (mediaList ->{
  164 + if (mediaList == null) return;
  165 + String dataStr = mediaList.getString("data");
  166 +
  167 + Integer code = mediaList.getInteger("code");
  168 + List<StreamPushItem> streamPushItems = null;
  169 + if (code == 0 ) {
  170 + if (dataStr != null) {
  171 + streamPushItems = handleJSON(dataStr, mediaServerItem);
  172 + }
  173 + }
  174 +
  175 + if (streamPushItems != null) {
  176 + for (StreamPushItem streamPushItem : streamPushItems) {
  177 + pushItemMap.remove(streamPushItem.getApp() + streamPushItem.getStream());
  178 + }
  179 + }
  180 + Collection<StreamPushItem> offlinePushItems = pushItemMap.values();
  181 + if (offlinePushItems.size() > 0) {
  182 + String type = "PUSH";
  183 + streamPushMapper.delAll(new ArrayList<>(offlinePushItems));
  184 + for (StreamPushItem offlinePushItem : offlinePushItems) {
  185 + JSONObject jsonObject = new JSONObject();
  186 + jsonObject.put("serverId", userSetup.getServerId());
  187 + jsonObject.put("app", offlinePushItem.getApp());
  188 + jsonObject.put("stream", offlinePushItem.getStream());
  189 + jsonObject.put("register", false);
  190 + jsonObject.put("mediaServerId", mediaServerId);
  191 + redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
  192 + // 移除redis内流的信息
  193 + redisCatchStorage.removeStream(mediaServerItem.getId(), "PUSH", offlinePushItem.getApp(), offlinePushItem.getStream());
  194 + }
  195 + }
  196 + }));
  197 + }
142 } 198 }
143 199
144 @Override 200 @Override
145 public void zlmServerOffline(String mediaServerId) { 201 public void zlmServerOffline(String mediaServerId) {
146 - // 移除没有serverId的推流 202 + List<StreamPushItem> streamPushItems = streamPushMapper.selectAllByMediaServerId(mediaServerId);
  203 + // 移除没有GBId的推流
147 streamPushMapper.deleteWithoutGBId(mediaServerId); 204 streamPushMapper.deleteWithoutGBId(mediaServerId);
  205 + gbStreamMapper.deleteWithoutGBId("push", mediaServerId);
148 // 其他的流设置未启用 206 // 其他的流设置未启用
149 gbStreamMapper.updateStatusByMediaServerId(mediaServerId, false); 207 gbStreamMapper.updateStatusByMediaServerId(mediaServerId, false);
150 - // 移除redis内流的信息  
151 - redisCatchStorage.removeStream(mediaServerId, "PUSH"); 208 + // 发送流停止消息
  209 + String type = "PUSH";
  210 + // 发送redis消息
  211 + List<StreamInfo> streamInfoList = redisCatchStorage.getStreams(mediaServerId, type);
  212 + if (streamInfoList.size() > 0) {
  213 + for (StreamInfo streamInfo : streamInfoList) {
  214 + JSONObject jsonObject = new JSONObject();
  215 + jsonObject.put("serverId", userSetup.getServerId());
  216 + jsonObject.put("app", streamInfo.getApp());
  217 + jsonObject.put("stream", streamInfo.getStreamId());
  218 + jsonObject.put("register", false);
  219 + jsonObject.put("mediaServerId", mediaServerId);
  220 + redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
  221 + // 移除redis内流的信息
  222 + redisCatchStorage.removeStream(mediaServerId, type, streamInfo.getApp(), streamInfo.getStreamId());
  223 + }
  224 + }
  225 + }
  226 +
  227 + @Override
  228 + public void clean() {
  229 +
152 } 230 }
153 } 231 }
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -140,11 +140,11 @@ public interface IRedisCatchStorage { @@ -140,11 +140,11 @@ public interface IRedisCatchStorage {
140 140
141 /** 141 /**
142 * 移除流信息从redis 142 * 移除流信息从redis
143 - * @param mediaServerItem 143 + * @param mediaServerId
144 * @param app 144 * @param app
145 * @param streamId 145 * @param streamId
146 */ 146 */
147 - void removeStream(MediaServerItem mediaServerItem, String type, String app, String streamId); 147 + void removeStream(String mediaServerId, String type, String app, String streamId);
148 148
149 149
150 /** 150 /**
@@ -167,4 +167,6 @@ public interface IRedisCatchStorage { @@ -167,4 +167,6 @@ public interface IRedisCatchStorage {
167 * @return 167 * @return
168 */ 168 */
169 ThirdPartyGB queryMemberNoGBId(String queryKey); 169 ThirdPartyGB queryMemberNoGBId(String queryKey);
  170 +
  171 + List<StreamInfo> getStreams(String mediaServerId, String pull);
170 } 172 }
src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
@@ -65,4 +65,18 @@ public interface GbStreamMapper { @@ -65,4 +65,18 @@ public interface GbStreamMapper {
65 "SET status=${status} " + 65 "SET status=${status} " +
66 "WHERE mediaServerId=#{mediaServerId} ") 66 "WHERE mediaServerId=#{mediaServerId} ")
67 void updateStatusByMediaServerId(String mediaServerId, boolean status); 67 void updateStatusByMediaServerId(String mediaServerId, boolean status);
  68 +
  69 + @Select("SELECT * FROM gb_stream WHERE mediaServerId=#{mediaServerId}")
  70 + void delByMediaServerId(String mediaServerId);
  71 +
  72 + @Delete("DELETE FROM gb_stream WHERE streamType=#{type} AND gbId=NULL AND mediaServerId=#{mediaServerId}")
  73 + void deleteWithoutGBId(String type, String mediaServerId);
  74 +
  75 + @Delete("<script> "+
  76 + "DELETE FROM gb_stream where " +
  77 + "<foreach collection='streamProxyItemList' item='item' separator='or'>" +
  78 + "(app=#{item.app} and stream=#{item.stream}) " +
  79 + "</foreach>" +
  80 + "</script>")
  81 + void batchDel(List<StreamProxyItem> streamProxyItemList);
68 } 82 }
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
@@ -62,6 +62,9 @@ public interface StreamProxyMapper { @@ -62,6 +62,9 @@ public interface StreamProxyMapper {
62 "WHERE mediaServerId=#{mediaServerId}") 62 "WHERE mediaServerId=#{mediaServerId}")
63 void updateStatus(boolean status, String mediaServerId); 63 void updateStatus(boolean status, String mediaServerId);
64 64
65 - @Delete("DELETE FROM stream_proxy WHERE mediaServerId=#{mediaServerId}") 65 + @Delete("DELETE FROM stream_proxy WHERE enable_remove_none_reader=true AND mediaServerId=#{mediaServerId}")
66 void deleteAutoRemoveItemByMediaServerId(String mediaServerId); 66 void deleteAutoRemoveItemByMediaServerId(String mediaServerId);
  67 +
  68 + @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream WHERE st.enable_remove_none_reader=true AND st.mediaServerId=#{mediaServerId} order by st.createTime desc")
  69 + List<StreamProxyItem> selecAutoRemoveItemByMediaServerId(String mediaServerId);
67 } 70 }
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
@@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; @@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
4 import org.apache.ibatis.annotations.*; 4 import org.apache.ibatis.annotations.*;
5 import org.springframework.stereotype.Repository; 5 import org.springframework.stereotype.Repository;
6 6
  7 +import java.util.Collection;
7 import java.util.List; 8 import java.util.List;
8 9
9 @Mapper 10 @Mapper
@@ -31,6 +32,14 @@ public interface StreamPushMapper { @@ -31,6 +32,14 @@ public interface StreamPushMapper {
31 @Delete("DELETE FROM stream_push WHERE app=#{app} AND stream=#{stream}") 32 @Delete("DELETE FROM stream_push WHERE app=#{app} AND stream=#{stream}")
32 int del(String app, String stream); 33 int del(String app, String stream);
33 34
  35 + @Delete("<script> "+
  36 + "DELETE FROM stream_push where " +
  37 + "<foreach collection='streamPushItems' item='item' separator='or'>" +
  38 + "(app=#{item.app} and stream=#{item.stream}) " +
  39 + "</foreach>" +
  40 + "</script>")
  41 + int delAll(List<StreamPushItem> streamPushItems);
  42 +
34 @Select("SELECT st.*, pgs.gbId, pgs.status, pgs.name, pgs.longitude, pgs.latitude FROM stream_push st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream") 43 @Select("SELECT st.*, pgs.gbId, pgs.status, pgs.name, pgs.longitude, pgs.latitude FROM stream_push st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream")
35 List<StreamPushItem> selectAll(); 44 List<StreamPushItem> selectAll();
36 45
@@ -56,4 +65,7 @@ public interface StreamPushMapper { @@ -56,4 +65,7 @@ public interface StreamPushMapper {
56 @Delete("DELETE FROM stream_push WHERE mediaServerId=#{mediaServerId}") 65 @Delete("DELETE FROM stream_push WHERE mediaServerId=#{mediaServerId}")
57 void deleteWithoutGBId(String mediaServerId); 66 void deleteWithoutGBId(String mediaServerId);
58 67
  68 + @Select("SELECT * FROM stream_push WHERE mediaServerId=#{mediaServerId}")
  69 + List<StreamPushItem> selectAllByMediaServerId(String mediaServerId);
  70 +
59 } 71 }
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -338,8 +338,8 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -338,8 +338,8 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
338 } 338 }
339 339
340 @Override 340 @Override
341 - public void removeStream(MediaServerItem mediaServerItem, String type, String app, String streamId) {  
342 - String key = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetup.getServerId() + "_" + type + "_" + app + "_" + streamId + "_" + mediaServerItem.getId(); 341 + public void removeStream(String mediaServerId, String type, String app, String streamId) {
  342 + String key = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetup.getServerId() + "_" + type + "_" + app + "_" + streamId + "_" + mediaServerId;
343 redis.del(key); 343 redis.del(key);
344 } 344 }
345 345
@@ -365,4 +365,16 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -365,4 +365,16 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
365 redis.del((String) stream); 365 redis.del((String) stream);
366 } 366 }
367 } 367 }
  368 +
  369 + @Override
  370 + public List<StreamInfo> getStreams(String mediaServerId, String type) {
  371 + List<StreamInfo> result = new ArrayList<>();
  372 + String key = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetup.getServerId() + "_" + type + "_*_*_" + mediaServerId;
  373 + List<Object> streams = redis.scan(key);
  374 + for (Object stream : streams) {
  375 + StreamInfo streamInfo = (StreamInfo)redis.get((String) stream);
  376 + result.add(streamInfo);
  377 + }
  378 + return result;
  379 + }
368 } 380 }