Commit e6ee7fe7477b485676ce506b4e971c9a50dfa588

Authored by 648540858
1 parent efc4a7bc

优化级联移动位置订阅位置更新

src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java
1 1 package com.genersoft.iot.vmp.conf;
2 2  
3 3 import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask;
  4 +import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.CatalogResponseMessageHandler;
  5 +import org.slf4j.Logger;
  6 +import org.slf4j.LoggerFactory;
4 7 import org.springframework.beans.factory.annotation.Autowired;
5 8 import org.springframework.context.annotation.Bean;
6 9 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
... ... @@ -18,6 +21,8 @@ import java.util.concurrent.ScheduledFuture;
18 21 @Component
19 22 public class DynamicTask {
20 23  
  24 + private Logger logger = LoggerFactory.getLogger(DynamicTask.class);
  25 +
21 26 @Autowired
22 27 private ThreadPoolTaskScheduler threadPoolTaskScheduler;
23 28  
... ... @@ -26,7 +31,12 @@ public class DynamicTask {
26 31  
27 32 @Bean
28 33 public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
29   - return new ThreadPoolTaskScheduler();
  34 + ThreadPoolTaskScheduler schedulerPool = new ThreadPoolTaskScheduler();
  35 + schedulerPool.setPoolSize(300);
  36 + schedulerPool.setWaitForTasksToCompleteOnShutdown(true);
  37 + schedulerPool.setAwaitTerminationSeconds(10);
  38 + return schedulerPool;
  39 +
30 40 }
31 41  
32 42 /**
... ... @@ -37,11 +47,24 @@ public class DynamicTask {
37 47 * @return
38 48 */
39 49 public void startCron(String key, Runnable task, int cycleForCatalog) {
40   - stop(key);
  50 + ScheduledFuture future = futureMap.get(key);
  51 + if (future != null) {
  52 + if (future.isCancelled()) {
  53 + logger.info("任务【{}】已存在但是关闭状态!!!", key);
  54 + } else {
  55 + logger.info("任务【{}】已存在且已启动!!!", key);
  56 + return;
  57 + }
  58 + }
41 59 // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔
42   - ScheduledFuture future = threadPoolTaskScheduler.scheduleAtFixedRate(task, cycleForCatalog * 1000L);
43   - futureMap.put(key, future);
44   - runnableMap.put(key, task);
  60 + future = threadPoolTaskScheduler.scheduleAtFixedRate(task, cycleForCatalog * 1000L);
  61 + if (future != null){
  62 + futureMap.put(key, future);
  63 + runnableMap.put(key, task);
  64 + logger.info("任务【{}】启动成功!!!", key);
  65 + }else {
  66 + logger.info("任务【{}】启动失败!!!", key);
  67 + }
45 68 }
46 69  
47 70 /**
... ... @@ -53,13 +76,31 @@ public class DynamicTask {
53 76 */
54 77 public void startDelay(String key, Runnable task, int delay) {
55 78 stop(key);
  79 + System.out.println("定时任务开始了");
56 80 Date starTime = new Date(System.currentTimeMillis() + delay);
  81 +
  82 + ScheduledFuture future = futureMap.get(key);
  83 + if (future != null) {
  84 + if (future.isCancelled()) {
  85 + logger.info("任务【{}】已存在但是关闭状态!!!", key);
  86 + } else {
  87 + logger.info("任务【{}】已存在且已启动!!!", key);
  88 + return;
  89 + }
  90 + }
57 91 // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔
58   - ScheduledFuture future = threadPoolTaskScheduler.schedule(task, starTime);
59   - futureMap.put(key, future);
  92 + future = threadPoolTaskScheduler.schedule(task, starTime);
  93 + if (future != null){
  94 + futureMap.put(key, future);
  95 + runnableMap.put(key, task);
  96 + logger.info("任务【{}】启动成功!!!", key);
  97 + }else {
  98 + logger.info("任务【{}】启动失败!!!", key);
  99 + }
60 100 }
61 101  
62 102 public void stop(String key) {
  103 + System.out.println("定时任务结束了");
63 104 if (futureMap.get(key) != null && !futureMap.get(key).isCancelled()) {
64 105 futureMap.get(key).cancel(true);
65 106 Runnable runnable = runnableMap.get(key);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java
1 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2  
  3 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  4 +import com.genersoft.iot.vmp.conf.DynamicTask;
  5 +import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeHandlerTask;
  6 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
  7 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  8 +import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
  9 +import org.springframework.beans.factory.annotation.Autowired;
3 10 import org.springframework.stereotype.Component;
4 11  
5 12 import java.util.ArrayList;
... ... @@ -9,12 +16,32 @@ import java.util.concurrent.ConcurrentHashMap;
9 16 @Component
10 17 public class SubscribeHolder {
11 18  
  19 + @Autowired
  20 + private DynamicTask dynamicTask;
  21 +
  22 + @Autowired
  23 + private IRedisCatchStorage redisCatchStorage;
  24 +
  25 + @Autowired
  26 + private ISIPCommanderForPlatform sipCommanderForPlatform;
  27 +
  28 + @Autowired
  29 + private IVideoManagerStorage storager;
  30 +
  31 + private final String taskOverduePrefix = "subscribe_overdue_";
  32 +
12 33 private static ConcurrentHashMap<String, SubscribeInfo> catalogMap = new ConcurrentHashMap<>();
13 34 private static ConcurrentHashMap<String, SubscribeInfo> mobilePositionMap = new ConcurrentHashMap<>();
14 35  
15 36  
16 37 public void putCatalogSubscribe(String platformId, SubscribeInfo subscribeInfo) {
17 38 catalogMap.put(platformId, subscribeInfo);
  39 + // 添加订阅到期
  40 + String taskOverdueKey = taskOverduePrefix + "catalog_" + platformId;
  41 + dynamicTask.stop(taskOverdueKey);
  42 + // 添加任务处理订阅过期
  43 + dynamicTask.startDelay(taskOverdueKey, () -> removeCatalogSubscribe(subscribeInfo.getId()),
  44 + subscribeInfo.getExpires() * 1000);
18 45 }
19 46  
20 47 public SubscribeInfo getCatalogSubscribe(String platformId) {
... ... @@ -23,10 +50,24 @@ public class SubscribeHolder {
23 50  
24 51 public void removeCatalogSubscribe(String platformId) {
25 52 catalogMap.remove(platformId);
  53 + String taskOverdueKey = taskOverduePrefix + "catalog_" + platformId;
  54 + // 添加任务处理订阅过期
  55 + dynamicTask.stop(taskOverdueKey);
26 56 }
27 57  
28 58 public void putMobilePositionSubscribe(String platformId, SubscribeInfo subscribeInfo) {
29 59 mobilePositionMap.put(platformId, subscribeInfo);
  60 + String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + "MobilePosition_" + platformId;
  61 + // 添加任务处理GPS定时推送
  62 + dynamicTask.startCron(key, new MobilePositionSubscribeHandlerTask(redisCatchStorage, sipCommanderForPlatform, storager, platformId, subscribeInfo.getSn(), key, this), subscribeInfo.getGpsInterval());
  63 + String taskOverdueKey = taskOverduePrefix + "MobilePosition_" + platformId;
  64 + dynamicTask.stop(taskOverdueKey);
  65 + // 添加任务处理订阅过期
  66 + dynamicTask.startDelay(taskOverdueKey, () -> {
  67 + System.out.println("订阅过期");
  68 + removeMobilePositionSubscribe(subscribeInfo.getId());
  69 + },
  70 + subscribeInfo.getExpires() * 1000);
30 71 }
31 72  
32 73 public SubscribeInfo getMobilePositionSubscribe(String platformId) {
... ... @@ -35,6 +76,12 @@ public class SubscribeHolder {
35 76  
36 77 public void removeMobilePositionSubscribe(String platformId) {
37 78 mobilePositionMap.remove(platformId);
  79 + String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + "MobilePosition_" + platformId;
  80 + // 结束任务处理GPS定时推送
  81 + dynamicTask.stop(key);
  82 + String taskOverdueKey = taskOverduePrefix + "MobilePosition_" + platformId;
  83 + // 添加任务处理订阅过期
  84 + dynamicTask.stop(taskOverdueKey);
38 85 }
39 86  
40 87 public List<String> getAllCatalogSubscribePlatform() {
... ... @@ -48,7 +95,7 @@ public class SubscribeHolder {
48 95 }
49 96  
50 97 public void removeAllSubscribe(String platformId) {
51   - mobilePositionMap.remove(platformId);
52   - catalogMap.remove(platformId);
  98 + removeMobilePositionSubscribe(platformId);
  99 + removeCatalogSubscribe(platformId);
53 100 }
54 101 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java
... ... @@ -33,6 +33,14 @@ public class SubscribeInfo {
33 33 private ServerTransaction transaction;
34 34 private Dialog dialog;
35 35  
  36 + /**
  37 + * 以下为可选字段
  38 + * @return
  39 + */
  40 + private String sn;
  41 + private int gpsInterval;
  42 +
  43 +
36 44 public String getId() {
37 45 return id;
38 46 }
... ... @@ -88,4 +96,20 @@ public class SubscribeInfo {
88 96 public void setDialog(Dialog dialog) {
89 97 this.dialog = dialog;
90 98 }
  99 +
  100 + public String getSn() {
  101 + return sn;
  102 + }
  103 +
  104 + public void setSn(String sn) {
  105 + this.sn = sn;
  106 + }
  107 +
  108 + public int getGpsInterval() {
  109 + return gpsInterval;
  110 + }
  111 +
  112 + public void setGpsInterval(int gpsInterval) {
  113 + this.gpsInterval = gpsInterval;
  114 + }
91 115 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/SubscribeListenerForPlatform.java deleted 100644 → 0
1   -package com.genersoft.iot.vmp.gb28181.event.subscribe;
2   -
3   -import com.genersoft.iot.vmp.common.VideoManagerConstants;
4   -import com.genersoft.iot.vmp.conf.DynamicTask;
5   -import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener;
6   -import com.genersoft.iot.vmp.conf.UserSetting;
7   -import org.slf4j.Logger;
8   -import org.slf4j.LoggerFactory;
9   -import org.springframework.beans.factory.annotation.Autowired;
10   -import org.springframework.data.redis.connection.Message;
11   -import org.springframework.data.redis.listener.RedisMessageListenerContainer;
12   -import org.springframework.stereotype.Component;
13   -
14   -/**
15   - * 平台订阅到期事件
16   - */
17   -@Component
18   -public class SubscribeListenerForPlatform extends RedisKeyExpirationEventMessageListener {
19   -
20   - private Logger logger = LoggerFactory.getLogger(SubscribeListenerForPlatform.class);
21   -
22   - @Autowired
23   - private UserSetting userSetting;
24   -
25   - @Autowired
26   - private DynamicTask dynamicTask;
27   -
28   - public SubscribeListenerForPlatform(RedisMessageListenerContainer listenerContainer, UserSetting userSetting) {
29   - super(listenerContainer, userSetting);
30   - }
31   -
32   -
33   - /**
34   - * 监听失效的key
35   - * @param message
36   - * @param pattern
37   - */
38   - @Override
39   - public void onMessage(Message message, byte[] pattern) {
40   - // 获取失效的key
41   - String expiredKey = message.toString();
42   - logger.debug(expiredKey);
43   - // 订阅到期
44   - String PLATFORM_KEEPLIVEKEY_PREFIX = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetting.getServerId() + "_";
45   - if (expiredKey.startsWith(PLATFORM_KEEPLIVEKEY_PREFIX)) {
46   - // 取消定时任务
47   - dynamicTask.stop(expiredKey);
48   - }
49   - }
50   -}
src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java
... ... @@ -61,8 +61,6 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; {
61 61 if (event.getPlatformId() != null) {
62 62 parentPlatform = storager.queryParentPlatByServerGBId(event.getPlatformId());
63 63 if (parentPlatform != null && !parentPlatform.isStatus())return;
64   - String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetting.getServerId() + "_Catalog_" + event.getPlatformId();
65   -// subscribe = redisCatchStorage.getSubscribe(key);
66 64 subscribe = subscribeHolder.getCatalogSubscribe(event.getPlatformId());
67 65  
68 66 if (subscribe == null) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/CatalogSubscribeTask.java
... ... @@ -46,7 +46,6 @@ public class CatalogSubscribeTask implements ISubscribeTask {
46 46 });
47 47 }
48 48  
49   - @Async
50 49 @Override
51 50 public void stop() {
52 51 /**
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java
... ... @@ -24,52 +24,50 @@ public class MobilePositionSubscribeHandlerTask implements ISubscribeTask {
24 24 private IVideoManagerStorage storager;
25 25 private ISIPCommanderForPlatform sipCommanderForPlatform;
26 26 private SubscribeHolder subscribeHolder;
27   - private String platformId;
  27 + private ParentPlatform platform;
28 28 private String sn;
29 29 private String key;
30 30  
31 31 public MobilePositionSubscribeHandlerTask(IRedisCatchStorage redisCatchStorage, ISIPCommanderForPlatform sipCommanderForPlatform, IVideoManagerStorage storager, String platformId, String sn, String key, SubscribeHolder subscribeInfo) {
  32 + System.out.println("MobilePositionSubscribeHandlerTask 初始化");
32 33 this.redisCatchStorage = redisCatchStorage;
33 34 this.storager = storager;
34   - this.platformId = platformId;
  35 + this.platform = storager.queryParentPlatByServerGBId(platformId);
35 36 this.sn = sn;
36 37 this.key = key;
37 38 this.sipCommanderForPlatform = sipCommanderForPlatform;
38 39 this.subscribeHolder = subscribeInfo;
39 40 }
40 41  
41   - @Async
42 42 @Override
43 43 public void run() {
44 44  
45 45 logger.info("执行MobilePositionSubscribeHandlerTask");
46   - SubscribeInfo subscribe = subscribeHolder.getMobilePositionSubscribe(platformId);
  46 + if (platform == null) return;
  47 + SubscribeInfo subscribe = subscribeHolder.getMobilePositionSubscribe(platform.getServerGBId());
47 48 if (subscribe != null) {
48   - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId);
49   - if (parentPlatform == null ) {
50   - logger.info("发送订阅时未找到平台信息:{}", platformId);
51   - return;
52   - }
53   - if (!parentPlatform.isStatus()) {
54   - logger.info("发送订阅时发现平台已经离线:{}", platformId);
55   - return;
56   - }
  49 +
  50 +// if (!parentPlatform.isStatus()) {
  51 +// logger.info("发送订阅时发现平台已经离线:{}", platformId);
  52 +// return;
  53 +// }
57 54 // TODO 暂时只处理视频流的回复,后续增加对国标设备的支持
58   - List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(platformId);
  55 + List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(platform.getServerGBId());
59 56 if (gbStreams.size() == 0) {
60   - logger.info("发送订阅时发现平台已经没有关联的直播流:{}", platformId);
  57 + logger.info("发送订阅时发现平台已经没有关联的直播流:{}", platform.getServerGBId());
61 58 return;
62 59 }
63 60 for (GbStream gbStream : gbStreams) {
64 61 String gbId = gbStream.getGbId();
65 62 GPSMsgInfo gpsMsgInfo = redisCatchStorage.getGpsMsgInfo(gbId);
66 63 if (gpsMsgInfo != null) { // 无最新位置不发送
  64 + logger.info("无最新位置不发送");
67 65 // 经纬度都为0不发送
68 66 if (gpsMsgInfo.getLng() == 0 && gpsMsgInfo.getLat() == 0) {
69 67 continue;
70 68 }
71 69 // 发送GPS消息
72   - sipCommanderForPlatform.sendNotifyMobilePosition(parentPlatform, gpsMsgInfo, subscribe);
  70 + sipCommanderForPlatform.sendNotifyMobilePosition(platform, gpsMsgInfo, subscribe);
73 71 }
74 72 }
75 73 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeTask.java
... ... @@ -11,6 +11,8 @@ import org.springframework.scheduling.annotation.Async;
11 11 import javax.sip.Dialog;
12 12 import javax.sip.DialogState;
13 13 import javax.sip.ResponseEvent;
  14 +import java.util.Timer;
  15 +import java.util.TimerTask;
14 16  
15 17 /**
16 18 * 移动位置订阅的定时更新
... ... @@ -21,18 +23,23 @@ public class MobilePositionSubscribeTask implements ISubscribeTask {
21 23 private ISIPCommander sipCommander;
22 24 private Dialog dialog;
23 25  
  26 + private Timer timer ;
  27 +
24 28 public MobilePositionSubscribeTask(Device device, ISIPCommander sipCommander) {
25 29 this.device = device;
26 30 this.sipCommander = sipCommander;
27 31 }
28 32  
29   - @Async
30 33 @Override
31 34 public void run() {
  35 + if (timer != null ) {
  36 + timer.cancel();
  37 + timer = null;
  38 + }
32 39 sipCommander.mobilePositionSubscribe(device, dialog, eventResult -> {
33   - if (eventResult.dialog != null || eventResult.dialog.getState().equals(DialogState.CONFIRMED)) {
34   - dialog = eventResult.dialog;
35   - }
  40 +// if (eventResult.dialog != null || eventResult.dialog.getState().equals(DialogState.CONFIRMED)) {
  41 +// dialog = eventResult.dialog;
  42 +// }
36 43 ResponseEvent event = (ResponseEvent) eventResult.event;
37 44 if (event.getResponse().getRawContent() != null) {
38 45 // 成功
... ... @@ -45,6 +52,13 @@ public class MobilePositionSubscribeTask implements ISubscribeTask {
45 52 dialog = null;
46 53 // 失败
47 54 logger.warn("[移动位置订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);
  55 + timer = new Timer();
  56 + timer.schedule(new TimerTask() {
  57 + @Override
  58 + public void run() {
  59 + MobilePositionSubscribeTask.this.run();
  60 + }
  61 + }, 2000);
48 62 });
49 63  
50 64 }
... ... @@ -58,6 +72,10 @@ public class MobilePositionSubscribeTask implements ISubscribeTask {
58 72 * COMPLETED-> Completed Dialog状态-已完成
59 73 * TERMINATED-> Terminated Dialog状态-终止
60 74 */
  75 + if (timer != null ) {
  76 + timer.cancel();
  77 + timer = null;
  78 + }
61 79 if (dialog != null && dialog.getState().equals(DialogState.CONFIRMED)) {
62 80 logger.info("取消移动订阅时dialog状态为{}", dialog.getState());
63 81 device.setSubscribeCycleForMobilePosition(0);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
... ... @@ -385,7 +385,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
385 385 if (parentPlatform == null) {
386 386 return false;
387 387 }
388   -
  388 + logger.info("[发送 移动位置订阅] {}/{}->{},{}", parentPlatform.getServerGBId(), gpsMsgInfo.getId(), gpsMsgInfo.getLng(), gpsMsgInfo.getLat());
389 389 try {
390 390 String characterSet = parentPlatform.getCharacterSet();
391 391 StringBuffer deviceStatusXml = new StringBuffer(600);
... ... @@ -405,7 +405,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
405 405 CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
406 406 : udpSipProvider.getNewCallId();
407 407 callIdHeader.setCallId(subscribeInfo.getCallId());
408   - logger.info("[发送 移动位置订阅] {}/{}->{},{}", parentPlatform.getServerGBId(), gpsMsgInfo.getId(), gpsMsgInfo.getLng(), gpsMsgInfo.getLat());
  408 +
409 409 sendNotify(parentPlatform, deviceStatusXml.toString(), subscribeInfo, eventResult -> {
410 410 logger.error("发送NOTIFY通知消息失败。错误:{} {}", eventResult.statusCode, eventResult.msg);
411 411 }, null);
... ... @@ -459,7 +459,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
459 459 // 设置编码, 防止中文乱码
460 460 messageFactory.setDefaultContentEncodingCharset(characterSet);
461 461 Dialog dialog = subscribeInfo.getDialog();
462   - if (dialog == null) return;
  462 + if (dialog == null || !dialog.getState().equals(DialogState.CONFIRMED)) return;
463 463 SIPRequest notifyRequest = (SIPRequest)dialog.createRequest(Request.NOTIFY);
464 464 ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
465 465 notifyRequest.setContent(catalogXmlContent, contentTypeHeader);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java
... ... @@ -149,7 +149,6 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
149 149 subscribeInfo.setDialog(dialog);
150 150 }
151 151 String sn = XmlUtil.getText(rootElement, "SN");
152   - String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetting.getServerId() + "_MobilePosition_" + platformId;
153 152 logger.info("[回复 移动位置订阅]: {}", platformId);
154 153 StringBuilder resultXml = new StringBuilder(200);
155 154 resultXml.append("<?xml version=\"1.0\" ?>\r\n")
... ... @@ -161,23 +160,25 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
161 160 .append("</Response>\r\n");
162 161  
163 162 if (subscribeInfo.getExpires() > 0) {
164   -
165   - if (subscribeHolder.getMobilePositionSubscribe(platformId) == null ) {
166   - String interval = XmlUtil.getText(rootElement, "Interval"); // GPS上报时间间隔
167   - subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo);
168   - dynamicTask.startCron(key, new MobilePositionSubscribeHandlerTask(redisCatchStorage, sipCommanderForPlatform, storager, platformId, sn, key, subscribeHolder), Integer.parseInt(interval));
  163 + String interval = XmlUtil.getText(rootElement, "Interval"); // GPS上报时间间隔
  164 + if (interval == null) {
  165 + subscribeInfo.setGpsInterval(5);
169 166 }else {
170   - if (subscribeHolder.getMobilePositionSubscribe(platformId).getDialog() != null
171   - && subscribeHolder.getMobilePositionSubscribe(platformId).getDialog().getState() != null
172   - && !subscribeHolder.getMobilePositionSubscribe(platformId).getDialog().getState().equals(DialogState.CONFIRMED)) {
173   - dynamicTask.stop(key);
174   - String interval = XmlUtil.getText(rootElement, "Interval"); // GPS上报时间间隔
175   - subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo);
176   - dynamicTask.startCron(key, new MobilePositionSubscribeHandlerTask(redisCatchStorage, sipCommanderForPlatform, storager, platformId, sn, key, subscribeHolder), Integer.parseInt(interval));
177   - }
  167 + subscribeInfo.setGpsInterval(Integer.parseInt(interval));
178 168 }
  169 +
  170 + subscribeInfo.setSn(sn);
  171 + subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo);
  172 +// if (subscribeHolder.getMobilePositionSubscribe(platformId) == null ) {
  173 +// subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo);
  174 +// }else {
  175 +// if (subscribeHolder.getMobilePositionSubscribe(platformId).getDialog() != null
  176 +// && subscribeHolder.getMobilePositionSubscribe(platformId).getDialog().getState() != null
  177 +// && !subscribeHolder.getMobilePositionSubscribe(platformId).getDialog().getState().equals(DialogState.CONFIRMED)) {
  178 +// subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo);
  179 +// }
  180 +// }
179 181 }else if (subscribeInfo.getExpires() == 0) {
180   - dynamicTask.stop(key);
181 182 subscribeHolder.removeMobilePositionSubscribe(platformId);
182 183 }
183 184  
... ... @@ -211,7 +212,6 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
211 212 subscribeInfo.setDialog(dialog);
212 213 }
213 214 String sn = XmlUtil.getText(rootElement, "SN");
214   - String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetting.getServerId() + "_Catalog_" + platformId;
215 215 logger.info("[回复 目录订阅]: {}/{}", platformId, deviceID);
216 216 StringBuilder resultXml = new StringBuilder(200);
217 217 resultXml.append("<?xml version=\"1.0\" ?>\r\n")
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
... ... @@ -145,9 +145,6 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
145 145 }
146 146 // 回复200 OK
147 147 responseAck(evt, Response.OK);
148   - if (offLineDetector.isOnline(device.getDeviceId())) {
149   - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
150   - }
151 148 }
152 149 } catch (DocumentException e) {
153 150 e.printStackTrace();
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
... ... @@ -14,6 +14,8 @@ import org.slf4j.LoggerFactory;
14 14 import org.springframework.beans.factory.annotation.Autowired;
15 15 import org.springframework.stereotype.Service;
16 16  
  17 +import javax.sip.DialogState;
  18 +
17 19 /**
18 20 * 设备业务(目录订阅)
19 21 */
... ... @@ -39,19 +41,17 @@ public class DeviceServiceImpl implements IDeviceService {
39 41 if (device == null || device.getSubscribeCycleForCatalog() < 0) {
40 42 return false;
41 43 }
42   - if (dynamicTask.contains(device.getDeviceId() + "catalog")) {
43   - // 存在则停止现有的,开启新的
44   - dynamicTask.stop(device.getDeviceId() + "catalog");
  44 + CatalogSubscribeTask task = (CatalogSubscribeTask)dynamicTask.get(device.getDeviceId() + "catalog");
  45 + if (task != null && task.getDialogState() != null && task.getDialogState().equals(DialogState.CONFIRMED)) { // 已存在不需要再次添加
  46 + return true;
45 47 }
46 48 logger.info("[添加目录订阅] 设备{}", device.getDeviceId());
47 49 // 添加目录订阅
48 50 CatalogSubscribeTask catalogSubscribeTask = new CatalogSubscribeTask(device, sipCommander);
49   - catalogSubscribeTask.run();
50 51 // 提前开始刷新订阅
51   - int subscribeCycleForCatalog = device.getSubscribeCycleForCatalog();
  52 + int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForCatalog(),30);
52 53 // 设置最小值为30
53   - subscribeCycleForCatalog = Math.max(subscribeCycleForCatalog, 30);
54   - dynamicTask.startCron(device.getDeviceId() + "catalog", catalogSubscribeTask, subscribeCycleForCatalog);
  54 + dynamicTask.startCron(device.getDeviceId() + "catalog", catalogSubscribeTask, subscribeCycleForCatalog -1);
55 55 return true;
56 56 }
57 57  
... ... @@ -70,18 +70,16 @@ public class DeviceServiceImpl implements IDeviceService {
70 70 if (device == null || device.getSubscribeCycleForMobilePosition() < 0) {
71 71 return false;
72 72 }
73   - if (dynamicTask.contains(device.getDeviceId() + "mobile_position")) {
74   - // 存在则停止现有的,开启新的
75   - dynamicTask.stop(device.getDeviceId() + "mobile_position");
76   - }
77 73 logger.info("[添加移动位置订阅] 设备{}", device.getDeviceId());
  74 + MobilePositionSubscribeTask task = (MobilePositionSubscribeTask)dynamicTask.get(device.getDeviceId() + "mobile_position");
  75 + if (task != null && task.getDialogState() != null && task.getDialogState().equals(DialogState.CONFIRMED)) { // 已存在不需要再次添加
  76 + return true;
  77 + }
78 78 // 添加目录订阅
79 79 MobilePositionSubscribeTask mobilePositionSubscribeTask = new MobilePositionSubscribeTask(device, sipCommander);
80   - mobilePositionSubscribeTask.run();
81 80 // 提前开始刷新订阅
82   - int subscribeCycleForCatalog = device.getSubscribeCycleForCatalog();
83 81 // 设置最小值为30
84   - subscribeCycleForCatalog = Math.max(subscribeCycleForCatalog, 30);
  82 + int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForMobilePosition(),30);
85 83 dynamicTask.startCron(device.getDeviceId() + "mobile_position" , mobilePositionSubscribeTask, subscribeCycleForCatalog -1 );
86 84 return true;
87 85 }
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
... ... @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
4 4 import com.alibaba.fastjson.JSONObject;
5 5 import com.genersoft.iot.vmp.VManageBootstrap;
6 6 import com.genersoft.iot.vmp.common.VersionPo;
  7 +import com.genersoft.iot.vmp.conf.DynamicTask;
7 8 import com.genersoft.iot.vmp.conf.SipConfig;
8 9 import com.genersoft.iot.vmp.conf.UserSetting;
9 10 import com.genersoft.iot.vmp.conf.VersionInfo;
... ... @@ -27,6 +28,7 @@ import javax.sip.ObjectInUseException;
27 28 import javax.sip.SipProvider;
28 29 import java.util.Iterator;
29 30 import java.util.List;
  31 +import java.util.Set;
30 32  
31 33 @SuppressWarnings("rawtypes")
32 34 @Api(tags = "服务控制")
... ... @@ -42,13 +44,16 @@ public class ServerController {
42 44 private IMediaServerService mediaServerService;
43 45  
44 46 @Autowired
45   - VersionInfo versionInfo;
  47 + private VersionInfo versionInfo;
46 48  
47 49 @Autowired
48   - SipConfig sipConfig;
  50 + private SipConfig sipConfig;
49 51  
50 52 @Autowired
51   - UserSetting userSetting;
  53 + private UserSetting userSetting;
  54 +
  55 + @Autowired
  56 + private DynamicTask dynamicTask;
52 57  
53 58 @Value("${server.port}")
54 59 private int serverPort;
... ... @@ -248,4 +253,35 @@ public class ServerController {
248 253 result.setData(jsonObject);
249 254 return result;
250 255 }
  256 +
  257 +// @ApiOperation("当前进行中的动态任务")
  258 +// @GetMapping(value = "/dynamicTask")
  259 +// @ResponseBody
  260 +// public WVPResult<JSONObject> getDynamicTask(){
  261 +// WVPResult<JSONObject> result = new WVPResult<>();
  262 +// result.setCode(0);
  263 +// result.setMsg("success");
  264 +//
  265 +// JSONObject jsonObject = new JSONObject();
  266 +//
  267 +// Set<String> allKeys = dynamicTask.getAllKeys();
  268 +// jsonObject.put("server.port", serverPort);
  269 +// if (StringUtils.isEmpty(type)) {
  270 +// jsonObject.put("sip", JSON.toJSON(sipConfig));
  271 +// jsonObject.put("base", JSON.toJSON(userSetting));
  272 +// }else {
  273 +// switch (type){
  274 +// case "sip":
  275 +// jsonObject.put("sip", sipConfig);
  276 +// break;
  277 +// case "base":
  278 +// jsonObject.put("base", userSetting);
  279 +// break;
  280 +// default:
  281 +// break;
  282 +// }
  283 +// }
  284 +// result.setData(jsonObject);
  285 +// return result;
  286 +// }
251 287 }
... ...