From f10b458fc919fbcadc4936bf3a7886088e20ac71 Mon Sep 17 00:00:00 2001 From: 648540858 <456panlinlin> Date: Fri, 8 Apr 2022 14:44:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AE=A2=E9=98=85=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E7=9A=84=E5=8F=91=E9=80=81=E4=B8=8E=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E8=AE=A2=E9=98=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/conf/DynamicTask.java | 14 +++- .../iot/vmp/conf/runner/SipDeviceRunner.java | 14 ++-- .../iot/vmp/gb28181/task/ISubscribeTask.java | 5 ++ .../task/impl/CatalogSubscribeTask.java | 75 ++++++++++++++++++ .../MobilePositionSubscribeHandlerTask.java} | 16 +++- .../impl/MobilePositionSubscribeTask.java | 77 +++++++++++++++++++ .../gb28181/transmit/cmd/ISIPCommander.java | 6 +- .../transmit/cmd/impl/SIPCommander.java | 29 +++++-- .../impl/SubscribeRequestProcessor.java | 8 +- .../impl/InviteResponseProcessor.java | 2 +- .../vmp/media/zlm/ZLMRTPServerFactory.java | 11 ++- .../service/bean/CatalogSubscribeTask.java | 42 ---------- .../bean/MobilePositionSubscribeTask.java | 38 --------- .../vmp/service/impl/DeviceServiceImpl.java | 12 +-- .../MobilePositionController.java | 6 +- web_src/src/components/dialog/deviceEdit.vue | 11 ++- 16 files changed, 242 insertions(+), 124 deletions(-) create mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/task/ISubscribeTask.java create mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/CatalogSubscribeTask.java rename src/main/java/com/genersoft/iot/vmp/gb28181/task/{GPSSubscribeTask.java => impl/MobilePositionSubscribeHandlerTask.java} (83%) create mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeTask.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/service/bean/CatalogSubscribeTask.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/service/bean/MobilePositionSubscribeTask.java diff --git a/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java b/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java index bbe0e819..0c57bdef 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java @@ -1,5 +1,6 @@ package com.genersoft.iot.vmp.conf; +import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; @@ -21,6 +22,7 @@ public class DynamicTask { private ThreadPoolTaskScheduler threadPoolTaskScheduler; private Map> futureMap = new ConcurrentHashMap<>(); + private Map runnableMap = new ConcurrentHashMap<>(); @Bean public ThreadPoolTaskScheduler threadPoolTaskScheduler() { @@ -34,12 +36,12 @@ public class DynamicTask { * @param cycleForCatalog 间隔 * @return */ - public String startCron(String key, Runnable task, int cycleForCatalog) { + public void startCron(String key, Runnable task, int cycleForCatalog) { stop(key); // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔 ScheduledFuture future = threadPoolTaskScheduler.scheduleWithFixedDelay(task, cycleForCatalog * 1000L); futureMap.put(key, future); - return "startCron"; + runnableMap.put(key, task); } /** @@ -49,18 +51,22 @@ public class DynamicTask { * @param delay 延时 /毫秒 * @return */ - public String startDelay(String key, Runnable task, int delay) { + public void startDelay(String key, Runnable task, int delay) { stop(key); Date starTime = new Date(System.currentTimeMillis() + delay); // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔 ScheduledFuture future = threadPoolTaskScheduler.schedule(task, starTime); futureMap.put(key, future); - return "startCron"; } public void stop(String key) { if (futureMap.get(key) != null && !futureMap.get(key).isCancelled()) { futureMap.get(key).cancel(true); + Runnable runnable = runnableMap.get(key); + if (runnable instanceof ISubscribeTask) { + ISubscribeTask subscribeTask = (ISubscribeTask) runnable; + subscribeTask.stop(); + } } } diff --git a/src/main/java/com/genersoft/iot/vmp/conf/runner/SipDeviceRunner.java b/src/main/java/com/genersoft/iot/vmp/conf/runner/SipDeviceRunner.java index 2c2ea6d7..4a897968 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/runner/SipDeviceRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/runner/SipDeviceRunner.java @@ -14,7 +14,7 @@ import java.util.List; /** - * 系统启动时控制设备离线 + * 系统启动时控制设备 */ @Component @Order(value=4) @@ -41,10 +41,14 @@ public class SipDeviceRunner implements CommandLineRunner { for (String deviceId : onlineForAll) { storager.online(deviceId); Device device = redisCatchStorage.getDevice(deviceId); - if (device != null && device.getSubscribeCycleForCatalog() > 0) { - // 查询在线设备那些开启了订阅,为设备开启定时的目录订阅 - deviceService.addCatalogSubscribe(device); - deviceService.addMobilePositionSubscribe(device); + if (device != null ) { + if (device.getSubscribeCycleForCatalog() > 0) { + // 查询在线设备那些开启了订阅,为设备开启定时的目录订阅 + deviceService.addCatalogSubscribe(device); + } + if (device.getSubscribeCycleForMobilePosition() > 0) { + deviceService.addMobilePositionSubscribe(device); + } } } // 重置cseq计数 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/ISubscribeTask.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/ISubscribeTask.java new file mode 100644 index 00000000..4c6a18ac --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/ISubscribeTask.java @@ -0,0 +1,5 @@ +package com.genersoft.iot.vmp.gb28181.task; + +public interface ISubscribeTask extends Runnable{ + void stop(); +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/CatalogSubscribeTask.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/CatalogSubscribeTask.java new file mode 100644 index 00000000..51356d55 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/CatalogSubscribeTask.java @@ -0,0 +1,75 @@ +package com.genersoft.iot.vmp.gb28181.task.impl; + +import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.sip.Dialog; +import javax.sip.DialogState; +import javax.sip.ResponseEvent; + +/** + * 目录订阅任务 + */ +public class CatalogSubscribeTask implements ISubscribeTask { + private final Logger logger = LoggerFactory.getLogger(CatalogSubscribeTask.class); + private Device device; + private final ISIPCommander sipCommander; + private Dialog dialog; + + public CatalogSubscribeTask(Device device, ISIPCommander sipCommander) { + this.device = device; + this.sipCommander = sipCommander; + } + + @Override + public void run() { + sipCommander.catalogSubscribe(device, dialog, eventResult -> { + if (eventResult.dialog != null || eventResult.dialog.getState().equals(DialogState.CONFIRMED)) { + dialog = eventResult.dialog; + } + ResponseEvent event = (ResponseEvent) eventResult.event; + if (event.getResponse().getRawContent() != null) { + // 成功 + logger.info("[目录订阅]成功: {}", device.getDeviceId()); + }else { + // 成功 + logger.info("[目录订阅]成功: {}", device.getDeviceId()); + } + },eventResult -> { + dialog = null; + // 失败 + logger.warn("[目录订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg); + }); + } + + @Override + public void stop() { + /** + * dialog 的各个状态 + * EARLY-> Early state状态-初始请求发送以后,收到了一个临时响应消息 + * CONFIRMED-> Confirmed Dialog状态-已确认 + * COMPLETED-> Completed Dialog状态-已完成 + * TERMINATED-> Terminated Dialog状态-终止 + */ + logger.info("取消目录订阅时dialog状态为{}", DialogState.CONFIRMED); + if (dialog != null && dialog.getState().equals(DialogState.CONFIRMED)) { + device.setSubscribeCycleForCatalog(0); + sipCommander.mobilePositionSubscribe(device, dialog, eventResult -> { + ResponseEvent event = (ResponseEvent) eventResult.event; + if (event.getResponse().getRawContent() != null) { + // 成功 + logger.info("[取消目录订阅订阅]成功: {}", device.getDeviceId()); + }else { + // 成功 + logger.info("[取消目录订阅订阅]成功: {}", device.getDeviceId()); + } + },eventResult -> { + // 失败 + logger.warn("[取消目录订阅订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg); + }); + } + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/GPSSubscribeTask.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java similarity index 83% rename from src/main/java/com/genersoft/iot/vmp/gb28181/task/GPSSubscribeTask.java rename to src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java index a2716e3e..fcac3e9d 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/task/GPSSubscribeTask.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java @@ -1,10 +1,10 @@ -package com.genersoft.iot.vmp.gb28181.task; +package com.genersoft.iot.vmp.gb28181.task.impl; -import com.alibaba.fastjson.JSON; import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo; +import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -13,7 +13,10 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import java.text.SimpleDateFormat; import java.util.List; -public class GPSSubscribeTask implements Runnable{ +/** + * 向已经订阅(移动位置)的上级发送MobilePosition消息 + */ +public class MobilePositionSubscribeHandlerTask implements ISubscribeTask { private IRedisCatchStorage redisCatchStorage; private IVideoManagerStorage storager; @@ -25,7 +28,7 @@ public class GPSSubscribeTask implements Runnable{ private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - public GPSSubscribeTask(IRedisCatchStorage redisCatchStorage, ISIPCommanderForPlatform sipCommanderForPlatform, IVideoManagerStorage storager, String platformId, String sn, String key, SubscribeHolder subscribeInfo) { + public MobilePositionSubscribeHandlerTask(IRedisCatchStorage redisCatchStorage, ISIPCommanderForPlatform sipCommanderForPlatform, IVideoManagerStorage storager, String platformId, String sn, String key, SubscribeHolder subscribeInfo) { this.redisCatchStorage = redisCatchStorage; this.storager = storager; this.platformId = platformId; @@ -66,4 +69,9 @@ public class GPSSubscribeTask implements Runnable{ } } } + + @Override + public void stop() { + + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeTask.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeTask.java new file mode 100644 index 00000000..f67f6d26 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeTask.java @@ -0,0 +1,77 @@ +package com.genersoft.iot.vmp.gb28181.task.impl; + +import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; +import org.dom4j.Element; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.sip.Dialog; +import javax.sip.DialogState; +import javax.sip.ResponseEvent; + +/** + * 移动位置订阅的定时更新 + */ +public class MobilePositionSubscribeTask implements ISubscribeTask { + private final Logger logger = LoggerFactory.getLogger(MobilePositionSubscribeTask.class); + private Device device; + private ISIPCommander sipCommander; + private Dialog dialog; + + public MobilePositionSubscribeTask(Device device, ISIPCommander sipCommander) { + this.device = device; + this.sipCommander = sipCommander; + } + + @Override + public void run() { + sipCommander.mobilePositionSubscribe(device, dialog, eventResult -> { + if (eventResult.dialog != null || eventResult.dialog.getState().equals(DialogState.CONFIRMED)) { + dialog = eventResult.dialog; + } + ResponseEvent event = (ResponseEvent) eventResult.event; + if (event.getResponse().getRawContent() != null) { + // 成功 + logger.info("[移动位置订阅]成功: {}", device.getDeviceId()); + }else { + // 成功 + logger.info("[移动位置订阅]成功: {}", device.getDeviceId()); + } + },eventResult -> { + dialog = null; + // 失败 + logger.warn("[移动位置订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg); + }); + + } + + @Override + public void stop() { + /** + * dialog 的各个状态 + * EARLY-> Early state状态-初始请求发送以后,收到了一个临时响应消息 + * CONFIRMED-> Confirmed Dialog状态-已确认 + * COMPLETED-> Completed Dialog状态-已完成 + * TERMINATED-> Terminated Dialog状态-终止 + */ + logger.info("取消移动订阅时dialog状态为{}", dialog.getState()); + if (dialog != null && dialog.getState().equals(DialogState.CONFIRMED)) { + device.setSubscribeCycleForMobilePosition(0); + sipCommander.mobilePositionSubscribe(device, dialog, eventResult -> { + ResponseEvent event = (ResponseEvent) eventResult.event; + if (event.getResponse().getRawContent() != null) { + // 成功 + logger.info("[取消移动位置订阅]成功: {}", device.getDeviceId()); + }else { + // 成功 + logger.info("[取消移动位置订阅]成功: {}", device.getDeviceId()); + } + },eventResult -> { + // 失败 + logger.warn("[取消移动位置订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg); + }); + } + } +} 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 6b8a6aef..1de03bd7 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 @@ -8,6 +8,8 @@ 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; +import javax.sip.Dialog; + /** * @description:设备能力接口,用于定义设备的控制、查询能力 * @author: swwheihei @@ -304,7 +306,7 @@ public interface ISIPCommander { * @param device 视频设备 * @return true = 命令发送成功 */ - boolean mobilePositionSubscribe(Device device, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent); + boolean mobilePositionSubscribe(Device device, Dialog dialog, SipSubscribe.Event okEvent , SipSubscribe.Event errorEvent); /** * 订阅、取消订阅报警信息 @@ -324,7 +326,7 @@ public interface ISIPCommander { * @param device 视频设备 * @return true = 命令发送成功 */ - boolean catalogSubscribe(Device device, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent); + boolean catalogSubscribe(Device device, Dialog dialog, 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 4baa349e..123d0e78 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 @@ -36,6 +36,8 @@ import org.springframework.util.StringUtils; import javax.sip.*; import javax.sip.address.SipURI; import javax.sip.header.CallIdHeader; +import javax.sip.header.ContentTypeHeader; +import javax.sip.header.ExpiresHeader; import javax.sip.header.ViaHeader; import javax.sip.message.Request; import java.lang.reflect.Field; @@ -56,6 +58,9 @@ public class SIPCommander implements ISIPCommander { @Autowired private SipConfig sipConfig; + @Autowired + private SipFactory sipFactory; + @Autowired @Qualifier(value="tcpSipProvider") private SipProviderImpl tcpSipProvider; @@ -1453,7 +1458,7 @@ public class SIPCommander implements ISIPCommander { * @param device 视频设备 * @return true = 命令发送成功 */ - public boolean mobilePositionSubscribe(Device device, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent) { + public boolean mobilePositionSubscribe(Device device, Dialog dialog, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent) { try { StringBuffer subscribePostitionXml = new StringBuffer(200); String charset = device.getCharset(); @@ -1467,12 +1472,20 @@ public class SIPCommander implements ISIPCommander { } subscribePostitionXml.append("\r\n"); - String tm = Long.toString(System.currentTimeMillis()); - - CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() - : udpSipProvider.getNewCallId(); - - Request request = headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), "z9hG4bK-viaPos-" + tm, "fromTagPos" + tm, null, device.getSubscribeCycleForMobilePosition(), "presence" ,callIdHeader); //Position;id=" + tm.substring(tm.length() - 4)); + Request request; + if (dialog != null) { + logger.info("发送移动位置订阅消息时 dialog的状态为: {}", dialog.getState()); + request = dialog.createRequest(Request.SUBSCRIBE); + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); + request.setContent(subscribePostitionXml.toString(), contentTypeHeader); + ExpiresHeader expireHeader = sipFactory.createHeaderFactory().createExpiresHeader(device.getSubscribeCycleForMobilePosition()); + request.addHeader(expireHeader); + }else { + String tm = Long.toString(System.currentTimeMillis()); + CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() + : udpSipProvider.getNewCallId(); + request = headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), "z9hG4bK-viaPos-" + tm, "fromTagPos" + tm, null, device.getSubscribeCycleForMobilePosition(), "presence" ,callIdHeader); //Position;id=" + tm.substring(tm.length() - 4)); + } transmitRequest(device, request, errorEvent, okEvent); return true; @@ -1542,7 +1555,7 @@ public class SIPCommander implements ISIPCommander { } @Override - public boolean catalogSubscribe(Device device, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) { + public boolean catalogSubscribe(Device device, Dialog dialog, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) { try { StringBuffer cmdXml = new StringBuffer(200); String charset = device.getCharset(); 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 e8554f7e..13367059 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 @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.gb28181.bean.CmdType; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo; -import com.genersoft.iot.vmp.gb28181.task.GPSSubscribeTask; +import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeHandlerTask; 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.request.ISIPRequestProcessor; @@ -147,7 +147,7 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme } String sn = XmlUtil.getText(rootElement, "SN"); String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetting.getServerId() + "_MobilePosition_" + platformId; - logger.info("接收到{}的MobilePosition订阅", platformId); + logger.info("[notify-MobilePosition]: {}", platformId); StringBuilder resultXml = new StringBuilder(200); resultXml.append("\r\n") .append("\r\n") @@ -162,7 +162,7 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme dynamicTask.stop(key); } String interval = XmlUtil.getText(rootElement, "Interval"); // GPS上报时间间隔 - dynamicTask.startCron(key, new GPSSubscribeTask(redisCatchStorage, sipCommanderForPlatform, storager, platformId, sn, key, subscribeHolder), Integer.parseInt(interval)); + dynamicTask.startCron(key, new MobilePositionSubscribeHandlerTask(redisCatchStorage, sipCommanderForPlatform, storager, platformId, sn, key, subscribeHolder), Integer.parseInt(interval) -1 ); subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo); }else if (subscribeInfo.getExpires() == 0) { dynamicTask.stop(key); @@ -200,7 +200,7 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme } String sn = XmlUtil.getText(rootElement, "SN"); String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetting.getServerId() + "_Catalog_" + platformId; - logger.info("接收到{}的Catalog订阅", platformId); + logger.info("[notify-Catalog]: {}", platformId); StringBuilder resultXml = new StringBuilder(200); resultXml.append("\r\n") .append("\r\n") 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 1b5081b1..c81aabb6 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 @@ -81,7 +81,7 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract { } requestURI.setPort(event.getRemotePort()); reqAck.setRequestURI(requestURI); - logger.info("向 " + event.getRemoteIpAddress() + ":" + event.getRemotePort() + "回复ack"); + logger.info("[回复ack] {}-> {}:{} ",requestURI, event.getRemoteIpAddress(), event.getRemotePort()); dialog.sendAck(reqAck); 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 57afd939..de9f1762 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 @@ -82,9 +82,14 @@ public class ZLMRTPServerFactory { } public int createRTPServer(MediaServerItem mediaServerItem, String streamId) { - - Map param = new HashMap<>(); int result = -1; + // 查询此rtp server 是否已经存在 + JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaServerItem, streamId); + if (rtpInfo.getInteger("code ") == 0 && rtpInfo.getBoolean("exist")) { + result = rtpInfo.getInteger("local_port"); + return result; + } + Map param = new HashMap<>(); // 推流端口设置0则使用随机端口 param.put("enable_tcp", 1); param.put("stream_id", streamId); @@ -301,7 +306,7 @@ public class ZLMRTPServerFactory { result= true; logger.info("停止RTP推流成功"); } else { - logger.error("RTP推流失败: {}, 参数:{}",jsonObject.getString("msg"),JSONObject.toJSON(param)); + logger.error("停止RTP推流失败: {}, 参数:{}",jsonObject.getString("msg"),JSONObject.toJSON(param)); } return result; } diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/CatalogSubscribeTask.java b/src/main/java/com/genersoft/iot/vmp/service/bean/CatalogSubscribeTask.java deleted file mode 100644 index 68419bfc..00000000 --- a/src/main/java/com/genersoft/iot/vmp/service/bean/CatalogSubscribeTask.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.genersoft.iot.vmp.service.bean; - -import com.genersoft.iot.vmp.gb28181.bean.Device; -import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; -import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; -import org.dom4j.DocumentException; -import org.dom4j.Element; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.sip.ResponseEvent; - -/** - * 目录订阅任务 - */ -public class CatalogSubscribeTask implements Runnable{ - private final Logger logger = LoggerFactory.getLogger(CatalogSubscribeTask.class); - private Device device; - private ISIPCommander sipCommander; - - public CatalogSubscribeTask(Device device, ISIPCommander sipCommander) { - this.device = device; - this.sipCommander = sipCommander; - } - - @Override - public void run() { - sipCommander.catalogSubscribe(device, eventResult -> { - ResponseEvent event = (ResponseEvent) eventResult.event; - if (event.getResponse().getRawContent() != null) { - // 成功 - logger.info("[目录订阅]成功: {}", device.getDeviceId()); - }else { - // 成功 - logger.info("[目录订阅]成功: {}", device.getDeviceId()); - } - },eventResult -> { - // 失败 - logger.warn("[目录订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg); - }); - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/MobilePositionSubscribeTask.java b/src/main/java/com/genersoft/iot/vmp/service/bean/MobilePositionSubscribeTask.java deleted file mode 100644 index df4bc6cc..00000000 --- a/src/main/java/com/genersoft/iot/vmp/service/bean/MobilePositionSubscribeTask.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.genersoft.iot.vmp.service.bean; - -import com.genersoft.iot.vmp.gb28181.bean.Device; -import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; -import org.dom4j.Element; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.sip.ResponseEvent; - -public class MobilePositionSubscribeTask implements Runnable{ - private final Logger logger = LoggerFactory.getLogger(MobilePositionSubscribeTask.class); - private Device device; - private ISIPCommander sipCommander; - - public MobilePositionSubscribeTask(Device device, ISIPCommander sipCommander) { - this.device = device; - this.sipCommander = sipCommander; - } - - @Override - public void run() { - sipCommander.mobilePositionSubscribe(device, eventResult -> { - ResponseEvent event = (ResponseEvent) eventResult.event; - Element rootElement = null; - if (event.getResponse().getRawContent() != null) { - // 成功 - logger.info("[移动位置订阅]成功: {}", device.getDeviceId()); - }else { - // 成功 - logger.info("[移动位置订阅]成功: {}", device.getDeviceId()); - } - },eventResult -> { - // 失败 - logger.warn("[移动位置订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg); - }); - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java index 384bf7f2..e9f7968f 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java @@ -4,8 +4,8 @@ import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.service.IDeviceService; -import com.genersoft.iot.vmp.service.bean.CatalogSubscribeTask; -import com.genersoft.iot.vmp.service.bean.MobilePositionSubscribeTask; +import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask; +import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -42,7 +42,7 @@ public class DeviceServiceImpl implements IDeviceService { int subscribeCycleForCatalog = device.getSubscribeCycleForCatalog(); // 设置最小值为30 subscribeCycleForCatalog = Math.max(subscribeCycleForCatalog, 30); - dynamicTask.startCron(device.getDeviceId() + "catalog", catalogSubscribeTask, subscribeCycleForCatalog - 5); + dynamicTask.startCron(device.getDeviceId() + "catalog", catalogSubscribeTask, subscribeCycleForCatalog); return true; } @@ -53,8 +53,6 @@ public class DeviceServiceImpl implements IDeviceService { } logger.info("移除目录订阅: {}", device.getDeviceId()); dynamicTask.stop(device.getDeviceId() + "catalog"); - device.setSubscribeCycleForCatalog(0); - sipCommander.catalogSubscribe(device, null, null); return true; } @@ -75,7 +73,7 @@ public class DeviceServiceImpl implements IDeviceService { int subscribeCycleForCatalog = device.getSubscribeCycleForCatalog(); // 设置最小值为30 subscribeCycleForCatalog = Math.max(subscribeCycleForCatalog, 30); - dynamicTask.startCron(device.getDeviceId() + "mobile_position" , mobilePositionSubscribeTask, subscribeCycleForCatalog - 5); + dynamicTask.startCron(device.getDeviceId() + "mobile_position" , mobilePositionSubscribeTask, subscribeCycleForCatalog -1 ); return true; } @@ -86,8 +84,6 @@ public class DeviceServiceImpl implements IDeviceService { } logger.info("移除移动位置订阅: {}", device.getDeviceId()); dynamicTask.stop(device.getDeviceId() + "mobile_position"); - device.setSubscribeCycleForCatalog(0); - sipCommander.mobilePositionSubscribe(device, null, null); return true; } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java index 365903c2..c360843d 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.gb28181.bean.MobilePosition; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; +import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.github.pagehelper.util.StringUtil; @@ -48,6 +49,9 @@ public class MobilePositionController { @Autowired private DeferredResultHolder resultHolder; + @Autowired + private IDeviceService deviceService; + /** * 查询历史轨迹 * @param deviceId 设备ID @@ -163,7 +167,7 @@ public class MobilePositionController { device.setMobilePositionSubmissionInterval(Integer.parseInt(interval)); storager.updateDevice(device); String result = msg; - if (cmder.mobilePositionSubscribe(device, null, null)) { + if (deviceService.removeMobilePositionSubscribe(device)) { result += ",成功"; } else { result += ",失败"; diff --git a/web_src/src/components/dialog/deviceEdit.vue b/web_src/src/components/dialog/deviceEdit.vue index 1150d21a..1b1aba02 100644 --- a/web_src/src/components/dialog/deviceEdit.vue +++ b/web_src/src/components/dialog/deviceEdit.vue @@ -10,7 +10,7 @@ @close="close()" >
- + @@ -36,13 +36,13 @@ - + - + - + @@ -98,6 +98,9 @@ export default { onSubmit: function () { console.log("onSubmit"); console.log(this.form); + this.form.subscribeCycleForCatalog = this.form.subscribeCycleForCatalog||0 + this.form.subscribeCycleForMobilePosition = this.form.subscribeCycleForMobilePosition||0 + this.form.mobilePositionSubmissionInterval = this.form.mobilePositionSubmissionInterval||0 this.$axios({ method: 'post', url:`/api/device/query/device/update/`,