648540858
2022-04-08 f10b458fc919fbcadc4936bf3a7886088e20ac71
优化订阅信息的发送与取消订阅
10个文件已修改
3个文件已添加
1 文件已重命名
2个文件已删除
366 ■■■■■ 已修改文件
src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/conf/runner/SipDeviceRunner.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/task/ISubscribeTask.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/CatalogSubscribeTask.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeTask.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/service/bean/CatalogSubscribeTask.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/service/bean/MobilePositionSubscribeTask.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
web_src/src/components/dialog/deviceEdit.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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 @@
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;
    private Map<String, ScheduledFuture<?>> futureMap = new ConcurrentHashMap<>();
    private Map<String, Runnable> runnableMap = new ConcurrentHashMap<>();
    @Bean
    public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
@@ -34,12 +36,12 @@
     * @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 @@
     * @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();
            }
        }
    }
src/main/java/com/genersoft/iot/vmp/conf/runner/SipDeviceRunner.java
@@ -14,7 +14,7 @@
/**
 * 系统启动时控制设备离线
 * 系统启动时控制设备
 */
@Component
@Order(value=4)
@@ -41,10 +41,14 @@
        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计数
src/main/java/com/genersoft/iot/vmp/gb28181/task/ISubscribeTask.java
New file
@@ -0,0 +1,5 @@
package com.genersoft.iot.vmp.gb28181.task;
public interface ISubscribeTask extends Runnable{
    void stop();
}
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/CatalogSubscribeTask.java
New file
@@ -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);
            });
        }
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java
File was renamed from src/main/java/com/genersoft/iot/vmp/gb28181/task/GPSSubscribeTask.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 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 @@
    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 @@
            }
        }
    }
    @Override
    public void stop() {
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeTask.java
New file
@@ -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);
            });
        }
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -8,6 +8,8 @@
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 @@
     * @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 @@
     * @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);
    /**
     * 拉框控制命令
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -36,6 +36,8 @@
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;
@@ -55,6 +57,9 @@
    
    @Autowired
    private SipConfig sipConfig;
    @Autowired
    private SipFactory sipFactory;
    @Autowired
    @Qualifier(value="tcpSipProvider")
@@ -1453,7 +1458,7 @@
     * @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 @@
            }
            subscribePostitionXml.append("</Query>\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 @@
    }
    @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();
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.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 @@
        }
        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("<?xml version=\"1.0\" ?>\r\n")
                .append("<Response>\r\n")
@@ -162,7 +162,7 @@
                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 @@
        }
        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("<?xml version=\"1.0\" ?>\r\n")
                .append("<Response>\r\n")
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java
@@ -81,7 +81,7 @@
                }
                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);
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
@@ -82,9 +82,14 @@
    }
    public int createRTPServer(MediaServerItem mediaServerItem, String streamId) {
        Map<String, Object> 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<String, Object> param = new HashMap<>();
        // 推流端口设置0则使用随机端口
        param.put("enable_tcp", 1);
        param.put("stream_id", streamId);
@@ -301,7 +306,7 @@
            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;
    }
src/main/java/com/genersoft/iot/vmp/service/bean/CatalogSubscribeTask.java
File was deleted
src/main/java/com/genersoft/iot/vmp/service/bean/MobilePositionSubscribeTask.java
File was deleted
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
@@ -4,8 +4,8 @@
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 @@
        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 @@
        }
        logger.info("移除目录订阅: {}", device.getDeviceId());
        dynamicTask.stop(device.getDeviceId() + "catalog");
        device.setSubscribeCycleForCatalog(0);
        sipCommander.catalogSubscribe(device, null, null);
        return true;
    }
@@ -75,7 +73,7 @@
        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 @@
        }
        logger.info("移除移动位置订阅: {}", device.getDeviceId());
        dynamicTask.stop(device.getDeviceId() + "mobile_position");
        device.setSubscribeCycleForCatalog(0);
        sipCommander.mobilePositionSubscribe(device, null, null);
        return true;
    }
}
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java
@@ -8,6 +8,7 @@
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;
@@ -47,6 +48,9 @@
    
    @Autowired
    private DeferredResultHolder resultHolder;
    @Autowired
    private IDeviceService deviceService;
    /**
     *  查询历史轨迹
@@ -163,7 +167,7 @@
        device.setMobilePositionSubmissionInterval(Integer.parseInt(interval));
        storager.updateDevice(device);
        String result = msg;
        if (cmder.mobilePositionSubscribe(device, null, null)) {
        if (deviceService.removeMobilePositionSubscribe(device)) {
            result += ",成功";
        } else {
            result += ",失败";
web_src/src/components/dialog/deviceEdit.vue
@@ -10,7 +10,7 @@
      @close="close()"
    >
      <div id="shared" style="margin-top: 1rem;margin-right: 100px;">
        <el-form ref="form" :rules="rules" :model="form" label-width="240px" >
        <el-form ref="form" :rules="rules" :model="form" label-width="200px" >
          <el-form-item label="设备编号" >
            <el-input v-model="form.deviceId" disabled></el-input>
          </el-form-item>
@@ -36,13 +36,13 @@
              <el-option key="UTF-8" label="UTF-8" value="utf-8"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="目录订阅周期(0为停用订阅)" prop="subscribeCycleForCatalog" >
          <el-form-item label="目录订阅" title="0为取消订阅" prop="subscribeCycleForCatalog" >
            <el-input v-model="form.subscribeCycleForCatalog" clearable ></el-input>
          </el-form-item>
          <el-form-item label="移动位置订阅周期(0为停用订阅)" prop="subscribeCycleForCatalog" >
          <el-form-item label="移动位置订阅" title="0为取消订阅" prop="subscribeCycleForCatalog" >
            <el-input v-model="form.subscribeCycleForMobilePosition" clearable ></el-input>
          </el-form-item>
          <el-form-item label="移动位置报送间隔" prop="subscribeCycleForCatalog" >
          <el-form-item v-if="form.subscribeCycleForMobilePosition > 0" label="移动位置报送间隔" prop="subscribeCycleForCatalog" >
            <el-input v-model="form.mobilePositionSubmissionInterval" clearable ></el-input>
          </el-form-item>
          <el-form-item>
@@ -98,6 +98,9 @@
    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/`,