From 938064199bf4d2ca9aac4fb8851efa0609124608 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Fri, 26 Aug 2022 11:06:50 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E6=8D=90=E8=B5=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/_content/donation.md | 7 ------- doc/_sidebar.md | 1 - 2 files changed, 8 deletions(-) delete mode 100644 doc/_content/donation.md diff --git a/doc/_content/donation.md b/doc/_content/donation.md deleted file mode 100644 index 959eee819..000000000 --- a/doc/_content/donation.md +++ /dev/null @@ -1,7 +0,0 @@ -# 捐赠 -项目目前仍在积极开发。大家的捐赠以及start可以让我看到大家的支持于关注。更加有动力把项目维护下去。 - -
- - -
\ No newline at end of file diff --git a/doc/_sidebar.md b/doc/_sidebar.md index eb0c96c01..3b10bae84 100644 --- a/doc/_sidebar.md +++ b/doc/_sidebar.md @@ -29,5 +29,4 @@ - [设备注册不上来的解决办法](_content/qa/regiser_error.md) - [点播超时/报错的解决办法](_content/qa/play_error.md) * [**免责声明**](_content/disclaimers.md) -* [**捐赠**](_content/donation.md) * [**关于本文档**](_content/about_doc.md) From 9f680a2e9e8560cf5f38acdc30335e51d88b2001 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Fri, 26 Aug 2022 18:03:09 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E6=8C=89=E7=85=A7=EF=BC=8C=E9=94=99=E8=AF=AF?= =?UTF-8?q?/sip/=E6=95=B0=E6=8D=AE=E5=BA=93=20=E5=88=86=E5=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/common/StreamInfo.java | 10 +++ .../AnonymousAuthenticationEntryPoint.java | 6 +- .../vmp/conf/security/UrlTokenHandler.java | 24 ++++++ .../genersoft/iot/vmp/gb28181/SipLayer.java | 14 +++- .../transmit/SIPProcessorObserver.java | 2 - .../transmit/cmd/impl/SIPCommander.java | 2 +- .../request/impl/InviteRequestProcessor.java | 1 + .../impl/SubscribeRequestProcessor.java | 1 - .../notify/cmd/AlarmNotifyMessageHandler.java | 2 +- .../vmp/media/zlm/ZLMHttpHookListener.java | 33 +++++---- .../vmp/media/zlm/ZLMRTPServerFactory.java | 7 +- .../service/impl/MediaServerServiceImpl.java | 2 +- .../vmp/service/impl/MediaServiceImpl.java | 3 +- .../iot/vmp/service/impl/PlayServiceImpl.java | 3 +- .../service/impl/RedisAlarmMsgListener.java | 32 +++++--- .../service/impl/RedisGbPlayMsgListener.java | 2 +- .../service/impl/StreamProxyServiceImpl.java | 3 +- .../iot/vmp/storager/IRedisCatchStorage.java | 2 + .../storager/impl/RedisCatchStorageImpl.java | 18 +++++ .../com/genersoft/iot/vmp/utils/DateUtil.java | 5 ++ .../gb28181/platform/PlatformController.java | 3 +- .../streamPush/StreamPushController.java | 74 +++++++------------ src/main/resources/logback-spring-local.xml | 30 +++++--- .../src/components/dialog/devicePlayer.vue | 2 +- .../src/components/dialog/platformEdit.vue | 19 +++-- 25 files changed, 187 insertions(+), 113 deletions(-) create mode 100644 src/main/java/com/genersoft/iot/vmp/conf/security/UrlTokenHandler.java diff --git a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java index 4f717f05e..41a56cd61 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java @@ -31,6 +31,8 @@ public class StreamInfo { private String rtsp; private String rtsps; private String rtc; + + private String rtcs; private String mediaServerId; private Object tracks; private String startTime; @@ -302,4 +304,12 @@ public class StreamInfo { public void setIp(String ip) { this.ip = ip; } + + public String getRtcs() { + return rtcs; + } + + public void setRtcs(String rtcs) { + this.rtcs = rtcs; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/conf/security/AnonymousAuthenticationEntryPoint.java b/src/main/java/com/genersoft/iot/vmp/conf/security/AnonymousAuthenticationEntryPoint.java index 95b226253..9cdd2a49c 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/security/AnonymousAuthenticationEntryPoint.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/security/AnonymousAuthenticationEntryPoint.java @@ -1,6 +1,8 @@ package com.genersoft.iot.vmp.conf.security; import com.alibaba.fastjson.JSONObject; +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; +import org.apache.poi.hssf.eventmodel.ERFListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.AuthenticationException; @@ -28,8 +30,8 @@ public class AnonymousAuthenticationEntryPoint implements AuthenticationEntryPoi response.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified"); response.setHeader("Content-type", "application/json;charset=UTF-8"); JSONObject jsonObject = new JSONObject(); - jsonObject.put("code", "-1"); - jsonObject.put("msg", "请登录后重新请求"); + jsonObject.put("code", ErrorCode.ERROR401.getCode()); + jsonObject.put("msg", ErrorCode.ERROR401.getMsg()); String logUri = "api/user/login"; if (request.getRequestURI().contains(logUri)){ jsonObject.put("msg", e.getMessage()); diff --git a/src/main/java/com/genersoft/iot/vmp/conf/security/UrlTokenHandler.java b/src/main/java/com/genersoft/iot/vmp/conf/security/UrlTokenHandler.java new file mode 100644 index 000000000..e63aca4a5 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/conf/security/UrlTokenHandler.java @@ -0,0 +1,24 @@ +package com.genersoft.iot.vmp.conf.security; + +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.SessionCookieConfig; +import javax.servlet.SessionTrackingMode; +import java.util.Collections; + +public class UrlTokenHandler extends SpringBootServletInitializer { + + @Override + public void onStartup(ServletContext servletContext) throws ServletException { + super.onStartup(servletContext); + + servletContext.setSessionTrackingModes( + Collections.singleton(SessionTrackingMode.COOKIE) + ); + SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig(); + sessionCookieConfig.setHttpOnly(true); + + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java index c1811bf43..29253e7a7 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java @@ -2,8 +2,10 @@ package com.genersoft.iot.vmp.gb28181; import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver; +import com.genersoft.iot.vmp.utils.DateUtil; import gov.nist.javax.sip.SipProviderImpl; import gov.nist.javax.sip.SipStackImpl; +import org.apache.commons.lang3.time.DateFormatUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -13,6 +15,7 @@ import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; import javax.sip.*; +import java.text.DateFormat; import java.util.Properties; import java.util.TooManyListenersException; import java.util.concurrent.LinkedBlockingQueue; @@ -52,7 +55,9 @@ public class SipLayer{ * 完整配置参考 gov.nist.javax.sip.SipStackImpl,需要下载源码 * gov/nist/javax/sip/SipStackImpl.class */ - properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true"); + if (logger.isDebugEnabled()) { + properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true"); + } // 接收所有notify请求,即使没有订阅 properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); // 为_NULL _对话框传递_终止的_事件 @@ -67,9 +72,10 @@ public class SipLayer{ * 0; public static final int TRACE_MESSAGES = 16; public static final int * TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32; */ - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "0"); - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log"); - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log"); + if (logger.isDebugEnabled()) { + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "DEBUG"); + } + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "INFO"); sipStack = (SipStackImpl) sipFactory.createSipStack(properties); return sipStack; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 319016c9c..d20dc74d3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -71,7 +71,6 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { @Override @Async public void processRequest(RequestEvent requestEvent) { - logger.debug("\n收到请求:\n{}", requestEvent.getRequest()); String method = requestEvent.getRequest().getMethod(); ISIPRequestProcessor sipRequestProcessor = requestProcessorMap.get(method); if (sipRequestProcessor == null) { @@ -90,7 +89,6 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { @Async public void processResponse(ResponseEvent responseEvent) { Response response = responseEvent.getResponse(); - logger.debug("\n收到响应:\n{}", responseEvent.getResponse()); int status = response.getStatusCode(); if (((status >= 200) && (status < 300)) || status == Response.UNAUTHORIZED) { // Success! diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index b9a5011d7..3f6fa0ce9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -640,7 +640,7 @@ public class SIPCommander implements ISIPCommander { hookEvent.call(new InviteStreamInfo(mediaServerItem, json, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream())); subscribe.removeSubscribe(hookSubscribe); hookSubscribe.getContent().put("regist", false); - hookSubscribe.getContent().put("schema", "rtmp"); + hookSubscribe.getContent().put("schema", "rtsp"); // 添加流注销的订阅,注销了后向设备发送bye subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemForEnd, JSONObject jsonForEnd)->{ diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index 34cb753a7..7e284574b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -410,6 +410,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements streamId = String.format("%s_%s", device.getDeviceId(), channelId); } SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false); + logger.info(JSONObject.toJSONString(ssrcInfo)); sendRtpItem.setStreamId(ssrcInfo.getStream()); // 写入redis, 超时时回复 redisCatchStorage.updateSendRTPSever(sendRtpItem); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java index 13cc1b662..6ce2ce053 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java @@ -180,7 +180,6 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme private void processNotifyCatalogList(RequestEvent evt, Element rootElement) throws SipException { - System.out.println(evt.getRequest().toString()); String platformId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); String deviceId = XmlUtil.getText(rootElement, "DeviceID"); ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java index 4ea5d92b9..98fd7a7c1 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java +++ b/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 } } - if (channelId.equals(sipConfig.getId())) { + if ("7".equals(deviceAlarm.getAlarmMethod()) ) { // 发送给平台的报警信息。 发送redis通知 AlarmChannelMessage alarmChannelMessage = new AlarmChannelMessage(); alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod())); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 21879ab64..e7c32ef8c 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -7,12 +7,10 @@ import java.util.Map; import com.alibaba.fastjson.JSON; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.UserSetting; -import com.genersoft.iot.vmp.gb28181.bean.Device; -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; -import com.genersoft.iot.vmp.gb28181.bean.GbStream; -import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; +import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -49,6 +47,9 @@ public class ZLMHttpHookListener { @Autowired private SIPCommander cmder; + @Autowired + private SIPCommanderFroPlatform commanderFroPlatform; + @Autowired private IPlayService playService; @@ -237,7 +238,7 @@ public class ZLMHttpHookListener { // 鉴权通过 redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo); // 通知assist新的callId - if (mediaInfo != null) { + if (mediaInfo != null && mediaInfo.getRecordAssistPort() > 0) { assistRESTfulUtils.addStreamCallInfo(mediaInfo, param.getApp(), param.getStream(), callId, null); } }else { @@ -427,7 +428,7 @@ public class ZLMHttpHookListener { }else { redisCatchStorage.removeStreamAuthorityInfo(app, stream); } - if ("rtmp".equals(schema)){ + if ("rtsp".equals(schema)){ logger.info("on_stream_changed:注册->{}, app->{}, stream->{}", regist, app, stream); if (regist) { mediaServerService.addCount(mediaServerId); @@ -523,17 +524,21 @@ public class ZLMHttpHookListener { if ("rtp".equals(app)){ ret.put("close", true); StreamInfo streamInfoForPlayCatch = redisCatchStorage.queryPlayByStreamId(streamId); - SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransaction(null, null, null, streamId); if (streamInfoForPlayCatch != null) { - // 如果在给上级推流,也不停止。 + // 收到无人观看说明流也没有在往上级推送 if (redisCatchStorage.isChannelSendingRTP(streamInfoForPlayCatch.getChannelId())) { - ret.put("close", false); - } else { - cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId(), - streamInfoForPlayCatch.getStream(), null); - redisCatchStorage.stopPlay(streamInfoForPlayCatch); - storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId()); + List sendRtpItems = redisCatchStorage.querySendRTPServerByChnnelId(streamInfoForPlayCatch.getChannelId()); + if (sendRtpItems.size() > 0) { + for (SendRtpItem sendRtpItem : sendRtpItems) { + ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); + commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId()); + } + } } + cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId(), + streamInfoForPlayCatch.getStream(), null); + redisCatchStorage.stopPlay(streamInfoForPlayCatch); + storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId()); }else{ StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlayback(null, null, streamId, null); if (streamInfoForPlayBackCatch != null) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java index 413a3f858..6c70096e6 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java @@ -92,6 +92,7 @@ public class ZLMRTPServerFactory { int result = -1; // 查询此rtp server 是否已经存在 JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaServerItem, streamId); + logger.info(JSONObject.toJSONString(rtpInfo)); if(rtpInfo.getInteger("code") == 0){ if (rtpInfo.getBoolean("exist")) { result = rtpInfo.getInteger("local_port"); @@ -113,7 +114,7 @@ public class ZLMRTPServerFactory { } param.put("ssrc", ssrc); JSONObject openRtpServerResultJson = zlmresTfulUtils.openRtpServer(mediaServerItem, param); - + logger.info(JSONObject.toJSONString(openRtpServerResultJson)); if (openRtpServerResultJson != null) { if (openRtpServerResultJson.getInteger("code") == 0) { result= openRtpServerResultJson.getInteger("port"); @@ -270,7 +271,7 @@ public class ZLMRTPServerFactory { * 查询待转推的流是否就绪 */ public Boolean isRtpReady(MediaServerItem mediaServerItem, String streamId) { - JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem,"rtp", "rtmp", streamId); + JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem,"rtp", "rtsp", streamId); return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")); } @@ -290,7 +291,7 @@ public class ZLMRTPServerFactory { * @return */ public int totalReaderCount(MediaServerItem mediaServerItem, String app, String streamId) { - JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId); + JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtsp", streamId); if (mediaInfo == null) { return 0; } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java index f6d3eef47..55b32d90f 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java @@ -417,7 +417,7 @@ public class MediaServerServiceImpl implements IMediaServerService { if (RedisUtil.zScore(key, serverItem.getId()) == null) { // 不存在则设置默认值 已存在则重置 RedisUtil.zAdd(key, serverItem.getId(), 0L); // 查询服务流数量 - zlmresTfulUtils.getMediaList(serverItem, null, null, "rtmp",(mediaList ->{ + zlmresTfulUtils.getMediaList(serverItem, null, null, "rtsp",(mediaList ->{ Integer code = mediaList.getInteger("code"); if (code == 0) { JSONArray data = mediaList.getJSONArray("data"); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 876dc9c78..ab1fd55b7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -112,6 +112,7 @@ public class MediaServiceImpl implements IMediaService { streamInfoResult.setWs_fmp4(String.format("ws://%s:%s/%s/%s.live.mp4%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam)); streamInfoResult.setTs(String.format("http://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam)); streamInfoResult.setWs_ts(String.format("ws://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam)); + 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)); if (mediaInfo.getHttpSSlPort() != 0) { streamInfoResult.setHttps_flv(String.format("https://%s:%s/%s/%s.live.flv%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); streamInfoResult.setWss_flv(String.format("wss://%s:%s/%s/%s.live.flv%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); @@ -122,7 +123,7 @@ public class MediaServiceImpl implements IMediaService { streamInfoResult.setHttps_ts(String.format("https://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); - streamInfoResult.setRtc(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)); + 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)); } streamInfoResult.setTracks(tracks); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 56fd65bae..e00eb5571 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -195,6 +195,7 @@ public class PlayServiceImpl implements IPlayService { streamId = String.format("%s_%s", device.getDeviceId(), channelId); } SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, device.isSsrcCheck(), false); + logger.info(JSONObject.toJSONString(ssrcInfo)); play(mediaServerItem, ssrcInfo, device, channelId, (mediaServerItemInUse, response)->{ if (hookEvent != null) { hookEvent.response(mediaServerItem, response); @@ -306,7 +307,7 @@ public class PlayServiceImpl implements IPlayService { // 单端口模式streamId也有变化,需要重新设置监听 if (!mediaServerItem.isRtpEnable()) { // 添加订阅 - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtmp", mediaServerItem.getId()); + HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId()); subscribe.removeSubscribe(hookSubscribe); hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase()); subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response)->{ diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java index 4d1948af6..1634234a4 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java @@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSON; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; +import com.genersoft.iot.vmp.service.IPlatformChannelService; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.utils.DateUtil; import org.slf4j.Logger; @@ -12,6 +14,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.MessageListener; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import java.util.List; @Component @@ -37,8 +42,6 @@ public class RedisAlarmMsgListener implements MessageListener { return; } String gbId = alarmChannelMessage.getGbId(); - Device device = storage.queryVideoDevice(gbId); - ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId); DeviceAlarm deviceAlarm = new DeviceAlarm(); deviceAlarm.setCreateTime(DateUtil.getNow()); @@ -46,18 +49,29 @@ public class RedisAlarmMsgListener implements MessageListener { deviceAlarm.setAlarmDescription(alarmChannelMessage.getAlarmDescription()); deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn()); deviceAlarm.setAlarmPriority("1"); - deviceAlarm.setAlarmTime(DateUtil.getNow()); + deviceAlarm.setAlarmTime(DateUtil.getNowForISO8601()); deviceAlarm.setAlarmType("1"); deviceAlarm.setLongitude(0); deviceAlarm.setLatitude(0); - - if (device != null && platform == null) { - commander.sendAlarmMessage(device, deviceAlarm); - }else if (device == null && platform != null){ - commanderForPlatform.sendAlarmMessage(platform, deviceAlarm); + if (ObjectUtils.isEmpty(gbId)) { + // 发送给所有的上级 + List parentPlatforms = storage.queryEnableParentPlatformList(true); + if (parentPlatforms.size() > 0) { + for (ParentPlatform parentPlatform : parentPlatforms) { + commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm); + } + } }else { - logger.warn("无法确定" + gbId + "是平台还是设备"); + Device device = storage.queryVideoDevice(gbId); + ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId); + if (device != null && platform == null) { + commander.sendAlarmMessage(device, deviceAlarm); + }else if (device == null && platform != null){ + commanderForPlatform.sendAlarmMessage(platform, deviceAlarm); + }else { + logger.warn("无法确定" + gbId + "是平台还是设备"); + } } } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java index 0f5f57c72..4ef1d0156 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java @@ -271,7 +271,7 @@ public class RedisGbPlayMsgListener implements MessageListener { }, userSetting.getPlatformPlayTimeout()); // 添加订阅 - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(content.getApp(), content.getStream(), true, "rtmp", mediaServerItem.getId()); + HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(content.getApp(), content.getStream(), true, "rtsp", mediaServerItem.getId()); subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json)->{ dynamicTask.stop(taskKey); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index 8fabbda60..e217ca961 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -301,7 +301,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService { if (jsonObject == null) { return false; } - System.out.println(jsonObject); if (jsonObject.getInteger("code") == 0) { result = true; streamProxy.setEnable(true); @@ -427,7 +426,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { if(data != null && data.size() > 0) { for (int i = 0; i < data.size(); i++) { JSONObject streamJSONObj = data.getJSONObject(i); - if ("rtmp".equals(streamJSONObj.getString("schema"))) { + if ("rtsp".equals(streamJSONObj.getString("schema"))) { StreamInfo streamInfo = new StreamInfo(); String app = streamJSONObj.getString("app"); String stream = streamJSONObj.getString("stream"); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java index d10de489f..b3bb89ccd 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java @@ -237,4 +237,6 @@ public interface IRedisCatchStorage { * 发送redis消息 查询所有推流设备的状态 */ void sendStreamPushRequestedMsgForStatus(); + + List querySendRTPServerByChnnelId(String channelId); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java index ff31c1191..a401ee2ed 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -379,6 +379,24 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { } } + @Override + public List querySendRTPServerByChnnelId(String channelId) { + if (channelId == null) { + return null; + } + String platformGbId = "*"; + String callId = "*"; + String streamId = "*"; + String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetting.getServerId() + "_" + platformGbId + + "_" + channelId + "_" + streamId + "_" + callId; + List scan = RedisUtil.scan(key); + List result = new ArrayList<>(); + for (Object o : scan) { + result.add((SendRtpItem) RedisUtil.get((String) o)); + } + return result; + } + @Override public List querySendRTPServer(String platformGbId) { if (platformGbId == null) { diff --git a/src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java b/src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java index 494bcbbb0..f7e07293a 100644 --- a/src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java @@ -82,4 +82,9 @@ public class DateUtil { return false; } } + + public static String getNowForISO8601() { + LocalDateTime nowDateTime = LocalDateTime.now(); + return formatterISO8601.format(nowDateTime); + } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java index 14b7a37b7..0e003e576 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java @@ -197,7 +197,7 @@ public class PlatformController { @Operation(summary = "保存上级平台信息") @PostMapping("/save") @ResponseBody - public String savePlatform(@RequestBody ParentPlatform parentPlatform) { + public void savePlatform(@RequestBody ParentPlatform parentPlatform) { if (logger.isDebugEnabled()) { logger.debug("保存上级平台信息API调用"); @@ -247,7 +247,6 @@ public class PlatformController { // 停止订阅相关的定时任务 subscribeHolder.removeAllSubscribe(parentPlatform.getServerGBId()); } - return null; } else { throw new ControllerException(ErrorCode.ERROR100.getCode(),"写入数据库失败"); } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java index d8a87d785..d0aff58e3 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java @@ -5,6 +5,7 @@ import com.alibaba.excel.ExcelReader; import com.alibaba.excel.read.metadata.ReadSheet; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.UserSetting; +import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.SecurityUtils; import com.genersoft.iot.vmp.conf.security.dto.LoginUser; import com.genersoft.iot.vmp.gb28181.bean.GbStream; @@ -17,6 +18,7 @@ import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.service.impl.StreamPushUploadFileHandler; import com.genersoft.iot.vmp.vmanager.bean.BatchGBStreamParam; +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.github.pagehelper.PageInfo; @@ -95,11 +97,9 @@ public class StreamPushController { @PostMapping(value = "/save_to_gb") @ResponseBody @Operation(summary = "将推流添加到国标") - public Object saveToGB(@RequestBody GbStream stream){ - if (streamPushService.saveToGB(stream)){ - return "success"; - }else { - return "fail"; + public void saveToGB(@RequestBody GbStream stream){ + if (!streamPushService.saveToGB(stream)){ + throw new ControllerException(ErrorCode.ERROR100); } } @@ -107,11 +107,9 @@ public class StreamPushController { @DeleteMapping(value = "/remove_form_gb") @ResponseBody @Operation(summary = "将推流移出到国标") - public Object removeFormGB(@RequestBody GbStream stream){ - if (streamPushService.removeFromGB(stream)){ - return "success"; - }else { - return "fail"; + public void removeFormGB(@RequestBody GbStream stream){ + if (!streamPushService.removeFromGB(stream)){ + throw new ControllerException(ErrorCode.ERROR100); } } @@ -121,25 +119,21 @@ public class StreamPushController { @Operation(summary = "中止一个推流") @Parameter(name = "app", description = "应用名", required = true) @Parameter(name = "stream", description = "流id", required = true) - public Object stop(String app, String streamId){ - if (streamPushService.stop(app, streamId)){ - return "success"; - }else { - return "fail"; + public void stop(String app, String streamId){ + if (!streamPushService.stop(app, streamId)){ + throw new ControllerException(ErrorCode.ERROR100); } } @DeleteMapping(value = "/batchStop") @ResponseBody @Operation(summary = "中止多个推流") - public Object batchStop(@RequestBody BatchGBStreamParam batchGBStreamParam){ + public void batchStop(@RequestBody BatchGBStreamParam batchGBStreamParam){ if (batchGBStreamParam.getGbStreams().size() == 0) { - return "fail"; + throw new ControllerException(ErrorCode.ERROR100); } - if (streamPushService.batchStop(batchGBStreamParam.getGbStreams())){ - return "success"; - }else { - return "fail"; + if (!streamPushService.batchStop(batchGBStreamParam.getGbStreams())){ + throw new ControllerException(ErrorCode.ERROR100); } } @@ -249,7 +243,7 @@ public class StreamPushController { @Parameter(name = "app", description = "应用名", required = true) @Parameter(name = "stream", description = "流id", required = true) @Parameter(name = "mediaServerId", description = "媒体服务器id") - public WVPResult getPlayUrl(@RequestParam String app,@RequestParam String stream, + public StreamInfo getPlayUrl(@RequestParam String app,@RequestParam String stream, @RequestParam(required = false) String mediaServerId){ boolean authority = false; // 是否登陆用户, 登陆用户返回完整信息 @@ -257,52 +251,38 @@ public class StreamPushController { if (userInfo!= null) { authority = true; } - WVPResult result = new WVPResult<>(); StreamPushItem push = streamPushService.getPush(app, stream); if (push != null && !push.isSelf()) { - result.setCode(-1); - result.setMsg("来自其他平台的推流信息"); - return result; + throw new ControllerException(ErrorCode.ERROR100.getCode(), "来自其他平台的推流信息"); } StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority); - if (streamInfo != null){ - result.setCode(0); - result.setMsg("success"); - result.setData(streamInfo); - }else { - result.setCode(-1); - result.setMsg("获取播放地址失败"); + if (streamInfo == null){ + throw new ControllerException(ErrorCode.ERROR100.getCode(), "获取播放地址失败"); } - - return result; + return streamInfo; } /** - * 获取推流播放地址 + * 添加推流信息 * @param stream 推流信息 * @return */ @PostMapping(value = "/add") @ResponseBody - @Operation(summary = "停止视频回放") - public WVPResult add(@RequestBody StreamPushItem stream){ + @Operation(summary = "添加推流信息") + public void add(@RequestBody StreamPushItem stream){ if (ObjectUtils.isEmpty(stream.getGbId())) { - - return new WVPResult<>(400, "国标ID不可为空", null); + throw new ControllerException(ErrorCode.ERROR400.getCode(), "国标ID不可为空"); } if (ObjectUtils.isEmpty(stream.getApp()) && ObjectUtils.isEmpty(stream.getStream())) { - return new WVPResult<>(400, "app或stream不可为空", null); + throw new ControllerException(ErrorCode.ERROR400.getCode(), "app或stream不可为空"); } stream.setStatus(false); stream.setPushIng(false); stream.setAliveSecond(0L); stream.setTotalReaderCount("0"); - boolean result = streamPushService.add(stream); - - if (result) { - return new WVPResult<>(0, "success", null); - }else { - return new WVPResult<>(-1, "fail", null); + if (!streamPushService.add(stream)) { + throw new ControllerException(ErrorCode.ERROR100); } } } diff --git a/src/main/resources/logback-spring-local.xml b/src/main/resources/logback-spring-local.xml index 9e583553a..b9d3b39ee 100644 --- a/src/main/resources/logback-spring-local.xml +++ b/src/main/resources/logback-spring-local.xml @@ -77,25 +77,35 @@ + + + + + ${LOG_HOME}/sip-%d{yyyy-MM-dd}.%i.log + + 30 + 50MB + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n + + + - - - - - - - - + + + + - + - diff --git a/web_src/src/components/dialog/devicePlayer.vue b/web_src/src/components/dialog/devicePlayer.vue index 336a27fc7..71530cec6 100644 --- a/web_src/src/components/dialog/devicePlayer.vue +++ b/web_src/src/components/dialog/devicePlayer.vue @@ -371,7 +371,7 @@ export default { if (tab.name === "codec") { this.$axios({ method: 'get', - url: '/zlm/' +this.mediaServerId+ '/index/api/getMediaInfo?vhost=__defaultVhost__&schema=rtmp&app='+ this.app +'&stream='+ this.streamId + url: '/zlm/' +this.mediaServerId+ '/index/api/getMediaInfo?vhost=__defaultVhost__&schema=rtsp&app='+ this.app +'&stream='+ this.streamId }).then(function (res) { that.tracksLoading = false; if (res.data.code == 0 && res.data.tracks) { diff --git a/web_src/src/components/dialog/platformEdit.vue b/web_src/src/components/dialog/platformEdit.vue index d2ebb84d8..633160b31 100644 --- a/web_src/src/components/dialog/platformEdit.vue +++ b/web_src/src/components/dialog/platformEdit.vue @@ -268,30 +268,29 @@ export default { } }, saveForm: function (){ - var that = this; - that.$axios({ + this.$axios({ method: 'post', url: this.saveUrl, - data: that.platform - }).then(function (res) { + data: this.platform + }).then((res) =>{ if (res.data.code === 0) { - that.$message({ + this.$message({ showClose: true, message: "保存成功", type: "success", }); - that.showDialog = false; - if (that.listChangeCallback != null) { - that.listChangeCallback(); + this.showDialog = false; + if (this.listChangeCallback != null) { + this.listChangeCallback(); } }else { - that.$message({ + this.$message({ showClose: true, message: res.data.msg, type: "error", }); } - }).catch(function (error) { + }).catch((error)=> { console.log(error); }); }, From 8b6449ce3ac8eb4a0f59f3a6e3974d9190dcd133 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 29 Aug 2022 09:55:09 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- sql/update.sql | 84 ------------------- .../transmit/SIPProcessorObserver.java | 2 +- 3 files changed, 2 insertions(+), 86 deletions(-) diff --git a/pom.xml b/pom.xml index 2b9a838c6..71dd94850 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ com.genersoft wvp-pro - 2.3.1 + 2.3.2 web video platform 国标28181视频平台 diff --git a/sql/update.sql b/sql/update.sql index d61ad3538..e69de29bb 100644 --- a/sql/update.sql +++ b/sql/update.sql @@ -1,84 +0,0 @@ -alter table stream_push - add serverId varchar(50) not null; - -alter table device - add geoCoordSys varchar(50) not null; -alter table device - add treeType varchar(50) not null; -update device set device.geoCoordSys='WGS84'; -update device set device.treeType='CivilCode'; - -alter table device_channel - add longitudeGcj02 double default null; -alter table device_channel - add latitudeGcj02 double default null; -alter table device_channel - add longitudeWgs84 double default null; -alter table device_channel - add latitudeWgs84 double default null; -alter table device_channel - add businessGroupId varchar(50) default null; -alter table device_channel - add gpsTime varchar(50) default null; - - -alter table device_mobile_position - change cnLng longitudeGcj02 double default null; -alter table device_mobile_position - change cnLat latitudeGcj02 double default null; -alter table device_mobile_position - add longitudeWgs84 double default null; -alter table device_mobile_position - add latitudeWgs84 double default null; -alter table device_mobile_position - drop geodeticSystem; -alter table device_mobile_position - add createTime varchar(50) default null; - -alter table device_alarm - add createTime varchar(50) default null; - -alter table gb_stream - change createStamp createTime varchar(50) default null; - -alter table parent_platform - add createTime varchar(50) default null; -alter table parent_platform - add updateTime varchar(50) default null; - -alter table stream_proxy - add updateTime varchar(50) default null; - -alter table stream_push - add pushTime varchar(50) default null; -alter table stream_push - add status int DEFAULT NULL; -alter table stream_push - add updateTime varchar(50) default null; -alter table stream_push - add pushIng int DEFAULT NULL; -alter table stream_push - change createStamp createTime varchar(50) default null; - -alter table gb_stream - drop column status; - -alter table user - add pushKey varchar(50) default null; -update user set pushKey='453df297a57a5a7438934sda801fc3' where id=1; - -alter table parent_platform - add treeType varchar(50) not null; -update parent_platform set parent_platform.treeType='BusinessGroup'; -alter table parent_platform drop shareAllLiveStream; - -alter table platform_catalog - add civilCode varchar(50) default null; -alter table platform_catalog - add businessGroupId varchar(50) default null; - -/********************* ADD ***************************/ -alter table stream_push - add self int DEFAULT NULL; - - diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index d20dc74d3..13f04b6d4 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -112,7 +112,7 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { } else if ((status >= 100) && (status < 200)) { // 增加其它无需回复的响应,如101、180等 } else { - logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/); + logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()); if (responseEvent.getResponse() != null && sipSubscribe.getErrorSubscribesSize() > 0 ) { CallIdHeader callIdHeader = (CallIdHeader)responseEvent.getResponse().getHeader(CallIdHeader.NAME); if (callIdHeader != null) { From 6e90050db47ca1d9ecec3de6bd95ea1bd1ca4060 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 29 Aug 2022 11:50:36 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E5=8E=BB=E9=99=A4zlm=E4=BD=BF=E7=94=A8redi?= =?UTF-8?q?s=E8=BF=87=E6=9C=9F=E4=BD=9C=E4=B8=BA=E5=BF=83=E8=B7=B3?= =?UTF-8?q?=E8=B6=85=E6=97=B6=E7=9A=84=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/common/VideoManagerConstants.java | 2 - ...edisKeyExpirationEventMessageListener.java | 3 +- .../KeepaliveTimeoutListenerForPlatform.java | 81 +++++++++++++++++++ .../zlm/event/ZLMKeepliveTimeoutListener.java | 72 ----------------- .../service/impl/MediaServerServiceImpl.java | 40 +++++++-- 5 files changed, 118 insertions(+), 80 deletions(-) rename src/main/java/com/genersoft/iot/vmp/conf/{ => redis}/RedisKeyExpirationEventMessageListener.java (94%) create mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMKeepliveTimeoutListener.java diff --git a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java index bbbfce971..7a122c774 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java +++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java @@ -14,8 +14,6 @@ public class VideoManagerConstants { public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_"; - public static final String MEDIA_SERVER_KEEPALIVE_PREFIX = "VMP_MEDIA_SERVER_KEEPALIVE_"; - public static final String MEDIA_SERVERS_ONLINE_PREFIX = "VMP_MEDIA_ONLINE_SERVERS_"; public static final String MEDIA_STREAM_PREFIX = "VMP_MEDIA_STREAM"; diff --git a/src/main/java/com/genersoft/iot/vmp/conf/RedisKeyExpirationEventMessageListener.java b/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisKeyExpirationEventMessageListener.java similarity index 94% rename from src/main/java/com/genersoft/iot/vmp/conf/RedisKeyExpirationEventMessageListener.java rename to src/main/java/com/genersoft/iot/vmp/conf/redis/RedisKeyExpirationEventMessageListener.java index ef4a6172e..b3adab52e 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/RedisKeyExpirationEventMessageListener.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisKeyExpirationEventMessageListener.java @@ -1,5 +1,6 @@ -package com.genersoft.iot.vmp.conf; +package com.genersoft.iot.vmp.conf.redis; +import com.genersoft.iot.vmp.conf.UserSetting; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; import org.springframework.data.redis.listener.RedisMessageListenerContainer; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java new file mode 100644 index 000000000..ead824649 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java @@ -0,0 +1,81 @@ +package com.genersoft.iot.vmp.gb28181.event.offline; + +import com.genersoft.iot.vmp.conf.UserSetting; +import com.genersoft.iot.vmp.conf.redis.RedisKeyExpirationEventMessageListener; +import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; +import com.genersoft.iot.vmp.storager.IVideoManagerStorage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.connection.Message; +import org.springframework.data.redis.listener.RedisMessageListenerContainer; +import org.springframework.stereotype.Component; + +import com.genersoft.iot.vmp.common.VideoManagerConstants; +import com.genersoft.iot.vmp.gb28181.event.EventPublisher; + +/** + * 设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件 + * @author swwheihei + */ +@Component +public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEventMessageListener { + + private Logger logger = LoggerFactory.getLogger(KeepaliveTimeoutListenerForPlatform.class); + + @Autowired + private EventPublisher publisher; + + @Autowired + private UserSetting userSetting; + + @Autowired + private SipSubscribe sipSubscribe; + + @Autowired + private IVideoManagerStorage storager; + + public KeepaliveTimeoutListenerForPlatform(RedisMessageListenerContainer listenerContainer, UserSetting userSetting) { + super(listenerContainer, userSetting); + } + + + /** + * 监听失效的key + * @param message + * @param pattern + */ + @Override + public void onMessage(Message message, byte[] pattern) { + // 获取失效的key + String expiredKey = message.toString(); + // 平台心跳到期,需要重发, 判断是否已经多次未收到心跳回复, 多次未收到,则重新发起注册, 注册尝试多次未得到回复,则认为平台离线 + String PLATFORM_KEEPLIVEKEY_PREFIX = VideoManagerConstants.PLATFORM_KEEPALIVE_PREFIX + userSetting.getServerId() + "_"; + String PLATFORM_REGISTER_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_PREFIX + userSetting.getServerId() + "_"; + String REGISTER_INFO_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_"; + if (expiredKey.startsWith(PLATFORM_KEEPLIVEKEY_PREFIX)) { + String platformGbId = expiredKey.substring(PLATFORM_KEEPLIVEKEY_PREFIX.length()); + ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGbId); + if (platform != null) { + publisher.platformKeepaliveExpireEventPublish(platformGbId); + } + }else if (expiredKey.startsWith(PLATFORM_REGISTER_PREFIX)) { + String platformGbId = expiredKey.substring(PLATFORM_REGISTER_PREFIX.length(),expiredKey.length()); + ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGbId); + if (platform != null) { + publisher.platformRegisterCycleEventPublish(platformGbId); + } + }else if (expiredKey.startsWith(REGISTER_INFO_PREFIX)) { + String callId = expiredKey.substring(REGISTER_INFO_PREFIX.length()); + if (sipSubscribe.getErrorSubscribe(callId) != null) { + SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(); + eventResult.callId = callId; + eventResult.msg = "注册超时"; + eventResult.type = "register timeout"; + sipSubscribe.getErrorSubscribe(callId).response(eventResult); + } + } + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMKeepliveTimeoutListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMKeepliveTimeoutListener.java deleted file mode 100644 index d3af23c0b..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMKeepliveTimeoutListener.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.genersoft.iot.vmp.media.zlm.event; - -import com.alibaba.fastjson.JSONObject; -import com.genersoft.iot.vmp.common.VideoManagerConstants; -import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener; -import com.genersoft.iot.vmp.conf.UserSetting; -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.service.IMediaServerService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.connection.Message; -import org.springframework.data.redis.listener.RedisMessageListenerContainer; -import org.springframework.stereotype.Component; - -/** - * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件 - * @author: swwheihei - * @date: 2020年5月6日 上午11:35:46 - */ -@Component -public class ZLMKeepliveTimeoutListener extends RedisKeyExpirationEventMessageListener { - - private Logger logger = LoggerFactory.getLogger(ZLMKeepliveTimeoutListener.class); - - @Autowired - private EventPublisher publisher; - - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; - - @Autowired - private UserSetting userSetting; - - @Autowired - private IMediaServerService mediaServerService; - - public ZLMKeepliveTimeoutListener(RedisMessageListenerContainer listenerContainer, UserSetting userSetting) { - super(listenerContainer, userSetting); - } - - - /** - * 监听失效的key,key格式为keeplive_deviceId - * @param message - * @param pattern - */ - @Override - public void onMessage(Message message, byte[] pattern) { - // 获取失效的key - String expiredKey = message.toString(); - String KEEPLIVEKEY_PREFIX = VideoManagerConstants.MEDIA_SERVER_KEEPALIVE_PREFIX + userSetting.getServerId() + "_"; - if(!expiredKey.startsWith(KEEPLIVEKEY_PREFIX)){ - return; - } - - String mediaServerId = expiredKey.substring(KEEPLIVEKEY_PREFIX.length(),expiredKey.length()); - logger.info("[zlm心跳到期]:" + mediaServerId); - // 发起http请求验证zlm是否确实无法连接,如果确实无法连接则发送离线事件,否则不作处理 - MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); - JSONObject mediaServerConfig = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); - if (mediaServerConfig != null && mediaServerConfig.getInteger("code") == 0) { - logger.info("[zlm心跳到期]:{}验证后zlm仍在线,恢复心跳信息", mediaServerId); - // 添加zlm信息 - mediaServerService.updateMediaServerKeepalive(mediaServerId, mediaServerConfig); - }else { - publisher.zlmOfflineEventPublish(mediaServerId); - } - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java index 55b32d90f..385dd5e44 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import org.slf4j.Logger; @@ -53,6 +54,8 @@ public class MediaServerServiceImpl implements IMediaServerService { private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class); + private final String zlmKeepaliveKeyPrefix = "zlm-keepalive_"; + @Autowired private SipConfig sipConfig; @@ -83,10 +86,12 @@ public class MediaServerServiceImpl implements IMediaServerService { @Autowired private ZLMRTPServerFactory zlmrtpServerFactory; - @Autowired private EventPublisher publisher; + @Autowired + private DynamicTask dynamicTask; + /** * 初始化 */ @@ -398,11 +403,37 @@ public class MediaServerServiceImpl implements IMediaServerService { if (serverItem.isAutoConfig()) { setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable())); } + final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + serverItem.getId(); + dynamicTask.stop(zlmKeepaliveKey); + dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(serverItem), serverItem.getHookAliveInterval() * 1000); publisher.zlmOnlineEventPublish(serverItem.getId()); logger.info("[ZLM] 连接成功 {} - {}:{} ", zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); } + class KeepAliveTimeoutRunnable implements Runnable{ + + private MediaServerItem serverItem; + + public KeepAliveTimeoutRunnable(MediaServerItem serverItem) { + this.serverItem = serverItem; + } + + @Override + public void run() { + logger.info("[zlm心跳到期]:" + serverItem.getId()); + // 发起http请求验证zlm是否确实无法连接,如果确实无法连接则发送离线事件,否则不作处理 + JSONObject mediaServerConfig = zlmresTfulUtils.getMediaServerConfig(serverItem); + if (mediaServerConfig != null && mediaServerConfig.getInteger("code") == 0) { + logger.info("[zlm心跳到期]:{}验证后zlm仍在线,恢复心跳信息,请检查zlm是否可以正常向wvp发送心跳", serverItem.getId()); + // 添加zlm信息 + updateMediaServerKeepalive(serverItem.getId(), mediaServerConfig); + }else { + publisher.zlmOfflineEventPublish(serverItem.getId()); + } + } + } + @Override public void zlmServerOffline(String mediaServerId) { @@ -429,7 +460,6 @@ public class MediaServerServiceImpl implements IMediaServerService { }else { clearRTPServer(serverItem); } - } @@ -625,9 +655,9 @@ public class MediaServerServiceImpl implements IMediaServerService { return; } } - String key = VideoManagerConstants.MEDIA_SERVER_KEEPALIVE_PREFIX + userSetting.getServerId() + "_" + mediaServerId; - int hookAliveInterval = mediaServerItem.getHookAliveInterval() + 2; - RedisUtil.set(key, data, hookAliveInterval); + final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + mediaServerItem.getId(); + dynamicTask.stop(zlmKeepaliveKey); + dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(mediaServerItem), mediaServerItem.getHookAliveInterval() * 1000); } private MediaServerItem getOneFromDatabase(String mediaServerId) { From 9e2630ee32cf98b7191b8034eabc8f8dd105b22b Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 29 Aug 2022 14:04:54 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E5=A2=9E=E5=8A=A0zlm=E5=BF=83=E8=B7=B3?= =?UTF-8?q?=E8=B6=85=E6=97=B6=E7=9A=84=E5=88=A4=E5=AE=9A=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/service/impl/MediaServerServiceImpl.java | 6 ++++-- .../vmp/vmanager/gb28181/platform/PlatformController.java | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java index 385dd5e44..9ee553109 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java @@ -405,7 +405,7 @@ public class MediaServerServiceImpl implements IMediaServerService { } final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + serverItem.getId(); dynamicTask.stop(zlmKeepaliveKey); - dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(serverItem), serverItem.getHookAliveInterval() * 1000); + dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(serverItem), (serverItem.getHookAliveInterval() + 5) * 1000); publisher.zlmOnlineEventPublish(serverItem.getId()); logger.info("[ZLM] 连接成功 {} - {}:{} ", zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); @@ -438,6 +438,8 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override public void zlmServerOffline(String mediaServerId) { delete(mediaServerId); + final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + mediaServerId; + dynamicTask.stop(zlmKeepaliveKey); } @Override @@ -657,7 +659,7 @@ public class MediaServerServiceImpl implements IMediaServerService { } final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + mediaServerItem.getId(); dynamicTask.stop(zlmKeepaliveKey); - dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(mediaServerItem), mediaServerItem.getHookAliveInterval() * 1000); + dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(mediaServerItem), (mediaServerItem.getHookAliveInterval() + 5) * 1000); } private MediaServerItem getOneFromDatabase(String mediaServerId) { diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java index 0e003e576..2a403301e 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java @@ -179,7 +179,8 @@ public class PlatformController { commanderForPlatform.register(parentPlatform, null, null); } - } else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()) { // 关闭启用时注销 + } else if (parentPlatformOld != null && parentPlatformOld.isEnable()) { + // 关闭启用时注销 commanderForPlatform.unregister(parentPlatform, null, null); } return null; From d47902bdca2eb772c974803a5bd72e917a294b39 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 29 Aug 2022 14:39:18 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E5=90=AF=E5=8A=A8=E6=97=B6redis=E6=9C=AA?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E5=AF=BC=E8=87=B4=E6=97=A0=E6=B3=95=E5=90=AF?= =?UTF-8?q?=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/MediaServerServiceImpl.java | 6 +- .../storager/impl/RedisCatchStorageImpl.java | 1 + .../iot/vmp/utils/SpringBeanFactory.java | 4 +- .../iot/vmp/utils/redis/RedisUtil.java | 164 ++++++++++++++++-- 4 files changed, 158 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java index 9ee553109..d923755a4 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java @@ -20,7 +20,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; @@ -40,7 +39,6 @@ import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.dao.MediaServerMapper; import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.redis.RedisUtil; -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -135,7 +133,7 @@ public class MediaServerServiceImpl implements IMediaServerService { logger.info("media server [ {} ] ssrcConfig is null", mediaServerItem.getId()); return null; }else { - String ssrc = null; + String ssrc; if (presetSsrc != null) { ssrc = presetSsrc; }else { @@ -497,7 +495,7 @@ public class MediaServerServiceImpl implements IMediaServerService { } // 获取分数最低的,及并发最低的 - Set objects = RedisUtil.ZRange(key, 0, -1); + Set objects = RedisUtil.zRange(key, 0, -1); ArrayList mediaServerObjectS = new ArrayList<>(objects); String mediaServerId = (String)mediaServerObjectS.get(0); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java index a401ee2ed..14a369cce 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -21,6 +21,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; import java.util.*; diff --git a/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java b/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java index b155bcd25..532387545 100644 --- a/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java @@ -33,11 +33,11 @@ public class SpringBeanFactory implements ApplicationContextAware { /** * 获取对象 这里重写了bean方法,起主要作用 */ - public static Object getBean(String beanId) throws BeansException { + public static T getBean(String beanId) throws BeansException { if (applicationContext == null) { return null; } - return applicationContext.getBean(beanId); + return (T) applicationContext.getBean(beanId); } /** diff --git a/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java b/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java index 5ef0b397e..0034c398a 100644 --- a/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java @@ -5,15 +5,13 @@ import java.util.concurrent.TimeUnit; import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.utils.SpringBeanFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.*; -import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; /** - * @description:Redis工具类 - * @author: swwheihei - * @date: 2020年5月6日 下午8:27:29 + * Redis工具类 + * @author swwheihei + * @date 2020年5月6日 下午8:27:29 */ @SuppressWarnings(value = {"rawtypes", "unchecked"}) public class RedisUtil { @@ -21,9 +19,9 @@ public class RedisUtil { private static RedisTemplate redisTemplate; static { - redisTemplate = (RedisTemplate)SpringBeanFactory.getBean("redisTemplate"); + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); } - + /** * 指定缓存失效时间 * @param key 键 @@ -31,6 +29,9 @@ public class RedisUtil { * @return true / false */ public static boolean expire(String key, long time) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); @@ -45,9 +46,11 @@ public class RedisUtil { /** * 根据 key 获取过期时间 * @param key 键 - * @return */ public static long getExpire(String key) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.getExpire(key, TimeUnit.SECONDS); } @@ -57,6 +60,9 @@ public class RedisUtil { * @return true / false */ public static boolean hasKey(String key) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { return redisTemplate.hasKey(key); } catch (Exception e) { @@ -71,6 +77,9 @@ public class RedisUtil { * @param key 键(一个或者多个) */ public static boolean del(String... key) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { if (key != null && key.length > 0) { if (key.length == 1) { @@ -95,6 +104,9 @@ public class RedisUtil { * @return 值 */ public static Object get(String key) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return key == null ? null : redisTemplate.opsForValue().get(key); } @@ -105,6 +117,9 @@ public class RedisUtil { * @return true / false */ public static boolean set(String key, Object value) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { redisTemplate.opsForValue().set(key, value); return true; @@ -122,6 +137,9 @@ public class RedisUtil { * @return true / false */ public static boolean set(String key, Object value, long time) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { if (time > 0) { redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); @@ -142,6 +160,9 @@ public class RedisUtil { * @return */ public static long incr(String key, long delta) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } if (delta < 0) { throw new RuntimeException("递增因子必须大于 0"); } @@ -155,6 +176,9 @@ public class RedisUtil { * @return */ public static long decr(String key, long delta) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } if (delta < 0) { throw new RuntimeException("递减因子必须大于 0"); } @@ -170,6 +194,9 @@ public class RedisUtil { * @return 值 */ public static Object hget(String key, String item) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForHash().get(key, item); } @@ -179,6 +206,9 @@ public class RedisUtil { * @return 对应的多个键值 */ public static Map hmget(String key) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForHash().entries(key); } @@ -189,6 +219,9 @@ public class RedisUtil { * @return true / false */ public static boolean hmset(String key, Map map) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { redisTemplate.opsForHash().putAll(key, map); return true; @@ -206,6 +239,9 @@ public class RedisUtil { * @return true / false */ public static boolean hmset(String key, Map map, long time) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { redisTemplate.opsForHash().putAll(key, map); if (time > 0) { @@ -226,6 +262,9 @@ public class RedisUtil { * @return true / false */ public static boolean hset(String key, String item, Object value) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { redisTemplate.opsForHash().put(key, item, value); return true; @@ -244,6 +283,9 @@ public class RedisUtil { * @return true / false */ public static boolean hset(String key, String item, Object value, long time) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { redisTemplate.opsForHash().put(key, item, value); if (time > 0) { @@ -262,6 +304,9 @@ public class RedisUtil { * @param item 项(可以多个,no null) */ public static void hdel(String key, Object... item) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } redisTemplate.opsForHash().delete(key, item); } @@ -272,6 +317,9 @@ public class RedisUtil { * @return true / false */ public static boolean hHasKey(String key, String item) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForHash().hasKey(key, item); } @@ -283,6 +331,9 @@ public class RedisUtil { * @return */ public static Double hincr(String key, String item, Double by) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForHash().increment(key, item, by); } @@ -294,6 +345,9 @@ public class RedisUtil { * @return */ public static Double hdecr(String key, String item, Double by) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForHash().increment(key, item, -by); } @@ -305,6 +359,9 @@ public class RedisUtil { * @return 值 */ public static Set sGet(String key) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { return redisTemplate.opsForSet().members(key); } catch (Exception e) { @@ -320,6 +377,9 @@ public class RedisUtil { * @return true / false */ public static boolean sHasKey(String key, Object value) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { return redisTemplate.opsForSet().isMember(key, value); } catch (Exception e) { @@ -335,6 +395,9 @@ public class RedisUtil { * @return 成功个数 */ public static long sSet(String key, Object... values) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { return redisTemplate.opsForSet().add(key, values); } catch (Exception e) { @@ -351,6 +414,9 @@ public class RedisUtil { * @return 成功放入个数 */ public static long sSet(String key, long time, Object... values) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { long count = redisTemplate.opsForSet().add(key, values); if (time > 0) { @@ -369,6 +435,9 @@ public class RedisUtil { * @return 长度 */ public static long sGetSetSize(String key) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { return redisTemplate.opsForSet().size(key); } catch (Exception e) { @@ -384,6 +453,9 @@ public class RedisUtil { * @return 成功移除个数 */ public static long setRemove(String key, Object... values) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { return redisTemplate.opsForSet().remove(key, values); } catch (Exception e) { @@ -401,6 +473,9 @@ public class RedisUtil { * @param score */ public static void zAdd(Object key, Object value, double score) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } redisTemplate.opsForZSet().add(key, value, score); } @@ -411,6 +486,9 @@ public class RedisUtil { * @param value */ public static void zRemove(Object key, Object value) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } redisTemplate.opsForZSet().remove(key, value); } @@ -422,6 +500,9 @@ public class RedisUtil { * @param delta -1 表示减 1 表示加1 */ public static Double zIncrScore(Object key, Object value, double delta) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForZSet().incrementScore(key, value, delta); } @@ -433,6 +514,9 @@ public class RedisUtil { * @return */ public static Double zScore(Object key, Object value) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForZSet().score(key, value); } @@ -444,6 +528,9 @@ public class RedisUtil { * @return */ public static Long zRank(Object key, Object value) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForZSet().rank(key, value); } @@ -454,6 +541,9 @@ public class RedisUtil { * @return */ public static Long zSize(Object key) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForZSet().zCard(key); } @@ -467,7 +557,10 @@ public class RedisUtil { * @param end * @return */ - public static Set ZRange(Object key, int start, int end) { + public static Set zRange(Object key, int start, int end) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForZSet().range(key, start, end); } /** @@ -479,6 +572,9 @@ public class RedisUtil { * @return */ public static Set> zRangeWithScore(Object key, int start, int end) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForZSet().rangeWithScores(key, start, end); } /** @@ -492,6 +588,9 @@ public class RedisUtil { * @return */ public static Set zRevRange(Object key, int start, int end) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForZSet().reverseRange(key, start, end); } /** @@ -503,6 +602,9 @@ public class RedisUtil { * @return */ public static Set zSortRange(Object key, int min, int max) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForZSet().rangeByScore(key, min, max); } @@ -517,6 +619,9 @@ public class RedisUtil { * @return */ public static List lGet(String key, long start, long end) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { return redisTemplate.opsForList().range(key, start, end); } catch (Exception e) { @@ -531,6 +636,9 @@ public class RedisUtil { * @return 长度 */ public static long lGetListSize(String key) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { return redisTemplate.opsForList().size(key); } catch (Exception e) { @@ -548,6 +656,9 @@ public class RedisUtil { * @return 值 */ public static Object lGetIndex(String key, long index) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { return redisTemplate.opsForList().index(key, index); } catch (Exception e) { @@ -563,6 +674,9 @@ public class RedisUtil { * @return true / false */ public static boolean lSet(String key, Object value) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { redisTemplate.opsForList().rightPush(key, value); return true; @@ -580,6 +694,9 @@ public class RedisUtil { * @return true / false */ public static boolean lSet(String key, Object value, long time) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { redisTemplate.opsForList().rightPush(key, value); if (time > 0) { @@ -599,6 +716,9 @@ public class RedisUtil { * @return true / false */ public static boolean lSetList(String key, List values) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { redisTemplate.opsForList().rightPushAll(key, values); return true; @@ -616,6 +736,9 @@ public class RedisUtil { * @return true / false */ public static boolean lSetList(String key, List values, long time) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { redisTemplate.opsForList().rightPushAll(key, values); if (time > 0) { @@ -636,6 +759,9 @@ public class RedisUtil { * @return true / false */ public static boolean lUpdateIndex(String key, long index, Object value) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { redisTemplate.opsForList().set(key, index, value); return true; @@ -655,6 +781,9 @@ public class RedisUtil { * @return */ public static long lRemove(String key, long count, Object value) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { return redisTemplate.opsForList().remove(key, count, value); } catch (Exception e) { @@ -669,6 +798,9 @@ public class RedisUtil { * @return */ public static Object lLeftPop(String key) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForList().leftPop(key); } @@ -678,6 +810,9 @@ public class RedisUtil { * @return */ public static Object lrightPop(String key) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } return redisTemplate.opsForList().rightPop(key); } @@ -687,6 +822,9 @@ public class RedisUtil { * @return true / false */ public static List keys(String key) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } try { Set set = redisTemplate.keys(key); return new ArrayList<>(set); @@ -727,6 +865,9 @@ public class RedisUtil { * @return */ public static List scan(String query) { + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } Set resultKeys = (Set) redisTemplate.execute((RedisCallback>) connection -> { ScanOptions scanOptions = ScanOptions.scanOptions().match("*" + query + "*").count(1000).build(); Cursor scan = connection.scan(scanOptions); @@ -743,9 +884,10 @@ public class RedisUtil { // ============================== 消息发送与订阅 ============================== public static void convertAndSend(String channel, JSONObject msg) { -// redisTemplate.convertAndSend(channel, msg); + if (redisTemplate == null) { + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); + } redisTemplate.convertAndSend(channel, msg); - } } From 2de4c322f6dc79ecfb120106af07e3335994657a Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Wed, 31 Aug 2022 11:29:13 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E5=AF=B9redis=20key?= =?UTF-8?q?=E8=BF=87=E6=9C=9F=E4=BA=8B=E4=BB=B6=E7=9A=84=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=EF=BC=9B=E9=87=8D=E6=9E=84=E5=9B=BD=E6=A0=87=E7=BA=A7=E8=81=94?= =?UTF-8?q?=E7=9A=84=E6=B3=A8=E5=86=8C=E4=BF=9D=E6=B4=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/conf/SipPlatformRunner.java | 35 ++- .../genersoft/iot/vmp/conf/UserSetting.java | 10 - ...edisKeyExpirationEventMessageListener.java | 41 ---- .../genersoft/iot/vmp/gb28181/SipLayer.java | 15 +- .../iot/vmp/gb28181/bean/ParentPlatform.java | 6 +- .../vmp/gb28181/bean/ParentPlatformCatch.java | 4 +- .../iot/vmp/gb28181/bean/SubscribeHolder.java | 3 + .../iot/vmp/gb28181/event/EventPublisher.java | 33 --- .../iot/vmp/gb28181/event/SipSubscribe.java | 28 ++- .../KeepaliveTimeoutListenerForPlatform.java | 81 ------ .../PlatformKeepaliveExpireEvent.java | 28 --- .../PlatformKeepaliveExpireEventLister.java | 87 ------- .../PlatformCycleRegisterEvent.java | 24 -- .../PlatformCycleRegisterEventLister.java | 46 ---- .../PlatformNotRegisterEvent.java | 25 -- .../PlatformNotRegisterEventLister.java | 90 ------- .../subscribe/catalog/CatalogEventLister.java | 13 - .../MobilePositionSubscribeHandlerTask.java | 1 - .../cmd/ISIPCommanderForPlatform.java | 4 +- .../cmd/SIPRequestHeaderPlarformProvider.java | 11 +- .../cmd/SIPRequestHeaderProvider.java | 11 +- .../transmit/cmd/impl/SIPCommander.java | 18 +- .../cmd/impl/SIPCommanderFroPlatform.java | 24 +- .../request/SIPRequestProcessorParent.java | 9 + .../impl/InviteResponseProcessor.java | 11 +- .../impl/RegisterResponseProcessor.java | 54 ++-- .../iot/vmp/gb28181/utils/HeaderUtils.java | 22 ++ .../iot/vmp/media/zlm/AssistRESTfulUtils.java | 2 +- .../vmp/media/zlm/ZLMHttpHookListener.java | 39 ++- .../iot/vmp/service/IPlatformService.java | 45 ++++ .../service/impl/MediaServerServiceImpl.java | 13 +- .../vmp/service/impl/PlatformServiceImpl.java | 232 ++++++++++++++++++ .../iot/vmp/service/impl/PlayServiceImpl.java | 4 +- .../iot/vmp/storager/IRedisCatchStorage.java | 9 +- .../vmp/storager/IVideoManagerStorage.java | 9 - .../dao/dto/PlatformRegisterInfo.java | 41 ++++ .../storager/impl/RedisCatchStorageImpl.java | 21 +- .../impl/VideoManagerStorageImpl.java | 7 - .../iot/vmp/utils/redis/RedisUtil.java | 1 + .../gb28181/platform/PlatformController.java | 39 +-- src/main/resources/all-application.yml | 2 - .../src/components/dialog/MediaServerEdit.vue | 2 +- .../src/components/dialog/StreamProxyEdit.vue | 2 +- .../src/components/dialog/platformEdit.vue | 2 +- .../src/components/dialog/pushStreamEdit.vue | 2 +- 45 files changed, 513 insertions(+), 693 deletions(-) delete mode 100644 src/main/java/com/genersoft/iot/vmp/conf/redis/RedisKeyExpirationEventMessageListener.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEvent.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEventLister.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformCycleRegisterEvent.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformCycleRegisterEventLister.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEvent.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java create mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/utils/HeaderUtils.java create mode 100644 src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java create mode 100644 src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java create mode 100644 src/main/java/com/genersoft/iot/vmp/storager/dao/dto/PlatformRegisterInfo.java diff --git a/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java b/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java index cf16f8642..93674f61c 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java @@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; +import com.genersoft.iot.vmp.service.IPlatformService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import org.springframework.beans.factory.annotation.Autowired; @@ -15,6 +16,7 @@ import java.util.List; /** * 系统启动时控制上级平台重新注册 + * @author lin */ @Component @Order(value=3) @@ -27,7 +29,7 @@ public class SipPlatformRunner implements CommandLineRunner { private IRedisCatchStorage redisCatchStorage; @Autowired - private EventPublisher publisher; + private IPlatformService platformService; @Autowired private ISIPCommanderForPlatform sipCommanderForPlatform; @@ -35,33 +37,26 @@ public class SipPlatformRunner implements CommandLineRunner { @Override public void run(String... args) throws Exception { - // 设置所有平台离线 - storager.outlineForAllParentPlatform(); - - // 清理所有平台注册缓存 - redisCatchStorage.cleanPlatformRegisterInfos(); - - // 停止所有推流 -// zlmrtpServerFactory.closeAllSendRtpStream(); - + // 获取所有启用的平台 List parentPlatforms = storager.queryEnableParentPlatformList(true); for (ParentPlatform parentPlatform : parentPlatforms) { - redisCatchStorage.updatePlatformRegister(parentPlatform); - - redisCatchStorage.updatePlatformKeepalive(parentPlatform); - + // 更新缓存 ParentPlatformCatch parentPlatformCatch = new ParentPlatformCatch(); - parentPlatformCatch.setParentPlatform(parentPlatform); parentPlatformCatch.setId(parentPlatform.getServerGBId()); redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); + if (parentPlatform.isStatus()) { + // 设置所有平台离线 + platformService.offline(parentPlatform); + // 取消订阅 + sipCommanderForPlatform.unregister(parentPlatform, null, (eventResult)->{ + platformService.login(parentPlatform); + }); + }else { + platformService.login(parentPlatform); + } - // 取消订阅 - sipCommanderForPlatform.unregister(parentPlatform, null, (eventResult)->{ - // 发送平台未注册消息 - publisher.platformNotRegisterEventPublish(parentPlatform.getServerGBId()); - }); } } } diff --git a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java index d28ddebc8..017b39db4 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java @@ -31,8 +31,6 @@ public class UserSetting { private Boolean logInDatebase = Boolean.TRUE; - private Boolean redisConfig = Boolean.TRUE; - private String serverId = "000000"; private String thirdPartyGBIdReg = "[\\s\\S]*"; @@ -123,14 +121,6 @@ public class UserSetting { this.thirdPartyGBIdReg = thirdPartyGBIdReg; } - public Boolean getRedisConfig() { - return redisConfig; - } - - public void setRedisConfig(Boolean redisConfig) { - this.redisConfig = redisConfig; - } - public Boolean getRecordSip() { return recordSip; } diff --git a/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisKeyExpirationEventMessageListener.java b/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisKeyExpirationEventMessageListener.java deleted file mode 100644 index b3adab52e..000000000 --- a/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisKeyExpirationEventMessageListener.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.genersoft.iot.vmp.conf.redis; - -import com.genersoft.iot.vmp.conf.UserSetting; -import org.springframework.data.redis.connection.RedisConnection; -import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; -import org.springframework.data.redis.listener.RedisMessageListenerContainer; - -import java.util.Properties; - -public class RedisKeyExpirationEventMessageListener extends KeyExpirationEventMessageListener { - - private UserSetting userSetting; - private RedisMessageListenerContainer listenerContainer; - private String keyspaceNotificationsConfigParameter = "EA"; - - public RedisKeyExpirationEventMessageListener(RedisMessageListenerContainer listenerContainer, UserSetting userSetting) { - super(listenerContainer); - this.listenerContainer = listenerContainer; - this.userSetting = userSetting; - } - - @Override - public void init() { - if (!userSetting.getRedisConfig()) { - // 配置springboot默认Config为空,即不让应用去修改redis的默认配置,因为Redis服务出于安全会禁用CONFIG命令给远程用户使用 - setKeyspaceNotificationsConfigParameter(""); - }else { - - RedisConnection connection = this.listenerContainer.getConnectionFactory().getConnection(); - Properties config = connection.getConfig("notify-keyspace-events"); - try { - if (!keyspaceNotificationsConfigParameter.equals(config.getProperty("notify-keyspace-events"))) { - connection.setConfig("notify-keyspace-events", keyspaceNotificationsConfigParameter); - } - } finally { - connection.close(); - } - } - super.init(); - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java index 29253e7a7..afc56718f 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java @@ -56,7 +56,7 @@ public class SipLayer{ * gov/nist/javax/sip/SipStackImpl.class */ if (logger.isDebugEnabled()) { - properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true"); + properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false"); } // 接收所有notify请求,即使没有订阅 properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); @@ -68,14 +68,13 @@ public class SipLayer{ properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "60"); /** - * sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE = - * 0; public static final int TRACE_MESSAGES = 16; public static final int - * TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32; + * sip_server_log.log 和 sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE */ - if (logger.isDebugEnabled()) { - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "DEBUG"); - } - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "INFO"); + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "ERROR"); +// if (logger.isDebugEnabled()) { +// properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "DEBUG"); +// } + sipStack = (SipStackImpl) sipFactory.createSipStack(properties); return sipStack; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java index ef2eecd5a..ade5d0eef 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java @@ -84,7 +84,7 @@ public class ParentPlatform { * 注册周期 (秒) */ @Schema(description = "注册周期 (秒)") - private String expires; + private int expires; /** * 心跳周期(秒) @@ -286,11 +286,11 @@ public class ParentPlatform { this.password = password; } - public String getExpires() { + public int getExpires() { return expires; } - public void setExpires(String expires) { + public void setExpires(int expires) { this.expires = expires; } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java index 6c429f265..a53d26e48 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java @@ -4,7 +4,9 @@ public class ParentPlatformCatch { private String id; - // 心跳未回复次数 + /** + * 心跳未回复次数 + */ private int keepAliveReply; // 注册未回复次数 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java index 4a900c164..441dff3fd 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java @@ -14,6 +14,9 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; +/** + * @author lin + */ @Component public class SubscribeHolder { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java index 8a4dd3da4..26ababd4c 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java @@ -2,9 +2,6 @@ package com.genersoft.iot.vmp.gb28181.event; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.device.RequestTimeoutEvent; -import com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire.PlatformKeepaliveExpireEvent; -import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformCycleRegisterEvent; -import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformNotRegisterEvent; import com.genersoft.iot.vmp.gb28181.event.record.RecordEndEvent; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; import com.genersoft.iot.vmp.media.zlm.event.ZLMOfflineEvent; @@ -31,36 +28,6 @@ public class EventPublisher { @Autowired private ApplicationEventPublisher applicationEventPublisher; - - /** - * 平台心跳到期事件 - * @param platformGbId - */ - public void platformKeepaliveExpireEventPublish(String platformGbId){ - PlatformKeepaliveExpireEvent platformKeepaliveExpireEvent = new PlatformKeepaliveExpireEvent(this); - platformKeepaliveExpireEvent.setPlatformGbID(platformGbId); - applicationEventPublisher.publishEvent(platformKeepaliveExpireEvent); - } - - /** - * 平台未注册事件 - * @param platformGbId - */ - public void platformNotRegisterEventPublish(String platformGbId){ - PlatformNotRegisterEvent platformNotRegisterEvent = new PlatformNotRegisterEvent(this); - platformNotRegisterEvent.setPlatformGbID(platformGbId); - applicationEventPublisher.publishEvent(platformNotRegisterEvent); - } - - /** - * 平台周期注册事件 - * @param paltformGbId - */ - public void platformRegisterCycleEventPublish(String paltformGbId) { - PlatformCycleRegisterEvent platformCycleRegisterEvent = new PlatformCycleRegisterEvent(this); - platformCycleRegisterEvent.setPlatformGbID(paltformGbId); - applicationEventPublisher.publishEvent(platformCycleRegisterEvent); - } /** * 设备报警事件 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java index c6cfc7a04..b3fd82e8d 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java @@ -59,9 +59,25 @@ public class SipSubscribe { void response(EventResult eventResult); } + /** + * + */ + public enum EventResultType{ + // 超时 + timeout, + // 回复 + response, + // 事务已结束 + transactionTerminated, + // 会话已结束 + dialogTerminated, + // 设备未找到 + deviceNotFoundEvent + } + public static class EventResult{ public int statusCode; - public String type; + public EventResultType type; public String msg; public String callId; public Dialog dialog; @@ -76,7 +92,7 @@ public class SipSubscribe { ResponseEvent responseEvent = (ResponseEvent)event; Response response = responseEvent.getResponse(); this.dialog = responseEvent.getDialog(); - this.type = "response"; + this.type = EventResultType.response; if (response != null) { this.msg = response.getReasonPhrase(); this.statusCode = response.getStatusCode(); @@ -85,28 +101,28 @@ public class SipSubscribe { }else if (event instanceof TimeoutEvent) { TimeoutEvent timeoutEvent = (TimeoutEvent)event; - this.type = "timeout"; + this.type = EventResultType.timeout; this.msg = "消息超时未回复"; this.statusCode = -1024; this.dialog = timeoutEvent.getClientTransaction().getDialog(); this.callId = this.dialog != null?timeoutEvent.getClientTransaction().getDialog().getCallId().getCallId(): null; }else if (event instanceof TransactionTerminatedEvent) { TransactionTerminatedEvent transactionTerminatedEvent = (TransactionTerminatedEvent)event; - this.type = "transactionTerminated"; + this.type = EventResultType.transactionTerminated; this.msg = "事务已结束"; this.statusCode = -1024; this.callId = transactionTerminatedEvent.getClientTransaction().getDialog().getCallId().getCallId(); this.dialog = transactionTerminatedEvent.getClientTransaction().getDialog(); }else if (event instanceof DialogTerminatedEvent) { DialogTerminatedEvent dialogTerminatedEvent = (DialogTerminatedEvent)event; - this.type = "dialogTerminated"; + this.type = EventResultType.dialogTerminated; this.msg = "会话已结束"; this.statusCode = -1024; this.callId = dialogTerminatedEvent.getDialog().getCallId().getCallId(); this.dialog = dialogTerminatedEvent.getDialog(); }else if (event instanceof DeviceNotFoundEvent) { DeviceNotFoundEvent deviceNotFoundEvent = (DeviceNotFoundEvent)event; - this.type = "deviceNotFoundEvent"; + this.type = EventResultType.deviceNotFoundEvent; this.msg = "设备未找到"; this.statusCode = -1024; this.dialog = deviceNotFoundEvent.getDialog(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java deleted file mode 100644 index ead824649..000000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.genersoft.iot.vmp.gb28181.event.offline; - -import com.genersoft.iot.vmp.conf.UserSetting; -import com.genersoft.iot.vmp.conf.redis.RedisKeyExpirationEventMessageListener; -import com.genersoft.iot.vmp.gb28181.bean.Device; -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; -import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.connection.Message; -import org.springframework.data.redis.listener.RedisMessageListenerContainer; -import org.springframework.stereotype.Component; - -import com.genersoft.iot.vmp.common.VideoManagerConstants; -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; - -/** - * 设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件 - * @author swwheihei - */ -@Component -public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEventMessageListener { - - private Logger logger = LoggerFactory.getLogger(KeepaliveTimeoutListenerForPlatform.class); - - @Autowired - private EventPublisher publisher; - - @Autowired - private UserSetting userSetting; - - @Autowired - private SipSubscribe sipSubscribe; - - @Autowired - private IVideoManagerStorage storager; - - public KeepaliveTimeoutListenerForPlatform(RedisMessageListenerContainer listenerContainer, UserSetting userSetting) { - super(listenerContainer, userSetting); - } - - - /** - * 监听失效的key - * @param message - * @param pattern - */ - @Override - public void onMessage(Message message, byte[] pattern) { - // 获取失效的key - String expiredKey = message.toString(); - // 平台心跳到期,需要重发, 判断是否已经多次未收到心跳回复, 多次未收到,则重新发起注册, 注册尝试多次未得到回复,则认为平台离线 - String PLATFORM_KEEPLIVEKEY_PREFIX = VideoManagerConstants.PLATFORM_KEEPALIVE_PREFIX + userSetting.getServerId() + "_"; - String PLATFORM_REGISTER_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_PREFIX + userSetting.getServerId() + "_"; - String REGISTER_INFO_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_"; - if (expiredKey.startsWith(PLATFORM_KEEPLIVEKEY_PREFIX)) { - String platformGbId = expiredKey.substring(PLATFORM_KEEPLIVEKEY_PREFIX.length()); - ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGbId); - if (platform != null) { - publisher.platformKeepaliveExpireEventPublish(platformGbId); - } - }else if (expiredKey.startsWith(PLATFORM_REGISTER_PREFIX)) { - String platformGbId = expiredKey.substring(PLATFORM_REGISTER_PREFIX.length(),expiredKey.length()); - ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGbId); - if (platform != null) { - publisher.platformRegisterCycleEventPublish(platformGbId); - } - }else if (expiredKey.startsWith(REGISTER_INFO_PREFIX)) { - String callId = expiredKey.substring(REGISTER_INFO_PREFIX.length()); - if (sipSubscribe.getErrorSubscribe(callId) != null) { - SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(); - eventResult.callId = callId; - eventResult.msg = "注册超时"; - eventResult.type = "register timeout"; - sipSubscribe.getErrorSubscribe(callId).response(eventResult); - } - } - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEvent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEvent.java deleted file mode 100644 index 1e9a2c4b4..000000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEvent.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire; - -import org.springframework.context.ApplicationEvent; - -/** - * 平台心跳超时事件 - */ -public class PlatformKeepaliveExpireEvent extends ApplicationEvent { - - /** - * Add default serial version ID - */ - private static final long serialVersionUID = 1L; - - private String platformGbID; - - public PlatformKeepaliveExpireEvent(Object source) { - super(source); - } - - public String getPlatformGbID() { - return platformGbID; - } - - public void setPlatformGbID(String platformGbID) { - this.platformGbID = platformGbID; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEventLister.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEventLister.java deleted file mode 100644 index 67b297c3c..000000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEventLister.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire; - -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; -import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.stereotype.Component; - -import javax.sip.message.Response; - -/** - * @description: 平台心跳超时事件 - * @author: panll - * @date: 2020年11月5日 10:00 - */ -@Component -public class PlatformKeepaliveExpireEventLister implements ApplicationListener { - - - private final static Logger logger = LoggerFactory.getLogger(PlatformKeepaliveExpireEventLister.class); - - @Autowired - private IVideoManagerStorage storager; - - @Autowired - private IRedisCatchStorage redisCatchStorage; - - @Autowired - private ISIPCommanderForPlatform sipCommanderForPlatform; - - @Autowired - private SipSubscribe sipSubscribe; - - @Autowired - private EventPublisher publisher; - - @Override - public void onApplicationEvent(@NotNull PlatformKeepaliveExpireEvent event) { - - if (logger.isDebugEnabled()) { - logger.debug("平台心跳到期事件事件触发,平台国标ID:" + event.getPlatformGbID()); - } - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(event.getPlatformGbID()); - ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(event.getPlatformGbID()); - if (parentPlatformCatch == null) { - return; - } - if (parentPlatform == null) { - logger.debug("平台心跳到期事件事件触发,但平台已经删除!!! 平台国标ID:" + event.getPlatformGbID()); - return; - } - parentPlatformCatch.setParentPlatform(parentPlatform); - // 发送心跳 - if (parentPlatformCatch.getKeepAliveReply() >= 3) { - // 有3次未收到心跳回复, 设置平台状态为离线, 开始重新注册 - logger.warn("有3次未收到心跳回复,标记设置平台状态为离线, 并重新注册 平台国标ID:" + event.getPlatformGbID()); - storager.updateParentPlatformStatus(event.getPlatformGbID(), false); - publisher.platformNotRegisterEventPublish(event.getPlatformGbID()); - parentPlatformCatch.setKeepAliveReply(0); - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); - }else { - // 再次发送心跳 - String callId = sipCommanderForPlatform.keepalive(parentPlatform); - - parentPlatformCatch.setKeepAliveReply( parentPlatformCatch.getKeepAliveReply() + 1); - // 存储心跳信息, 并设置状态为未回复, 如果多次过期仍未收到回复,则认为上级平台已经离线 - redisCatchStorage.updatePlatformKeepalive(parentPlatform); - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); - - sipSubscribe.addOkSubscribe(callId, (SipSubscribe.EventResult eventResult) ->{ - if (eventResult.statusCode == Response.OK) { - // 收到心跳响应信息, - parentPlatformCatch.setKeepAliveReply(0); - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); - } - } ); - } - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformCycleRegisterEvent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformCycleRegisterEvent.java deleted file mode 100644 index c2ff61f34..000000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformCycleRegisterEvent.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.genersoft.iot.vmp.gb28181.event.platformNotRegister; - -import org.springframework.context.ApplicationEvent; - -public class PlatformCycleRegisterEvent extends ApplicationEvent { - /** - * Add default serial version ID - */ - private static final long serialVersionUID = 1L; - - private String platformGbID; - - public String getPlatformGbID() { - return platformGbID; - } - - public void setPlatformGbID(String platformGbID) { - this.platformGbID = platformGbID; - } - - public PlatformCycleRegisterEvent(Object source) { - super(source); - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformCycleRegisterEventLister.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformCycleRegisterEventLister.java deleted file mode 100644 index d2a9246f4..000000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformCycleRegisterEventLister.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.genersoft.iot.vmp.gb28181.event.platformNotRegister; - -import com.genersoft.iot.vmp.conf.DynamicTask; -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; -import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.stereotype.Component; - -import java.util.Timer; -import java.util.TimerTask; - -@Component -public class PlatformCycleRegisterEventLister implements ApplicationListener { - - private final static Logger logger = LoggerFactory.getLogger(PlatformCycleRegisterEventLister.class); - - @Autowired - private IVideoManagerStorage storager; - @Autowired - private ISIPCommanderForPlatform sipCommanderFroPlatform; - @Autowired - private DynamicTask dynamicTask; - - @Override - public void onApplicationEvent(PlatformCycleRegisterEvent event) { - logger.info("上级平台周期注册事件"); - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(event.getPlatformGbID()); - if (parentPlatform == null) { - logger.info("[ 平台未注册事件 ] 平台已经删除!!! 平台国标ID:" + event.getPlatformGbID()); - return; - } - String taskKey = "platform-cycle-register" + parentPlatform.getServerGBId();; - SipSubscribe.Event okEvent = (responseEvent)->{ - dynamicTask.stop(taskKey); - }; - dynamicTask.startCron(taskKey, ()->{ - logger.info("[平台注册]再次向平台注册,平台国标ID:" + event.getPlatformGbID()); - sipCommanderFroPlatform.register(parentPlatform, null, okEvent); - }, Integer.parseInt(parentPlatform.getExpires())* 1000); - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEvent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEvent.java deleted file mode 100644 index c9369754a..000000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEvent.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.genersoft.iot.vmp.gb28181.event.platformNotRegister; - -import org.springframework.context.ApplicationEvent; - -public class PlatformNotRegisterEvent extends ApplicationEvent { - - /** - * Add default serial version ID - */ - private static final long serialVersionUID = 1L; - - private String platformGbID; - - public PlatformNotRegisterEvent(Object source) { - super(source); - } - - public String getPlatformGbID() { - return platformGbID; - } - - public void setPlatformGbID(String platformGbID) { - this.platformGbID = platformGbID; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java deleted file mode 100644 index 56bdeb58b..000000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.genersoft.iot.vmp.gb28181.event.platformNotRegister; - -import com.genersoft.iot.vmp.conf.DynamicTask; -import com.genersoft.iot.vmp.conf.SipConfig; -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; -import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.service.IMediaServerService; -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.stereotype.Component; - -import java.util.*; - -/** - * @description: 平台未注册事件,来源有二: - * 1、平台新添加 - * 2、平台心跳超时 - * @author: panll - * @date: 2020年11月24日 10:00 - */ -@Component -public class PlatformNotRegisterEventLister implements ApplicationListener { - - private final static Logger logger = LoggerFactory.getLogger(PlatformNotRegisterEventLister.class); - - @Autowired - private IVideoManagerStorage storager; - @Autowired - private IRedisCatchStorage redisCatchStorage; - @Autowired - private IMediaServerService mediaServerService; - - @Autowired - private SIPCommanderFroPlatform sipCommanderFroPlatform; - - @Autowired - private ZLMRTPServerFactory zlmrtpServerFactory; - - @Autowired - private SipConfig config; - - @Autowired - private DynamicTask dynamicTask; - - // @Autowired - // private RedisUtil redis; - - @Override - public void onApplicationEvent(PlatformNotRegisterEvent event) { - - logger.info("[ 平台未注册事件 ]平台国标ID:" + event.getPlatformGbID()); - - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(event.getPlatformGbID()); - if (parentPlatform == null) { - logger.info("[ 平台未注册事件 ] 平台已经删除!!! 平台国标ID:" + event.getPlatformGbID()); - return; - } - // 查询是否有推流, 如果有则都停止 - List sendRtpItems = redisCatchStorage.querySendRTPServer(event.getPlatformGbID()); - if (sendRtpItems != null && sendRtpItems.size() > 0) { - logger.info("[ 平台未注册事件 ] 停止[ {} ]的所有推流", event.getPlatformGbID()); - for (SendRtpItem sendRtpItem : sendRtpItems) { - redisCatchStorage.deleteSendRTPServer(event.getPlatformGbID(), sendRtpItem.getChannelId(), null, null); - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - Map param = new HashMap<>(); - param.put("vhost", "__defaultVhost__"); - param.put("app", sendRtpItem.getApp()); - param.put("stream", sendRtpItem.getStreamId()); - zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); - } - - } - String taskKey = "platform-not-register-" + parentPlatform.getServerGBId(); - SipSubscribe.Event okEvent = (responseEvent)->{ - dynamicTask.stop(taskKey); - }; - dynamicTask.startCron(taskKey, ()->{ - logger.info("[平台注册]再次向平台注册,平台国标ID:" + event.getPlatformGbID()); - sipCommanderFroPlatform.register(parentPlatform, null, okEvent); - }, config.getRegisterTimeInterval()* 1000); - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java index 79bb4cad1..734d60077 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java @@ -30,23 +30,10 @@ public class CatalogEventLister implements ApplicationListener { @Autowired private IVideoManagerStorage storager; - @Autowired - private IRedisCatchStorage redisCatchStorage; - @Autowired - private IMediaServerService mediaServerService; @Autowired private SIPCommanderFroPlatform sipCommanderFroPlatform; - @Autowired - private ZLMRTPServerFactory zlmrtpServerFactory; - - @Autowired - private SipConfig config; - - @Autowired - private UserSetting userSetting; - @Autowired private IGbStreamService gbStreamService; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java index 7edee4dd7..2ee103763 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java @@ -60,7 +60,6 @@ public class MobilePositionSubscribeHandlerTask implements ISubscribeTask { // TODO 暂时只处理视频流的回复,后续增加对国标设备的支持 List gbStreams = storager.queryGbStreamListInPlatform(platform.getServerGBId()); if (gbStreams.size() == 0) { - logger.info("发送订阅时发现平台已经没有关联的直播流:{}", platform.getServerGBId()); return; } for (DeviceChannel deviceChannel : gbStreams) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java index d000f5afb..351505f39 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java @@ -15,7 +15,7 @@ public interface ISIPCommanderForPlatform { * @return */ boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent); - boolean register(ParentPlatform parentPlatform, String callId, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain); + boolean register(ParentPlatform parentPlatform, String callId, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister); /** * 向上级平台注销 @@ -30,7 +30,7 @@ public interface ISIPCommanderForPlatform { * @param parentPlatform * @return callId(作为接受回复的判定) */ - String keepalive(ParentPlatform parentPlatform); + String keepalive(ParentPlatform parentPlatform,SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent); /** diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java index ad8043f15..a75e806cb 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo; +import com.genersoft.iot.vmp.gb28181.utils.HeaderUtils; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import gov.nist.javax.sip.message.MessageFactoryImpl; import org.springframework.beans.factory.annotation.Autowired; @@ -75,7 +76,7 @@ public class SIPRequestHeaderPlarformProvider { } - public Request createRegisterRequest(@NotNull ParentPlatform platform, long CSeq, String fromTag, String viaTag, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException { + public Request createRegisterRequest(@NotNull ParentPlatform platform, long CSeq, String fromTag, String viaTag, CallIdHeader callIdHeader, boolean isRegister) throws ParseException, InvalidArgumentException, PeerUnavailableException { Request request = null; String sipAddress = sipConfig.getIp() + ":" + sipConfig.getPort(); //请求行 @@ -109,18 +110,20 @@ public class SIPRequestHeaderPlarformProvider { .createSipURI(platform.getDeviceGBId(), sipAddress)); request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); - ExpiresHeader expires = sipFactory.createHeaderFactory().createExpiresHeader(Integer.parseInt(platform.getExpires())); + ExpiresHeader expires = sipFactory.createHeaderFactory().createExpiresHeader(isRegister ? platform.getExpires() : 0); request.addHeader(expires); + UserAgentHeader userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory); + request.addHeader(userAgentHeader); return request; } public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, String fromTag, String viaTag, - String callId, WWWAuthenticateHeader www , CallIdHeader callIdHeader) throws ParseException, PeerUnavailableException, InvalidArgumentException { + String callId, WWWAuthenticateHeader www , CallIdHeader callIdHeader, boolean isRegister) throws ParseException, PeerUnavailableException, InvalidArgumentException { - Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(), fromTag, viaTag, callIdHeader); + Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(), fromTag, viaTag, callIdHeader, isRegister); SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); if (www == null) { AuthorizationHeader authorizationHeader = sipFactory.createHeaderFactory().createAuthorizationHeader("Digest"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index b89fd8ea5..aee6d4e05 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -12,6 +12,7 @@ import javax.sip.message.Request; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; +import com.genersoft.iot.vmp.gb28181.utils.HeaderUtils; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import gov.nist.javax.sip.SipProviderImpl; import gov.nist.javax.sip.SipStackImpl; @@ -266,15 +267,7 @@ public class SIPRequestHeaderProvider { Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory() .createSipURI(sipConfig.getId(), sipConfig.getIp() + ":" + sipConfig.getPort())); infoRequest.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); - List agentParam = new ArrayList<>(); - agentParam.add("wvp-pro"); - // TODO 添加版本信息以及日期 - UserAgentHeader userAgentHeader = null; - try { - userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); - } catch (ParseException e) { - throw new RuntimeException(e); - } + UserAgentHeader userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory); infoRequest.addHeader(userAgentHeader); ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 3f6fa0ce9..e9d80466e 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; +import com.genersoft.iot.vmp.gb28181.utils.HeaderUtils; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.HookType; @@ -740,15 +741,7 @@ public class SIPCommander implements ISIPCommander { // 增加Contact header Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort())); byeRequest.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); - List agentParam = new ArrayList<>(); - agentParam.add("wvp-pro"); - // TODO 添加版本信息以及日期 - UserAgentHeader userAgentHeader = null; - try { - userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); - } catch (ParseException e) { - throw new RuntimeException(e); - } + UserAgentHeader userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory); byeRequest.addHeader(userAgentHeader); ClientTransaction clientTransaction = null; if("TCP".equals(protocol)) { @@ -1677,14 +1670,11 @@ public class SIPCommander implements ISIPCommander { clientTransaction = udpSipProvider.getNewClientTransaction(request); } if (request.getHeader(UserAgentHeader.NAME) == null) { - List agentParam = new ArrayList<>(); - agentParam.add("wvp-pro"); - // TODO 添加版本信息以及日期 UserAgentHeader userAgentHeader = null; try { - userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); + userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory); } catch (ParseException e) { - throw new RuntimeException(e); + logger.error("添加UserAgentHeader失败", e); } request.addHeader(userAgentHeader); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java index 1d8b60585..2d6d582ba 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java @@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider; +import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; @@ -75,28 +76,21 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @Override public boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { - return register(parentPlatform, null, null, errorEvent, okEvent, false); + return register(parentPlatform, null, null, errorEvent, okEvent, false, true); } @Override public boolean unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { - ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); - parentPlatform.setExpires("0"); - if (parentPlatformCatch != null) { - parentPlatformCatch.setParentPlatform(parentPlatform); - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); - } - return register(parentPlatform, null, null, errorEvent, okEvent, false); + return register(parentPlatform, null, null, errorEvent, okEvent, false, false); } @Override public boolean register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable WWWAuthenticateHeader www, - SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain) { + SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) { try { Request request; String tm = Long.toString(System.currentTimeMillis()); if (!registerAgain ) { - // //callid CallIdHeader callIdHeader = null; if(parentPlatform.getTransport().equals("TCP")) { callIdHeader = tcpSipProvider.getNewCallId(); @@ -107,10 +101,10 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(), "FromRegister" + tm, - "z9hG4bK-" + UUID.randomUUID().toString().replace("-", ""), callIdHeader); + "z9hG4bK-" + UUID.randomUUID().toString().replace("-", ""), callIdHeader, isRegister); // 将 callid 写入缓存, 等注册成功可以更新状态 String callIdFromHeader = callIdHeader.getCallId(); - redisCatchStorage.updatePlatformRegisterInfo(callIdFromHeader, parentPlatform.getServerGBId()); + redisCatchStorage.updatePlatformRegisterInfo(callIdFromHeader, PlatformRegisterInfo.getInstance(parentPlatform.getServerGBId(), isRegister)); sipSubscribe.addErrorSubscribe(callIdHeader.getCallId(), (event)->{ if (event != null) { @@ -127,7 +121,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { }else { CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() : udpSipProvider.getNewCallId(); - request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, "FromRegister" + tm, null, callId, www, callIdHeader); + request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, "FromRegister" + tm, null, callId, www, callIdHeader, isRegister); } transmitRequest(parentPlatform, request, null, okEvent); @@ -145,7 +139,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { } @Override - public String keepalive(ParentPlatform parentPlatform) { + public String keepalive(ParentPlatform parentPlatform,SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { String callId = null; try { String characterSet = parentPlatform.getCharacterSet(); @@ -168,7 +162,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { UUID.randomUUID().toString().replace("-", ""), null, callIdHeader); - transmitRequest(parentPlatform, request); + transmitRequest(parentPlatform, request, errorEvent, okEvent); callId = callIdHeader.getCallId(); } catch (ParseException | InvalidArgumentException | SipException e) { e.printStackTrace(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java index 8f3ba0a23..8977d8a70 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java @@ -59,6 +59,9 @@ public abstract class SIPRequestProcessorParent { public ServerTransaction getServerTransaction(RequestEvent evt) { Request request = evt.getRequest(); ServerTransaction serverTransaction = evt.getServerTransaction(); + if (serverTransaction != null) { + System.out.println(serverTransaction.getState().toString()); + } // 判断TCP还是UDP boolean isTcp = false; ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); @@ -86,6 +89,8 @@ public abstract class SIPRequestProcessorParent { logger.error(e.getMessage()); } catch (TransactionUnavailableException e) { logger.error(e.getMessage()); + }finally { + } } return serverTransaction; @@ -182,6 +187,10 @@ public abstract class SIPRequestProcessorParent { sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost()+":"+sipURI.getPort() )); response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); + ServerTransaction serverTransaction = getServerTransaction(evt); + if (serverTransaction == null) { + + } getServerTransaction(evt).sendResponse(response); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java index 04a11b930..1a396353b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java +++ b/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; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract; +import com.genersoft.iot.vmp.gb28181.utils.HeaderUtils; import gov.nist.javax.sip.ResponseEventExt; import gov.nist.javax.sip.message.SIPResponse; import gov.nist.javax.sip.stack.SIPDialog; @@ -103,15 +104,7 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract { } requestURI.setPort(event.getRemotePort()); reqAck.setRequestURI(requestURI); - List agentParam = new ArrayList<>(); - agentParam.add("wvp-pro"); - // TODO 添加版本信息以及日期 - UserAgentHeader userAgentHeader = null; - try { - userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); - } catch (ParseException e) { - throw new RuntimeException(e); - } + UserAgentHeader userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory); reqAck.addHeader(userAgentHeader); Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort())); reqAck.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java index a48dd203b..a5cddaedd 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java +++ b/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; import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract; +import com.genersoft.iot.vmp.service.IPlatformService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; +import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -44,6 +46,9 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { @Autowired private SubscribeHolder subscribeHolder; + @Autowired + private IPlatformService platformService; + @Override public void afterPropertiesSet() throws Exception { // 添加消息处理的订阅 @@ -60,48 +65,39 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { Response response = evt.getResponse(); CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME); String callId = callIdHeader.getCallId(); - - String platformGBId = redisCatchStorage.queryPlatformRegisterInfo(callId); - if (platformGBId == null) { - logger.info(String.format("未找到callId: %s 的注册/注销平台id", callId )); + PlatformRegisterInfo platformRegisterInfo = redisCatchStorage.queryPlatformRegisterInfo(callId); + if (platformRegisterInfo == null) { + logger.info(String.format("[国标级联]未找到callId: %s 的注册/注销平台id", callId )); return; } - ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(platformGBId); + ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(platformRegisterInfo.getPlatformId()); if (parentPlatformCatch == null) { - logger.warn(String.format("[收到注册/注销%S请求]平台:%s,但是平台缓存信息未查询到!!!", response.getStatusCode(),platformGBId)); + logger.warn(String.format("[国标级联]收到注册/注销%S请求,平台:%s,但是平台缓存信息未查询到!!!", response.getStatusCode(),platformRegisterInfo.getPlatformId())); return; } - String action = parentPlatformCatch.getParentPlatform().getExpires().equals("0") ? "注销" : "注册"; - logger.info(String.format("[%s %S响应]%s ", action, response.getStatusCode(), platformGBId )); + + String action = platformRegisterInfo.isRegister() ? "注册" : "注销"; + logger.info(String.format("[国标级联]%s %S响应,%s ", action, response.getStatusCode(), platformRegisterInfo.getPlatformId() )); ParentPlatform parentPlatform = parentPlatformCatch.getParentPlatform(); if (parentPlatform == null) { - logger.warn(String.format("收到 %s %s的%S请求, 但是平台信息未查询到!!!", platformGBId, action, response.getStatusCode())); + logger.warn(String.format("[国标级联]收到 %s %s的%S请求, 但是平台信息未查询到!!!", platformRegisterInfo.getPlatformId(), action, response.getStatusCode())); return; } - if (response.getStatusCode() == 401) { + if (response.getStatusCode() == Response.UNAUTHORIZED) { WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME); - sipCommanderForPlatform.register(parentPlatform, callId, www, null, null, true); - }else if (response.getStatusCode() == 200){ - // 注册/注销成功 - logger.info(String.format("%s %s成功", platformGBId, action)); + sipCommanderForPlatform.register(parentPlatform, callId, www, null, null, true, platformRegisterInfo.isRegister()); + }else if (response.getStatusCode() == Response.OK){ + + if (platformRegisterInfo.isRegister()) { + platformService.online(parentPlatform); + }else { + platformService.offline(parentPlatform); + } + + // 注册/注销成功移除缓存的信息 redisCatchStorage.delPlatformRegisterInfo(callId); - redisCatchStorage.delPlatformCatchInfo(platformGBId); - // 取回Expires设置,避免注销过程中被置为0 - ParentPlatform parentPlatformTmp = storager.queryParentPlatByServerGBId(platformGBId); - if (parentPlatformTmp != null) { - parentPlatformTmp.setStatus("注册".equals(action)); - redisCatchStorage.updatePlatformRegister(parentPlatformTmp); - redisCatchStorage.updatePlatformKeepalive(parentPlatformTmp); - parentPlatformCatch.setParentPlatform(parentPlatformTmp); - } - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); - storager.updateParentPlatformStatus(platformGBId, "注册".equals(action)); - if ("注销".equals(action)) { - subscribeHolder.removeCatalogSubscribe(platformGBId); - subscribeHolder.removeMobilePositionSubscribe(platformGBId); - } } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/HeaderUtils.java b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/HeaderUtils.java new file mode 100644 index 000000000..86112672a --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/HeaderUtils.java @@ -0,0 +1,22 @@ +package com.genersoft.iot.vmp.gb28181.utils; + +import javax.sip.PeerUnavailableException; +import javax.sip.SipFactory; +import javax.sip.header.UserAgentHeader; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +/** + * 生成header的工具类 + * @author lin + */ +public class HeaderUtils { + + public static UserAgentHeader createUserAgentHeader(SipFactory sipFactory) throws PeerUnavailableException, ParseException { + List agentParam = new ArrayList<>(); + agentParam.add("WVP PRO"); + // TODO 添加版本信息以及日期 + return sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java index 36ae1b819..2d117543f 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java @@ -50,7 +50,7 @@ public class AssistRESTfulUtils { if (mediaServerItem == null) { return null; } - if (ObjectUtils.isEmpty(mediaServerItem.getRecordAssistPort())) { + if (mediaServerItem.getRecordAssistPort() > 0) { logger.warn("未启用Assist服务"); return null; } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index e7c32ef8c..7afe0fd1b 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -18,8 +18,11 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.PostMapping; @@ -92,6 +95,10 @@ public class ZLMHttpHookListener { @Autowired private AssistRESTfulUtils assistRESTfulUtils; + @Qualifier("taskExecutor") + @Autowired + private ThreadPoolTaskExecutor taskExecutor; + /** * 服务器定时上报时间,上报间隔可配置,默认10s上报一次 * @@ -238,9 +245,12 @@ public class ZLMHttpHookListener { // 鉴权通过 redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo); // 通知assist新的callId - if (mediaInfo != null && mediaInfo.getRecordAssistPort() > 0) { - assistRESTfulUtils.addStreamCallInfo(mediaInfo, param.getApp(), param.getStream(), callId, null); - } + taskExecutor.execute(()->{ + if (mediaInfo != null && mediaInfo.getRecordAssistPort() > 0) { + assistRESTfulUtils.addStreamCallInfo(mediaInfo, param.getApp(), param.getStream(), callId, null); + } + }); + }else { zlmMediaListManager.sendStreamEvent(param.getApp(),param.getStream(), param.getMediaServerId()); } @@ -416,18 +426,23 @@ public class ZLMHttpHookListener { String schema = item.getSchema(); List tracks = item.getTracks(); boolean regist = item.isRegist(); - if (regist) { - StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); - if (streamAuthorityInfo == null) { - streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(item); + if (item.getOriginType() == OriginType.RTMP_PUSH.ordinal() + || item.getOriginType() == OriginType.RTSP_PUSH.ordinal() + || item.getOriginType() == OriginType.RTC_PUSH.ordinal()) { + if (regist) { + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); + if (streamAuthorityInfo == null) { + streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(item); + }else { + streamAuthorityInfo.setOriginType(item.getOriginType()); + streamAuthorityInfo.setOriginTypeStr(item.getOriginTypeStr()); + } + redisCatchStorage.updateStreamAuthorityInfo(app, stream, streamAuthorityInfo); }else { - streamAuthorityInfo.setOriginType(item.getOriginType()); - streamAuthorityInfo.setOriginTypeStr(item.getOriginTypeStr()); + redisCatchStorage.removeStreamAuthorityInfo(app, stream); } - redisCatchStorage.updateStreamAuthorityInfo(app, stream, streamAuthorityInfo); - }else { - redisCatchStorage.removeStreamAuthorityInfo(app, stream); } + if ("rtsp".equals(schema)){ logger.info("on_stream_changed:注册->{}, app->{}, stream->{}", regist, app, stream); if (regist) { diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java new file mode 100644 index 000000000..b5f3c5b7c --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java @@ -0,0 +1,45 @@ +package com.genersoft.iot.vmp.service; + +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; +import com.github.pagehelper.PageInfo; + +/** + * 国标平台的业务类 + * @author lin + */ +public interface IPlatformService { + + ParentPlatform queryPlatformByServerGBId(String platformGbId); + + /** + * 分页获取上级平台 + * @param page + * @param count + * @return + */ + PageInfo queryParentPlatformList(int page, int count); + + /** + * 添加级联平台 + * @param parentPlatform 级联平台 + */ + boolean add(ParentPlatform parentPlatform); + + /** + * 平台上线 + * @param parentPlatform 平台信息 + */ + void online(ParentPlatform parentPlatform); + + /** + * 平台离线 + * @param parentPlatform 平台信息 + */ + void offline(ParentPlatform parentPlatform); + + /** + * 向上级平台发起注册 + * @param parentPlatform + */ + void login(ParentPlatform parentPlatform); +} diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java index d923755a4..37aeca0d6 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java @@ -513,10 +513,7 @@ public class MediaServerServiceImpl implements IMediaServerService { mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); String protocol = sslEnabled ? "https" : "http"; String hookPrex = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort); - String recordHookPrex = null; - if (mediaServerItem.getRecordAssistPort() != 0) { - recordHookPrex = String.format("http://127.0.0.1:%s/api/record", mediaServerItem.getRecordAssistPort()); - } + Map param = new HashMap<>(); param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline param.put("ffmpeg.cmd","%s -fflags nobuffer -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s"); @@ -525,7 +522,6 @@ public class MediaServerServiceImpl implements IMediaServerService { param.put("hook.on_play",String.format("%s/on_play", hookPrex)); param.put("hook.on_http_access",String.format("%s/on_http_access", hookPrex)); param.put("hook.on_publish", String.format("%s/on_publish", hookPrex)); - param.put("hook.on_record_mp4",recordHookPrex != null? String.format("%s/on_record_mp4", recordHookPrex): ""); param.put("hook.on_record_ts",String.format("%s/on_record_ts", hookPrex)); param.put("hook.on_rtsp_auth",String.format("%s/on_rtsp_auth", hookPrex)); param.put("hook.on_rtsp_realm",String.format("%s/on_rtsp_realm", hookPrex)); @@ -535,6 +531,11 @@ public class MediaServerServiceImpl implements IMediaServerService { param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrex)); param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex)); param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrex)); + if (mediaServerItem.getRecordAssistPort() > 0) { + param.put("hook.on_record_mp4",String.format("http://127.0.0.1:%s/api/record/on_record_mp4", mediaServerItem.getRecordAssistPort())); + }else { + param.put("hook.on_record_mp4",""); + } param.put("hook.timeoutSec","20"); param.put("general.streamNoneReaderDelayMS",mediaServerItem.getStreamNoneReaderDelayMS()==-1?"3600000":mediaServerItem.getStreamNoneReaderDelayMS() ); // 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 @@ -544,7 +545,7 @@ public class MediaServerServiceImpl implements IMediaServerService { param.put("general.continue_push_ms", "3000" ); // 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流, // 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项 - param.put("general.wait_track_ready_ms", "3000" ); +// param.put("general.wait_track_ready_ms", "3000" ); if (mediaServerItem.isRtpEnable() && !ObjectUtils.isEmpty(mediaServerItem.getRtpPortRange())) { param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-")); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java new file mode 100644 index 000000000..3a5d19a6b --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -0,0 +1,232 @@ +package com.genersoft.iot.vmp.service.impl; + +import com.genersoft.iot.vmp.conf.DynamicTask; +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; +import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; +import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.service.IPlatformService; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; +import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.sip.TimeoutEvent; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author lin + */ +@Service +public class PlatformServiceImpl implements IPlatformService { + + private final static String REGISTER_KEY_PREFIX = "platform_register_"; + private final static String KEEPALIVE_KEY_PREFIX = "platform_keepalive_"; + + private final static Logger logger = LoggerFactory.getLogger(PlatformServiceImpl.class); + + @Autowired + private ParentPlatformMapper platformMapper; + + @Autowired + private IRedisCatchStorage redisCatchStorage; + + @Autowired + private IMediaServerService mediaServerService; + + @Autowired + private SIPCommanderFroPlatform commanderForPlatform; + + @Autowired + private DynamicTask dynamicTask; + + @Autowired + private ZLMRTPServerFactory zlmrtpServerFactory; + + @Autowired + private SubscribeHolder subscribeHolder; + + + + @Override + public ParentPlatform queryPlatformByServerGBId(String platformGbId) { + return platformMapper.getParentPlatByServerGBId(platformGbId); + } + + @Override + public PageInfo queryParentPlatformList(int page, int count) { + PageHelper.startPage(page, count); + List all = platformMapper.getParentPlatformList(); + return new PageInfo<>(all); + } + + @Override + public boolean add(ParentPlatform parentPlatform) { + + if (parentPlatform.getCatalogGroup() == 0) { + // 每次发送目录的数量默认为1 + parentPlatform.setCatalogGroup(1); + } + if (parentPlatform.getAdministrativeDivision() == null) { + // 行政区划默认去编号的前6位 + parentPlatform.setAdministrativeDivision(parentPlatform.getServerGBId().substring(0,6)); + } + parentPlatform.setCatalogId(parentPlatform.getDeviceGBId()); + int result = platformMapper.addParentPlatform(parentPlatform); + // 添加缓存 + ParentPlatformCatch parentPlatformCatch = new ParentPlatformCatch(); + parentPlatformCatch.setParentPlatform(parentPlatform); + parentPlatformCatch.setId(parentPlatform.getServerGBId()); + parentPlatformCatch.setParentPlatform(parentPlatform); + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); + if (parentPlatform.isEnable()) { + // 保存时启用就发送注册 + // 注册成功时由程序直接调用了online方法 + commanderForPlatform.register(parentPlatform, eventResult -> { + logger.info("[国标级联] {},添加向上级注册失败,请确定上级平台可用时重新保存", parentPlatform.getServerGBId()); + }, null); + } + return result > 0; + } + + @Override + public void online(ParentPlatform parentPlatform) { + logger.info("[国标级联]:{}, 平台上线", parentPlatform.getServerGBId()); + platformMapper.updateParentPlatformStatus(parentPlatform.getServerGBId(), true); + ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); + if (parentPlatformCatch != null) { + parentPlatformCatch.getParentPlatform().setStatus(true); + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); + }else { + parentPlatformCatch = new ParentPlatformCatch(); + parentPlatformCatch.setParentPlatform(parentPlatform); + parentPlatformCatch.setId(parentPlatform.getServerGBId()); + parentPlatform.setStatus(true); + parentPlatformCatch.setParentPlatform(parentPlatform); + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); + } + + final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId(); + if (dynamicTask.contains(registerTaskKey)) { + dynamicTask.stop(registerTaskKey); + } + // 添加注册任务 + dynamicTask.startDelay(registerTaskKey, + // 注册失败(注册成功时由程序直接调用了online方法) + ()->commanderForPlatform.register(parentPlatform, eventResult -> offline(parentPlatform),null), + parentPlatform.getExpires()*1000); + + final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId(); + if (!dynamicTask.contains(keepaliveTaskKey)) { + // 添加心跳任务 + dynamicTask.startCron(keepaliveTaskKey, + ()-> commanderForPlatform.keepalive(parentPlatform, eventResult -> { + // 心跳失败 + if (eventResult.type == SipSubscribe.EventResultType.timeout) { + // 心跳超时 + ParentPlatformCatch platformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); + // 此时是第三次心跳超时, 平台离线 + if (platformCatch.getKeepAliveReply() == 2) { + // 设置平台离线,并重新注册 + offline(parentPlatform); + logger.info("[国标级联] {},三次心跳超时后再次发起注册", parentPlatform.getServerGBId()); + commanderForPlatform.register(parentPlatform, eventResult1 -> { + logger.info("[国标级联] {},三次心跳超时后再次发起注册仍然失败,开始定时发起注册,间隔为1分钟", parentPlatform.getServerGBId()); + // 添加注册任务 + dynamicTask.startCron(registerTaskKey, + // 注册失败(注册成功时由程序直接调用了online方法) + ()->logger.info("[国标级联] {},平台离线后持续发起注册,失败", parentPlatform.getServerGBId()), + 60*1000); + }, null); + } + + }else { + logger.warn("[国标级联]发送心跳收到错误,code: {}, msg: {}", eventResult.statusCode, eventResult.msg); + } + + }, eventResult -> { + // 心跳成功 + // 清空之前的心跳超时计数 + ParentPlatformCatch platformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); + if (platformCatch.getKeepAliveReply() > 0) { + platformCatch.setKeepAliveReply(0); + redisCatchStorage.updatePlatformCatchInfo(platformCatch); + } + }), + parentPlatform.getExpires()*1000); + } + } + + @Override + public void offline(ParentPlatform parentPlatform) { + logger.info("[平台离线]:{}", parentPlatform.getServerGBId()); + ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); + parentPlatformCatch.setKeepAliveReply(0); + parentPlatformCatch.setRegisterAliveReply(0); + ParentPlatform parentPlatformInCatch = parentPlatformCatch.getParentPlatform(); + parentPlatformInCatch.setStatus(false); + parentPlatformCatch.setParentPlatform(parentPlatformInCatch); + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); + platformMapper.updateParentPlatformStatus(parentPlatform.getServerGBId(), false); + + // 停止所有推流 + logger.info("[平台离线] {}, 停止所有推流", parentPlatform.getServerGBId()); + stopAllPush(parentPlatform.getServerGBId()); + // 清除注册定时 + logger.info("[平台离线] {}, 停止定时注册任务", parentPlatform.getServerGBId()); + final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId(); + if (dynamicTask.contains(registerTaskKey)) { + dynamicTask.stop(registerTaskKey); + } + // 清除心跳定时 + logger.info("[平台离线] {}, 停止定时发送心跳任务", parentPlatform.getServerGBId()); + final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId(); + if (dynamicTask.contains(keepaliveTaskKey)) { + // 添加心跳任务 + dynamicTask.stop(keepaliveTaskKey); + } + // 停止目录订阅回复 + logger.info("[平台离线] {}, 停止订阅回复", parentPlatform.getServerGBId()); + subscribeHolder.removeAllSubscribe(parentPlatform.getServerGBId()); + } + + private void stopAllPush(String platformId) { + List sendRtpItems = redisCatchStorage.querySendRTPServer(platformId); + if (sendRtpItems != null && sendRtpItems.size() > 0) { + for (SendRtpItem sendRtpItem : sendRtpItems) { + redisCatchStorage.deleteSendRTPServer(platformId, sendRtpItem.getChannelId(), null, null); + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + Map param = new HashMap<>(3); + param.put("vhost", "__defaultVhost__"); + param.put("app", sendRtpItem.getApp()); + param.put("stream", sendRtpItem.getStreamId()); + zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); + } + + } + } + + @Override + public void login(ParentPlatform parentPlatform) { + final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId(); + commanderForPlatform.register(parentPlatform, eventResult1 -> { + logger.info("[国标级联] {},开始定时发起注册,间隔为1分钟", parentPlatform.getServerGBId()); + // 添加注册任务 + dynamicTask.startCron(registerTaskKey, + // 注册失败(注册成功时由程序直接调用了online方法) + ()->logger.info("[国标级联] {},平台离线后持续发起注册,失败", parentPlatform.getServerGBId()), + 60*1000); + }, null); + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index e00eb5571..dc62b07f1 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -575,7 +575,7 @@ public class PlayServiceImpl implements IPlayService { logger.warn("查询录像信息时发现节点已离线"); return null; } - if (mediaServerItem.getRecordAssistPort() != 0) { + if (mediaServerItem.getRecordAssistPort() > 0) { JSONObject jsonObject = assistRESTfulUtils.fileDuration(mediaServerItem, streamInfo.getApp(), streamInfo.getStream(), null); if (jsonObject != null && jsonObject.getInteger("code") == 0) { long duration = jsonObject.getLong("data"); @@ -691,7 +691,7 @@ public class PlayServiceImpl implements IPlayService { // for (SendRtpItem sendRtpItem : sendRtpItems) { // if (sendRtpItem.getMediaServerId().equals(mediaServerId)) { // if (mediaListMap.get(sendRtpItem.getStreamId()) == null) { -// ParentPlatform platform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); +// ParentPlatform platform = storager.queryPlatformByServerGBId(sendRtpItem.getPlatformId()); // sipCommanderFroPlatform.streamByeCmd(platform, sendRtpItem.getCallId()); // } // } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java index b3bb89ccd..1f467e4eb 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; +import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; import java.util.List; import java.util.Map; @@ -61,17 +62,13 @@ public interface IRedisCatchStorage { void delPlatformCatchInfo(String platformGbId); - void updatePlatformKeepalive(ParentPlatform parentPlatform); - void delPlatformKeepalive(String platformGbId); - void updatePlatformRegister(ParentPlatform parentPlatform); - void delPlatformRegister(String platformGbId); - void updatePlatformRegisterInfo(String callId, String platformGbId); + void updatePlatformRegisterInfo(String callId, PlatformRegisterInfo platformRegisterInfo); - String queryPlatformRegisterInfo(String callId); + PlatformRegisterInfo queryPlatformRegisterInfo(String callId); void delPlatformRegisterInfo(String callId); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java index b2c1e1b97..b65cc6817 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java @@ -170,15 +170,6 @@ public interface IVideoManagerStorage { */ boolean deleteParentPlatform(ParentPlatform parentPlatform); - - /** - * 分页获取上级平台 - * @param page - * @param count - * @return - */ - PageInfo queryParentPlatformList(int page, int count); - /** * 获取所有已启用的平台 * @return diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/dto/PlatformRegisterInfo.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/dto/PlatformRegisterInfo.java new file mode 100644 index 000000000..16f663631 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/dto/PlatformRegisterInfo.java @@ -0,0 +1,41 @@ +package com.genersoft.iot.vmp.storager.dao.dto; + +/** + * 平台发送注册/注销消息时缓存此消息 + * @author lin + */ +public class PlatformRegisterInfo { + + /** + * 平台Id + */ + private String platformId; + + /** + * 是否时注册,false为注销 + */ + private boolean register; + + public static PlatformRegisterInfo getInstance(String platformId, boolean register) { + PlatformRegisterInfo platformRegisterInfo = new PlatformRegisterInfo(); + platformRegisterInfo.setPlatformId(platformId); + platformRegisterInfo.setRegister(register); + return platformRegisterInfo; + } + + public String getPlatformId() { + return platformId; + } + + public void setPlatformId(String platformId) { + this.platformId = platformId; + } + + public boolean isRegister() { + return register; + } + + public void setRegister(boolean register) { + this.register = register; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java index 14a369cce..ecefe7373 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -16,6 +16,7 @@ import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; +import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import org.slf4j.Logger; @@ -290,18 +291,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { RedisUtil.set(key, parentPlatformCatch); } - @Override - public void updatePlatformKeepalive(ParentPlatform parentPlatform) { - String key = VideoManagerConstants.PLATFORM_KEEPALIVE_PREFIX + userSetting.getServerId() + "_" + parentPlatform.getServerGBId(); - RedisUtil.set(key, "", Integer.parseInt(parentPlatform.getKeepTimeout())); - } - - @Override - public void updatePlatformRegister(ParentPlatform parentPlatform) { - String key = VideoManagerConstants.PLATFORM_REGISTER_PREFIX + userSetting.getServerId() + "_" + parentPlatform.getServerGBId(); - RedisUtil.set(key, "", Integer.parseInt(parentPlatform.getExpires())); - } - @Override public ParentPlatformCatch queryPlatformCatchInfo(String platformGbId) { return (ParentPlatformCatch)RedisUtil.get(VideoManagerConstants.PLATFORM_CATCH_PREFIX + userSetting.getServerId() + "_" + platformGbId); @@ -324,15 +313,15 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @Override - public void updatePlatformRegisterInfo(String callId, String platformGbId) { + public void updatePlatformRegisterInfo(String callId, PlatformRegisterInfo platformRegisterInfo) { String key = VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_" + callId; - RedisUtil.set(key, platformGbId, 30); + RedisUtil.set(key, platformRegisterInfo, 30); } @Override - public String queryPlatformRegisterInfo(String callId) { - return (String)RedisUtil.get(VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_" + callId); + public PlatformRegisterInfo queryPlatformRegisterInfo(String callId) { + return (PlatformRegisterInfo)RedisUtil.get(VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_" + callId); } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java index 0ec9dbc93..e8e0e02f7 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java @@ -457,13 +457,6 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { return result > 0; } - @Override - public PageInfo queryParentPlatformList(int page, int count) { - PageHelper.startPage(page, count); - List all = platformMapper.getParentPlatformList(); - return new PageInfo<>(all); - } - @Override public ParentPlatform queryParentPlatByServerGBId(String platformGbId) { return platformMapper.getParentPlatByServerGBId(platformGbId); diff --git a/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java b/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java index 0034c398a..749dddd27 100644 --- a/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java @@ -5,6 +5,7 @@ import java.util.concurrent.TimeUnit; import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.utils.SpringBeanFactory; +import gov.nist.javax.sip.stack.UDPMessageChannel; import org.springframework.data.redis.core.*; import org.springframework.util.CollectionUtils; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java index 2a403301e..bf4218944 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java @@ -9,14 +9,13 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog; import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; -import com.genersoft.iot.vmp.gb28181.bean.TreeType; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.service.IPlatformChannelService; +import com.genersoft.iot.vmp.service.IPlatformService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.UpdateChannelParam; import com.github.pagehelper.PageInfo; @@ -26,10 +25,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import com.genersoft.iot.vmp.conf.SipConfig; @@ -70,6 +66,9 @@ public class PlatformController { @Autowired private DynamicTask dynamicTask; + @Autowired + private IPlatformService platformService; + /** * 获取国标服务的配置 * @@ -95,8 +94,7 @@ public class PlatformController { @Parameter(name = "id", description = "平台国标编号", required = true) @GetMapping("/info/{id}") public ParentPlatform getPlatform(@PathVariable String id) { - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(id); - WVPResult wvpResult = new WVPResult<>(); + ParentPlatform parentPlatform = platformService.queryPlatformByServerGBId(id); if (parentPlatform != null) { return parentPlatform; } else { @@ -117,7 +115,7 @@ public class PlatformController { @Parameter(name = "count", description = "每页条数", required = true) public PageInfo platforms(@PathVariable int page, @PathVariable int count) { - PageInfo parentPlatformPageInfo = storager.queryParentPlatformList(page, count); + PageInfo parentPlatformPageInfo = platformService.queryParentPlatformList(page, count); if (parentPlatformPageInfo.getList().size() > 0) { for (ParentPlatform platform : parentPlatformPageInfo.getList()) { platform.setMobilePositionSubscribe(subscribeHolder.getMobilePositionSubscribe(platform.getServerGBId()) != null); @@ -136,7 +134,7 @@ public class PlatformController { @Operation(summary = "添加上级平台信息") @PostMapping("/add") @ResponseBody - public String addPlatform(@RequestBody ParentPlatform parentPlatform) { + public void addPlatform(@RequestBody ParentPlatform parentPlatform) { if (logger.isDebugEnabled()) { logger.debug("保存上级平台信息API调用"); @@ -158,33 +156,16 @@ public class PlatformController { throw new ControllerException(ErrorCode.ERROR400.getCode(), "error severPort"); } + ParentPlatform parentPlatformOld = storager.queryParentPlatByServerGBId(parentPlatform.getServerGBId()); if (parentPlatformOld != null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台 " + parentPlatform.getServerGBId() + " 已存在"); } parentPlatform.setCreateTime(DateUtil.getNow()); parentPlatform.setUpdateTime(DateUtil.getNow()); - boolean updateResult = storager.updateParentPlatform(parentPlatform); + boolean updateResult = platformService.add(parentPlatform); - if (updateResult) { - // 保存时启用就发送注册 - if (parentPlatform.isEnable()) { - if (parentPlatformOld != null && parentPlatformOld.isStatus()) { - commanderForPlatform.unregister(parentPlatformOld, null, eventResult -> { - // 只要保存就发送注册 - commanderForPlatform.register(parentPlatform, null, null); - }); - } else { - // 只要保存就发送注册 - commanderForPlatform.register(parentPlatform, null, null); - } - - } else if (parentPlatformOld != null && parentPlatformOld.isEnable()) { - // 关闭启用时注销 - commanderForPlatform.unregister(parentPlatform, null, null); - } - return null; - } else { + if (!updateResult) { throw new ControllerException(ErrorCode.ERROR100.getCode(),"写入数据库失败"); } } diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml index 6679c0d8f..222c07650 100644 --- a/src/main/resources/all-application.yml +++ b/src/main/resources/all-application.yml @@ -179,8 +179,6 @@ user-settings: platform-play-timeout: 60000 # 是否开启接口鉴权 interface-authentication: true - # 自动配置redis 可以过期事件 - redis-config: true # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 interface-authentication-excludes: - /api/v1/** diff --git a/web_src/src/components/dialog/MediaServerEdit.vue b/web_src/src/components/dialog/MediaServerEdit.vue index 7206bacee..1754461d2 100644 --- a/web_src/src/components/dialog/MediaServerEdit.vue +++ b/web_src/src/components/dialog/MediaServerEdit.vue @@ -357,7 +357,7 @@ export default { var result = false; var that = this; await that.$axios({ - method: 'post', + method: 'get', url:`/api/platform/exit/${deviceGbId}` }).then(function (res) { result = res.data; diff --git a/web_src/src/components/dialog/StreamProxyEdit.vue b/web_src/src/components/dialog/StreamProxyEdit.vue index ac209db6c..936bc53d1 100644 --- a/web_src/src/components/dialog/StreamProxyEdit.vue +++ b/web_src/src/components/dialog/StreamProxyEdit.vue @@ -263,7 +263,7 @@ export default { var result = false; var that = this; await that.$axios({ - method: 'post', + method: 'get', url:`/api/platform/exit/${deviceGbId}` }).then(function (res) { result = res.data; diff --git a/web_src/src/components/dialog/platformEdit.vue b/web_src/src/components/dialog/platformEdit.vue index 633160b31..ef28b4c72 100644 --- a/web_src/src/components/dialog/platformEdit.vue +++ b/web_src/src/components/dialog/platformEdit.vue @@ -327,7 +327,7 @@ export default { var result = false; var that = this; await that.$axios({ - method: 'post', + method: 'get', url:`/api/platform/exit/${deviceGbId}`}) .then(function (res) { if (res.data.code === 0) { diff --git a/web_src/src/components/dialog/pushStreamEdit.vue b/web_src/src/components/dialog/pushStreamEdit.vue index 8c827a3d3..de4e7bcc8 100644 --- a/web_src/src/components/dialog/pushStreamEdit.vue +++ b/web_src/src/components/dialog/pushStreamEdit.vue @@ -158,7 +158,7 @@ export default { var result = false; var that = this; await that.$axios({ - method:"post", + method:"get", url:`/api/platform/exit/${deviceGbId}` }).then(function (res) { result = res.data; From 275b272160679beaf19147764b73c1c439880593 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Wed, 31 Aug 2022 13:09:45 +0800 Subject: [PATCH 8/9] =?UTF-8?q?hook=E8=AE=A2=E9=98=85=E6=9B=BE=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=BF=87=E6=9C=9F=E6=B8=85=E9=99=A4=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E9=98=B2=E6=AD=A2=E5=86=85=E5=AD=98=E6=BA=A2=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gb28181/transmit/cmd/ISIPCommander.java | 4 +- .../transmit/cmd/impl/SIPCommander.java | 11 +--- .../request/impl/AckRequestProcessor.java | 8 +-- .../request/impl/InviteRequestProcessor.java | 5 +- .../vmp/media/zlm/ZLMHttpHookListener.java | 20 +++---- .../vmp/media/zlm/ZLMMediaListManager.java | 8 +-- .../iot/vmp/media/zlm/ZLMRunner.java | 7 +-- ...bscribe.java => ZlmHttpHookSubscribe.java} | 55 ++++++++++++++----- .../iot/vmp/service/IPlayService.java | 7 +-- .../iot/vmp/service/impl/PlayServiceImpl.java | 10 ++-- .../service/impl/RedisGbPlayMsgListener.java | 8 +-- .../vmp/vmanager/server/ServerController.java | 7 +-- 12 files changed, 73 insertions(+), 77 deletions(-) rename src/main/java/com/genersoft/iot/vmp/media/zlm/{ZLMHttpHookSubscribe.java => ZlmHttpHookSubscribe.java} (69%) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java index 4c147d0c3..068d2dfc9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -93,7 +93,7 @@ public interface ISIPCommander { * @param device 视频设备 * @param channelId 预览通道 */ - void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent); + void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent); /** * 请求回放视频流 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index e9d80466e..5ceaa2676 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -13,10 +13,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; import com.genersoft.iot.vmp.gb28181.utils.HeaderUtils; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; -import com.genersoft.iot.vmp.media.zlm.dto.HookType; import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -34,19 +33,15 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import javax.sip.*; import javax.sip.address.Address; import javax.sip.address.SipURI; -import javax.sip.address.URI; import javax.sip.header.*; import javax.sip.message.Request; import java.lang.reflect.Field; import java.text.ParseException; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; /** * @description:设备能力接口,用于定义设备的控制、查询能力 @@ -89,7 +84,7 @@ public class SIPCommander implements ISIPCommander { private UserSetting userSetting; @Autowired - private ZLMHttpHookSubscribe subscribe; + private ZlmHttpHookSubscribe subscribe; @Autowired private SipSubscribe sipSubscribe; @@ -352,7 +347,7 @@ public class SIPCommander implements ISIPCommander { */ @Override public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, - ZLMHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) { + ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) { String stream = ssrcInfo.getStream(); try { if (device == null) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java index 78b8e62c4..c46f181d2 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java @@ -1,10 +1,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; -import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; -import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.DynamicTask; -import com.genersoft.iot.vmp.gb28181.bean.InviteStreamType; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; @@ -12,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; @@ -21,7 +18,6 @@ import com.genersoft.iot.vmp.service.impl.RedisGbPlayMsgListener; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.utils.SerializeUtils; -import org.ehcache.shadow.org.terracotta.offheapstore.storage.IntegerStorageEngine; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; @@ -69,7 +65,7 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In private IMediaServerService mediaServerService; @Autowired - private ZLMHttpHookSubscribe subscribe; + private ZlmHttpHookSubscribe subscribe; @Autowired private DynamicTask dynamicTask; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index 7e284574b..52cb3749f 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; @@ -40,7 +40,6 @@ import org.springframework.stereotype.Component; import javax.sdp.*; import javax.sip.*; -import javax.sip.address.SipURI; import javax.sip.header.CallIdHeader; import javax.sip.message.Request; import javax.sip.message.Response; @@ -307,7 +306,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements Long finalStartTime = startTime; Long finalStopTime = stopTime; - ZLMHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON) -> { + ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON) -> { String app = responseJSON.getString("app"); String stream = responseJSON.getString("stream"); logger.info("[上级点播]下级已经开始推流。 回复200OK(SDP), {}/{}", app, stream); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 7afe0fd1b..87271a30a 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -22,9 +22,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -81,7 +79,7 @@ public class ZLMHttpHookListener { private ZLMMediaListManager zlmMediaListManager; @Autowired - private ZLMHttpHookSubscribe subscribe; + private ZlmHttpHookSubscribe subscribe; @Autowired private UserSetting userSetting; @@ -109,9 +107,9 @@ public class ZLMHttpHookListener { logger.info("[ ZLM HOOK ] on_server_keepalive API调用,参数:" + json.toString()); String mediaServerId = json.getString("mediaServerId"); - List subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive); + List subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive); if (subscribes != null && subscribes.size() > 0) { - for (ZLMHttpHookSubscribe.Event subscribe : subscribes) { + for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { subscribe.response(null, json); } } @@ -175,7 +173,7 @@ public class ZLMHttpHookListener { logger.debug("[ ZLM HOOK ]on_play API调用,参数:" + JSON.toJSONString(param)); } String mediaServerId = param.getMediaServerId(); - ZLMHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_play, json); + ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_play, json); if (subscribe != null ) { MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo != null) { @@ -263,7 +261,7 @@ public class ZLMHttpHookListener { } - ZLMHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); + ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); if (subscribe != null) { if (mediaInfo != null) { subscribe.response(mediaInfo, json); @@ -387,7 +385,7 @@ public class ZLMHttpHookListener { logger.debug("[ ZLM HOOK ]on_shell_login API调用,参数:" + json.toString()); } String mediaServerId = json.getString("mediaServerId"); - ZLMHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_shell_login, json); + ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_shell_login, json); if (subscribe != null ) { MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo != null) { @@ -413,7 +411,7 @@ public class ZLMHttpHookListener { logger.info("[ ZLM HOOK ]on_stream_changed API调用,参数:" + JSONObject.toJSONString(item)); String mediaServerId = item.getMediaServerId(); JSONObject json = (JSONObject) JSON.toJSON(item); - ZLMHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json); + ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json); if (subscribe != null ) { MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo != null) { @@ -635,9 +633,9 @@ public class ZLMHttpHookListener { } String remoteAddr = request.getRemoteAddr(); jsonObject.put("ip", remoteAddr); - List subscribes = this.subscribe.getSubscribes(HookType.on_server_started); + List subscribes = this.subscribe.getSubscribes(HookType.on_server_started); if (subscribes != null && subscribes.size() > 0) { - for (ZLMHttpHookSubscribe.Event subscribe : subscribes) { + for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { subscribe.response(null, jsonObject); } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java index a8b4a8d97..50a1fa59a 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java @@ -1,30 +1,24 @@ package com.genersoft.iot.vmp.media.zlm; -import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.service.IStreamPushService; -import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.dao.GbStreamMapper; import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper; import com.genersoft.iot.vmp.storager.dao.StreamPushMapper; import com.genersoft.iot.vmp.utils.DateUtil; -import org.checkerframework.checker.units.qual.C; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; import java.util.*; import java.util.concurrent.ConcurrentHashMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * @author lin @@ -59,7 +53,7 @@ public class ZLMMediaListManager { private StreamPushMapper streamPushMapper; @Autowired - private ZLMHttpHookSubscribe subscribe; + private ZlmHttpHookSubscribe subscribe; @Autowired private UserSetting userSetting; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java index b24d0a1a4..da4bb76c3 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java @@ -8,7 +8,6 @@ import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForServerStarted; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; import org.slf4j.Logger; @@ -19,9 +18,7 @@ import org.springframework.core.annotation.Order; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; -import java.time.Instant; import java.util.*; -import java.util.concurrent.TimeUnit; @Component @Order(value=1) @@ -35,7 +32,7 @@ public class ZLMRunner implements CommandLineRunner { private ZLMRESTfulUtils zlmresTfulUtils; @Autowired - private ZLMHttpHookSubscribe hookSubscribe; + private ZlmHttpHookSubscribe hookSubscribe; @Autowired private EventPublisher publisher; @@ -62,8 +59,6 @@ public class ZLMRunner implements CommandLineRunner { } mediaServerService.syncCatchFromDatabase(); HookSubscribeForServerStarted hookSubscribeForServerStarted = HookSubscribeFactory.on_server_started(); -// Instant expiresInstant = Instant.now().plusSeconds(TimeUnit.SECONDS.toSeconds(60)); -// hookSubscribeForStreamChange.setExpires(expiresInstant); // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 hookSubscribe.addSubscribe(hookSubscribeForServerStarted, (MediaServerItem mediaServerItem, JSONObject response)->{ diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java similarity index 69% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java rename to src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java index 57b6d81f9..823bdabb4 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java @@ -4,6 +4,9 @@ import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.media.zlm.dto.HookType; import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -13,21 +16,22 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; /** - * @description:针对 ZLMediaServer的hook事件订阅 - * @author: pan - * @date: 2020年12月2日 21:17:32 + * ZLMediaServer的hook事件订阅 + * @author lin */ @Component -public class ZLMHttpHookSubscribe { +public class ZlmHttpHookSubscribe { + + private final static Logger logger = LoggerFactory.getLogger(ZlmHttpHookSubscribe.class); @FunctionalInterface public interface Event{ void response(MediaServerItem mediaServerItem, JSONObject response); } - private Map> allSubscribes = new ConcurrentHashMap<>(); + private Map> allSubscribes = new ConcurrentHashMap<>(); - public void addSubscribe(IHookSubscribe hookSubscribe, ZLMHttpHookSubscribe.Event event) { + public void addSubscribe(IHookSubscribe hookSubscribe, ZlmHttpHookSubscribe.Event event) { if (hookSubscribe.getExpires() == null) { // 默认5分钟过期 Instant expiresInstant = Instant.now().plusSeconds(TimeUnit.MINUTES.toSeconds(5)); @@ -36,8 +40,8 @@ public class ZLMHttpHookSubscribe { allSubscribes.computeIfAbsent(hookSubscribe.getHookType(), k -> new ConcurrentHashMap<>()).put(hookSubscribe, event); } - public ZLMHttpHookSubscribe.Event sendNotify(HookType type, JSONObject hookResponse) { - ZLMHttpHookSubscribe.Event event= null; + public ZlmHttpHookSubscribe.Event sendNotify(HookType type, JSONObject hookResponse) { + ZlmHttpHookSubscribe.Event event= null; Map eventMap = allSubscribes.get(type); if (eventMap == null) { return null; @@ -69,8 +73,8 @@ public class ZLMHttpHookSubscribe { Set> entries = eventMap.entrySet(); if (entries.size() > 0) { - List> entriesToRemove = new ArrayList<>(); - for (Map.Entry entry : entries) { + List> entriesToRemove = new ArrayList<>(); + for (Map.Entry entry : entries) { JSONObject content = entry.getKey().getContent(); if (content == null || content.size() == 0) { entriesToRemove.add(entry); @@ -87,13 +91,13 @@ public class ZLMHttpHookSubscribe { result = result && content.getString(s).equals(hookSubscribe.getContent().getString(s)); } } - if (null != result && result){ + if (result){ entriesToRemove.add(entry); } } if (!CollectionUtils.isEmpty(entriesToRemove)) { - for (Map.Entry entry : entriesToRemove) { + for (Map.Entry entry : entriesToRemove) { entries.remove(entry); } } @@ -106,12 +110,12 @@ public class ZLMHttpHookSubscribe { * @param type * @return */ - public List getSubscribes(HookType type) { + public List getSubscribes(HookType type) { Map eventMap = allSubscribes.get(type); if (eventMap == null) { return null; } - List result = new ArrayList<>(); + List result = new ArrayList<>(); for (IHookSubscribe key : eventMap.keySet()) { result.add(eventMap.get(key)); } @@ -127,5 +131,28 @@ public class ZLMHttpHookSubscribe { return result; } + /** + * 对订阅数据进行过期清理 + */ + @Scheduled(cron="0 0/5 * * * ?") //每5分钟执行一次 + public void execute(){ + logger.info("[hook订阅] 清理"); + + Instant instant = Instant.now().minusMillis(TimeUnit.MINUTES.toMillis(5)); + int total = 0; + for (HookType hookType : allSubscribes.keySet()) { + Map hookSubscribeEventMap = allSubscribes.get(hookType); + if (hookSubscribeEventMap.size() > 0) { + for (IHookSubscribe hookSubscribe : hookSubscribeEventMap.keySet()) { + if (hookSubscribe.getExpires().isBefore(instant)) { + // 过期的 + hookSubscribeEventMap.remove(hookSubscribe); + total ++; + } + } + } + } + logger.info("[hook订阅] 清理结束,共清理{}条过期数据", total); + } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java index 4df0a6b89..1e4dc1331 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java @@ -6,14 +6,13 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.InviteStreamCallback; import com.genersoft.iot.vmp.gb28181.bean.InviteStreamInfo; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; import com.genersoft.iot.vmp.service.bean.PlayBackCallback; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; -import org.springframework.http.ResponseEntity; import org.springframework.web.context.request.async.DeferredResult; /** @@ -24,9 +23,9 @@ public interface IPlayService { void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid); void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, - ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, + ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, InviteTimeOutCallback timeoutCallback, String uuid); - PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent, Runnable timeoutCallback); + PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent, Runnable timeoutCallback); MediaServerItem getNewMediaServerItem(Device device); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index dc62b07f1..5ccc5e83c 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -39,7 +39,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; @@ -99,7 +99,7 @@ public class PlayServiceImpl implements IPlayService { private DynamicTask dynamicTask; @Autowired - private ZLMHttpHookSubscribe subscribe; + private ZlmHttpHookSubscribe subscribe; @Qualifier("taskExecutor") @@ -110,7 +110,7 @@ public class PlayServiceImpl implements IPlayService { @Override public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, - ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, + ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, Runnable timeoutCallback) { if (mediaServerItem == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的zlm"); @@ -231,8 +231,8 @@ public class PlayServiceImpl implements IPlayService { @Override public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, - ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, - InviteTimeOutCallback timeoutCallback, String uuid) { + ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, + InviteTimeOutCallback timeoutCallback, String uuid) { String streamId = null; if (mediaServerItem.isRtpEnable()) { diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java index 4ef1d0156..ff82cd7f6 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java @@ -5,12 +5,11 @@ import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; -import com.genersoft.iot.vmp.media.zlm.dto.HookType; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.*; @@ -24,9 +23,6 @@ import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.MessageListener; import org.springframework.stereotype.Component; -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import java.text.ParseException; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -86,7 +82,7 @@ public class RedisGbPlayMsgListener implements MessageListener { private ZLMMediaListManager mediaListManager; @Autowired - private ZLMHttpHookSubscribe subscribe; + private ZlmHttpHookSubscribe subscribe; public interface PlayMsgCallback{ diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java index 08b07938c..2884734b9 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java @@ -8,24 +8,21 @@ import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.VersionInfo; import com.genersoft.iot.vmp.conf.exception.ControllerException; -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.utils.SpringBeanFactory; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import gov.nist.javax.sip.SipStackImpl; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; -import org.ehcache.xml.model.ThreadPoolsType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import javax.sip.ListeningPoint; @@ -42,7 +39,7 @@ import java.util.List; public class ServerController { @Autowired - private ZLMHttpHookSubscribe zlmHttpHookSubscribe; + private ZlmHttpHookSubscribe zlmHttpHookSubscribe; @Autowired private IMediaServerService mediaServerService; From 703c2e292a812f80d9a1a7551c18c2cf457f58ba Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Wed, 31 Aug 2022 18:07:53 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E4=BA=91=E7=AB=AF=E5=BD=95=E5=83=8F?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E6=B7=BB=E5=8A=A0=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/genersoft/iot/vmp/gb28181/SipLayer.java | 7 ------- .../iot/vmp/service/impl/PlatformServiceImpl.java | 2 +- web_src/src/components/CloudRecord.vue | 8 ++++++-- web_src/src/components/CloudRecordDetail.vue | 5 +++++ web_src/src/components/Login.vue | 11 +++++++---- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java index afc56718f..f32bd26a5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java @@ -2,25 +2,18 @@ package com.genersoft.iot.vmp.gb28181; import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver; -import com.genersoft.iot.vmp.utils.DateUtil; import gov.nist.javax.sip.SipProviderImpl; import gov.nist.javax.sip.SipStackImpl; -import org.apache.commons.lang3.time.DateFormatUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; -import org.springframework.stereotype.Component; import javax.sip.*; -import java.text.DateFormat; import java.util.Properties; import java.util.TooManyListenersException; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; @Configuration public class SipLayer{ diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java index 3a5d19a6b..708d6935b 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -102,7 +102,7 @@ public class PlatformServiceImpl implements IPlatformService { @Override public void online(ParentPlatform parentPlatform) { - logger.info("[国标级联]:{}, 平台上线", parentPlatform.getServerGBId()); + logger.info("[国标级联]:{}, 平台上线/更新注册", parentPlatform.getServerGBId()); platformMapper.updateParentPlatformStatus(parentPlatform.getServerGBId(), true); ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); if (parentPlatformCatch != null) { diff --git a/web_src/src/components/CloudRecord.vue b/web_src/src/components/CloudRecord.vue index 73f20c1d9..4784e05c7 100644 --- a/web_src/src/components/CloudRecord.vue +++ b/web_src/src/components/CloudRecord.vue @@ -1,7 +1,11 @@