Commit f6893cf95b15531dfc45950fea7e780e045ba2ae

Authored by 648540858
1 parent c395cf42

优化设备在线状态

Showing 52 changed files with 571 additions and 802 deletions
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
... ... @@ -47,8 +47,6 @@ public class VideoManagerConstants {
47 47 public static final String PLATFORM_SEND_RTP_INFO_PREFIX = "VMP_PLATFORM_SEND_RTP_INFO_";
48 48  
49 49 public static final String EVENT_ONLINE_REGISTER = "1";
50   -
51   - public static final String EVENT_ONLINE_KEEPLIVE = "2";
52 50  
53 51 public static final String EVENT_ONLINE_MESSAGE = "3";
54 52  
... ...
src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java
... ... @@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.common.ApiSaveConstant;
4 4 import com.genersoft.iot.vmp.conf.security.SecurityUtils;
5 5 import com.genersoft.iot.vmp.service.ILogService;
6 6 import com.genersoft.iot.vmp.storager.dao.dto.LogDto;
  7 +import com.genersoft.iot.vmp.utils.DateUtil;
7 8 import org.apache.commons.lang3.StringUtils;
8 9 import org.slf4j.Logger;
9 10 import org.slf4j.LoggerFactory;
... ... @@ -16,7 +17,6 @@ import javax.servlet.annotation.WebFilter;
16 17 import javax.servlet.http.HttpServletRequest;
17 18 import javax.servlet.http.HttpServletResponse;
18 19 import java.io.IOException;
19   -import java.text.SimpleDateFormat;
20 20  
21 21 /**
22 22 * @author lin
... ... @@ -26,7 +26,6 @@ public class ApiAccessFilter extends OncePerRequestFilter {
26 26  
27 27 private final static Logger logger = LoggerFactory.getLogger(ApiAccessFilter.class);
28 28  
29   - private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
30 29  
31 30 @Autowired
32 31 private UserSetting userSetting;
... ... @@ -58,7 +57,7 @@ public class ApiAccessFilter extends OncePerRequestFilter {
58 57 logDto.setTiming(System.currentTimeMillis() - start);
59 58 logDto.setType(servletRequest.getMethod());
60 59 logDto.setUri(servletRequest.getRequestURI());
61   - logDto.setCreateTime(format.format(System.currentTimeMillis()));
  60 + logDto.setCreateTime(DateUtil.getNow());
62 61 logService.add(logDto);
63 62 // logger.warn("[Api Access] [{}] [{}] [{}] [{}] [{}] {}ms",
64 63 // uriName, servletRequest.getMethod(), servletRequest.getRequestURI(), servletRequest.getRemoteAddr(), HttpStatus.valueOf(servletResponse.getStatus()),
... ...
src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java
... ... @@ -43,27 +43,27 @@ public class DynamicTask {
43 43 * 循环执行的任务
44 44 * @param key 任务ID
45 45 * @param task 任务
46   - * @param cycleForCatalog 间隔
  46 + * @param cycleForCatalog 间隔 毫秒
47 47 * @return
48 48 */
49 49 public void startCron(String key, Runnable task, int cycleForCatalog) {
50 50 ScheduledFuture future = futureMap.get(key);
51 51 if (future != null) {
52 52 if (future.isCancelled()) {
53   - logger.info("任务【{}】已存在但是关闭状态!!!", key);
  53 + logger.debug("任务【{}】已存在但是关闭状态!!!", key);
54 54 } else {
55   - logger.info("任务【{}】已存在且已启动!!!", key);
  55 + logger.debug("任务【{}】已存在且已启动!!!", key);
56 56 return;
57 57 }
58 58 }
59 59 // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔
60   - future = threadPoolTaskScheduler.scheduleAtFixedRate(task, cycleForCatalog * 1000L);
  60 + future = threadPoolTaskScheduler.scheduleAtFixedRate(task, cycleForCatalog);
61 61 if (future != null){
62 62 futureMap.put(key, future);
63 63 runnableMap.put(key, task);
64   - logger.info("任务【{}】启动成功!!!", key);
  64 + logger.debug("任务【{}】启动成功!!!", key);
65 65 }else {
66   - logger.info("任务【{}】启动失败!!!", key);
  66 + logger.debug("任务【{}】启动失败!!!", key);
67 67 }
68 68 }
69 69  
... ... @@ -81,9 +81,9 @@ public class DynamicTask {
81 81 ScheduledFuture future = futureMap.get(key);
82 82 if (future != null) {
83 83 if (future.isCancelled()) {
84   - logger.info("任务【{}】已存在但是关闭状态!!!", key);
  84 + logger.debug("任务【{}】已存在但是关闭状态!!!", key);
85 85 } else {
86   - logger.info("任务【{}】已存在且已启动!!!", key);
  86 + logger.debug("任务【{}】已存在且已启动!!!", key);
87 87 return;
88 88 }
89 89 }
... ... @@ -92,9 +92,9 @@ public class DynamicTask {
92 92 if (future != null){
93 93 futureMap.put(key, future);
94 94 runnableMap.put(key, task);
95   - logger.info("任务【{}】启动成功!!!", key);
  95 + logger.debug("任务【{}】启动成功!!!", key);
96 96 }else {
97   - logger.info("任务【{}】启动失败!!!", key);
  97 + logger.debug("任务【{}】启动失败!!!", key);
98 98 }
99 99 }
100 100  
... ...
src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
1 1 package com.genersoft.iot.vmp.conf;
2 2  
3 3 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  4 +import com.genersoft.iot.vmp.utils.DateUtil;
4 5 import org.springframework.beans.factory.annotation.Value;
5 6 import org.springframework.context.annotation.Configuration;
6 7 import org.springframework.util.StringUtils;
7 8  
8   -import java.text.SimpleDateFormat;
9   -import java.util.Date;
10 9  
11 10 @Configuration("mediaConfig")
12 11 public class MediaConfig{
... ... @@ -206,9 +205,8 @@ public class MediaConfig{
206 205 mediaServerItem.setRecordAssistPort(recordAssistPort);
207 206 mediaServerItem.setHookAliveInterval(120);
208 207  
209   - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
210   - mediaServerItem.setCreateTime(format.format(System.currentTimeMillis()));
211   - mediaServerItem.setUpdateTime(format.format(System.currentTimeMillis()));
  208 + mediaServerItem.setCreateTime(DateUtil.getNow());
  209 + mediaServerItem.setUpdateTime(DateUtil.getNow());
212 210  
213 211 return mediaServerItem;
214 212 }
... ...
src/main/java/com/genersoft/iot/vmp/conf/ThreadPoolTaskConfig.java
... ... @@ -35,10 +35,11 @@ public class ThreadPoolTaskConfig {
35 35 * 允许线程空闲时间(单位:默认为秒)
36 36 */
37 37 private static final int keepAliveTime = 30;
  38 +
38 39 /**
39 40 * 缓冲队列大小
40 41 */
41   - private static final int queueCapacity = 500;
  42 + private static final int queueCapacity = 10000;
42 43 /**
43 44 * 线程池名前缀
44 45 */
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
... ... @@ -48,8 +48,15 @@ public class SipLayer{
48 48 Properties properties = new Properties();
49 49 properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
50 50 properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getMonitorIp());
  51 + /**
  52 + * 完整配置参考 gov.nist.javax.sip.SipStackImpl,需要下载源码
  53 + * gov/nist/javax/sip/SipStackImpl.class
  54 + */
51 55 properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true");
52 56 properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); // 接收所有notify请求,即使没有订阅
  57 + properties.setProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG", "true"); // 为_NULL _对话框传递_终止的_事件
  58 + properties.setProperty("gov.nist.javax.sip.RELEASE_REFERENCES_STRATEGY", "Normal"); // 会话清理策略
  59 + properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "10");
53 60 /**
54 61 * sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE =
55 62 * 0; public static final int TRACE_MESSAGES = 16; public static final int
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
... ... @@ -100,11 +100,6 @@ public class Device {
100 100 private String mediaServerId;
101 101  
102 102 /**
103   - * 首次注册
104   - */
105   - private boolean firsRegister;
106   -
107   - /**
108 103 * 字符集, 支持 UTF-8 与 GB2312
109 104 */
110 105 private String charset ;
... ... @@ -279,14 +274,6 @@ public class Device {
279 274 this.mediaServerId = mediaServerId;
280 275 }
281 276  
282   - public boolean isFirsRegister() {
283   - return firsRegister;
284   - }
285   -
286   - public void setFirsRegister(boolean firsRegister) {
287   - this.firsRegister = firsRegister;
288   - }
289   -
290 277 public String getCharset() {
291 278 return charset;
292 279 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java
1 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2  
3 3  
  4 +import com.genersoft.iot.vmp.utils.DateUtil;
4 5 import org.jetbrains.annotations.NotNull;
5 6  
6 7 import java.text.ParseException;
7   -import java.text.SimpleDateFormat;
8 8 import java.util.Date;
9 9  
10 10 /**
... ... @@ -116,10 +116,9 @@ public class RecordItem implements Comparable<RecordItem>{
116 116  
117 117 @Override
118 118 public int compareTo(@NotNull RecordItem recordItem) {
119   - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
120 119 try {
121   - Date startTime_now = sdf.parse(startTime);
122   - Date startTime_param = sdf.parse(recordItem.getStartTime());
  120 + Date startTime_now = DateUtil.format.parse(startTime);
  121 + Date startTime_param = DateUtil.format.parse(recordItem.getStartTime());
123 122 if (startTime_param.compareTo(startTime_now) > 0) {
124 123 return -1;
125 124 }else {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java
... ... @@ -61,7 +61,7 @@ public class SubscribeHolder {
61 61 // 添加任务处理GPS定时推送
62 62 dynamicTask.startCron(key, new MobilePositionSubscribeHandlerTask(redisCatchStorage, sipCommanderForPlatform,
63 63 storager, platformId, subscribeInfo.getSn(), key, this, dynamicTask),
64   - subscribeInfo.getGpsInterval());
  64 + subscribeInfo.getGpsInterval() * 1000);
65 65 String taskOverdueKey = taskOverduePrefix + "MobilePosition_" + platformId;
66 66 dynamicTask.stop(taskOverdueKey);
67 67 // 添加任务处理订阅过期
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
1 1 package com.genersoft.iot.vmp.gb28181.event;
2 2  
3 3 import com.genersoft.iot.vmp.gb28181.bean.*;
4   -import com.genersoft.iot.vmp.gb28181.event.offline.OfflineEvent;
  4 +import com.genersoft.iot.vmp.gb28181.event.device.RequestTimeoutEvent;
5 5 import com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire.PlatformKeepaliveExpireEvent;
6 6 import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformCycleRegisterEvent;
7 7 import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformNotRegisterEvent;
... ... @@ -11,12 +11,11 @@ import com.genersoft.iot.vmp.media.zlm.event.ZLMOfflineEvent;
11 11 import com.genersoft.iot.vmp.media.zlm.event.ZLMOnlineEvent;
12 12 import org.springframework.beans.factory.annotation.Autowired;
13 13 import org.springframework.context.ApplicationEventPublisher;
14   -import org.springframework.scheduling.annotation.Async;
15 14 import org.springframework.stereotype.Component;
16 15  
17 16 import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEvent;
18   -import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent;
19 17  
  18 +import javax.sip.TimeoutEvent;
20 19 import java.util.ArrayList;
21 20 import java.util.HashSet;
22 21 import java.util.List;
... ... @@ -32,28 +31,6 @@ public class EventPublisher {
32 31  
33 32 @Autowired
34 33 private ApplicationEventPublisher applicationEventPublisher;
35   -
36   - public void onlineEventPublish(Device device, String from, int expires) {
37   - OnlineEvent onEvent = new OnlineEvent(this);
38   - onEvent.setDevice(device);
39   - onEvent.setFrom(from);
40   - onEvent.setExpires(expires);
41   - applicationEventPublisher.publishEvent(onEvent);
42   - }
43   -
44   - public void onlineEventPublish(Device device, String from) {
45   - OnlineEvent onEvent = new OnlineEvent(this);
46   - onEvent.setDevice(device);
47   - onEvent.setFrom(from);
48   - applicationEventPublisher.publishEvent(onEvent);
49   - }
50   -
51   - public void outlineEventPublish(String deviceId, String from){
52   - OfflineEvent outEvent = new OfflineEvent(this);
53   - outEvent.setDeviceId(deviceId);
54   - outEvent.setFrom(from);
55   - applicationEventPublisher.publishEvent(outEvent);
56   - }
57 34  
58 35 /**
59 36 * 平台心跳到期事件
... ... @@ -115,6 +92,13 @@ public class EventPublisher {
115 92 }
116 93  
117 94  
  95 + public void requestTimeOut(TimeoutEvent timeoutEvent) {
  96 + RequestTimeoutEvent requestTimeoutEvent = new RequestTimeoutEvent(this);
  97 + requestTimeoutEvent.setTimeoutEvent(timeoutEvent);
  98 + applicationEventPublisher.publishEvent(requestTimeoutEvent);
  99 + }
  100 +
  101 +
118 102 /**
119 103 *
120 104 * @param platformId
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/device/RequestTimeoutEvent.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.event.device;
  2 +
  3 +import org.springframework.context.ApplicationEvent;
  4 +
  5 +import javax.sip.TimeoutEvent;
  6 +
  7 +/**
  8 + * @author lin
  9 + */
  10 +public class RequestTimeoutEvent extends ApplicationEvent {
  11 + public RequestTimeoutEvent(Object source) {
  12 + super(source);
  13 + }
  14 +
  15 +
  16 + private TimeoutEvent timeoutEvent;
  17 +
  18 + public TimeoutEvent getTimeoutEvent() {
  19 + return timeoutEvent;
  20 + }
  21 +
  22 + public void setTimeoutEvent(TimeoutEvent timeoutEvent) {
  23 + this.timeoutEvent = timeoutEvent;
  24 + }
  25 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/device/RequestTimeoutEventImpl.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.event.device;
  2 +
  3 +import com.genersoft.iot.vmp.gb28181.bean.Device;
  4 +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
  5 +import com.genersoft.iot.vmp.service.IDeviceService;
  6 +import org.springframework.beans.factory.annotation.Autowired;
  7 +import org.springframework.context.ApplicationListener;
  8 +import org.springframework.stereotype.Component;
  9 +
  10 +import javax.sip.ClientTransaction;
  11 +import javax.sip.address.SipURI;
  12 +import javax.sip.header.CallIdHeader;
  13 +import javax.sip.header.ToHeader;
  14 +import javax.sip.message.Request;
  15 +
  16 +/**
  17 + * @author lin
  18 + */
  19 +@Component
  20 +public class RequestTimeoutEventImpl implements ApplicationListener<RequestTimeoutEvent> {
  21 +
  22 + @Autowired
  23 + private IDeviceService deviceService;
  24 +
  25 + @Override
  26 + public void onApplicationEvent(RequestTimeoutEvent event) {
  27 + ClientTransaction clientTransaction = event.getTimeoutEvent().getClientTransaction();
  28 + if (clientTransaction != null) {
  29 + Request request = clientTransaction.getRequest();
  30 + if (request != null) {
  31 + String host = ((SipURI) request.getRequestURI()).getHost();
  32 + int port = ((SipURI) request.getRequestURI()).getPort();
  33 + Device device = deviceService.getDeviceByHostAndPort(host, port);
  34 + if (device == null) {
  35 + return;
  36 + }
  37 + deviceService.offline(device.getDeviceId());
  38 + }
  39 + }
  40 + }
  41 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java
... ... @@ -17,9 +17,8 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants;
17 17 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
18 18  
19 19 /**
20   - * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
21   - * @author: swwheihei
22   - * @date: 2020年5月6日 上午11:35:46
  20 + * 设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
  21 + * @author swwheihei
23 22 */
24 23 @Component
25 24 public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEventMessageListener {
... ... @@ -55,25 +54,18 @@ public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEvent
55 54 // 平台心跳到期,需要重发, 判断是否已经多次未收到心跳回复, 多次未收到,则重新发起注册, 注册尝试多次未得到回复,则认为平台离线
56 55 String PLATFORM_KEEPLIVEKEY_PREFIX = VideoManagerConstants.PLATFORM_KEEPALIVE_PREFIX + userSetting.getServerId() + "_";
57 56 String PLATFORM_REGISTER_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_PREFIX + userSetting.getServerId() + "_";
58   - String KEEPLIVEKEY_PREFIX = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_";
59 57 String REGISTER_INFO_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_";
60 58 if (expiredKey.startsWith(PLATFORM_KEEPLIVEKEY_PREFIX)) {
61   - String platformGBId = expiredKey.substring(PLATFORM_KEEPLIVEKEY_PREFIX.length(),expiredKey.length());
62   - ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGBId);
  59 + String platformGbId = expiredKey.substring(PLATFORM_KEEPLIVEKEY_PREFIX.length());
  60 + ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGbId);
63 61 if (platform != null) {
64   - publisher.platformKeepaliveExpireEventPublish(platformGBId);
  62 + publisher.platformKeepaliveExpireEventPublish(platformGbId);
65 63 }
66 64 }else if (expiredKey.startsWith(PLATFORM_REGISTER_PREFIX)) {
67   - String platformGBId = expiredKey.substring(PLATFORM_REGISTER_PREFIX.length(),expiredKey.length());
68   - ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGBId);
  65 + String platformGbId = expiredKey.substring(PLATFORM_REGISTER_PREFIX.length(),expiredKey.length());
  66 + ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGbId);
69 67 if (platform != null) {
70   - publisher.platformRegisterCycleEventPublish(platformGBId);
71   - }
72   - }else if (expiredKey.startsWith(KEEPLIVEKEY_PREFIX)){
73   - String deviceId = expiredKey.substring(KEEPLIVEKEY_PREFIX.length(),expiredKey.length());
74   - Device device = storager.queryVideoDevice(deviceId);
75   - if (device != null) {
76   - publisher.outlineEventPublish(deviceId, KEEPLIVEKEY_PREFIX);
  68 + publisher.platformRegisterCycleEventPublish(platformGbId);
77 69 }
78 70 }else if (expiredKey.startsWith(REGISTER_INFO_PREFIX)) {
79 71 String callId = expiredKey.substring(REGISTER_INFO_PREFIX.length());
... ... @@ -85,6 +77,5 @@ public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEvent
85 77 sipSubscribe.getErrorSubscribe(callId).response(eventResult);
86 78 }
87 79 }
88   -
89 80 }
90 81 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java deleted 100644 → 0
1   -package com.genersoft.iot.vmp.gb28181.event.offline;
2   -
3   -import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener;
4   -import com.genersoft.iot.vmp.conf.UserSetting;
5   -import org.slf4j.Logger;
6   -import org.slf4j.LoggerFactory;
7   -import org.springframework.beans.factory.annotation.Autowired;
8   -import org.springframework.data.redis.connection.Message;
9   -import org.springframework.data.redis.listener.RedisMessageListenerContainer;
10   -import org.springframework.stereotype.Component;
11   -
12   -import com.genersoft.iot.vmp.common.VideoManagerConstants;
13   -import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
14   -
15   -/**
16   - * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
17   - * @author: swwheihei
18   - * @date: 2020年5月6日 上午11:35:46
19   - */
20   -@Component
21   -public class KeepliveTimeoutListener extends RedisKeyExpirationEventMessageListener {
22   -
23   - private Logger logger = LoggerFactory.getLogger(KeepliveTimeoutListener.class);
24   -
25   - @Autowired
26   - private EventPublisher publisher;
27   -
28   - @Autowired
29   - private UserSetting userSetting;
30   -
31   - public KeepliveTimeoutListener(RedisMessageListenerContainer listenerContainer, UserSetting userSetting) {
32   - super(listenerContainer, userSetting);
33   - }
34   -
35   - @Override
36   - public void init() {
37   - if (!userSetting.getRedisConfig()) {
38   - // 配置springboot默认Config为空,即不让应用去修改redis的默认配置,因为Redis服务出于安全会禁用CONFIG命令给远程用户使用
39   - setKeyspaceNotificationsConfigParameter("");
40   - }
41   - super.init();
42   - }
43   -
44   -
45   - /**
46   - * 监听失效的key,key格式为keeplive_deviceId
47   - * @param message
48   - * @param pattern
49   - */
50   - @Override
51   - public void onMessage(Message message, byte[] pattern) {
52   - // 获取失效的key
53   - String expiredKey = message.toString();
54   - String KEEPLIVEKEY_PREFIX = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_";
55   - if(!expiredKey.startsWith(KEEPLIVEKEY_PREFIX)){
56   - logger.debug("收到redis过期监听,但开头不是"+KEEPLIVEKEY_PREFIX+",忽略");
57   - return;
58   - }
59   -
60   - String deviceId = expiredKey.substring(KEEPLIVEKEY_PREFIX.length(),expiredKey.length());
61   - publisher.outlineEventPublish(deviceId, VideoManagerConstants.EVENT_OUTLINE_TIMEOUT);
62   - }
63   -}
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java deleted 100644 → 0
1   -package com.genersoft.iot.vmp.gb28181.event.offline;
2   -
3   -import org.springframework.context.ApplicationEvent;
4   -
5   -/**
6   - * @description: 离线事件类
7   - * @author: swwheihei
8   - * @date: 2020年5月6日 上午11:33:13
9   - */
10   -public class OfflineEvent extends ApplicationEvent {
11   -
12   - /**
13   - *
14   - */
15   - private static final long serialVersionUID = 1L;
16   -
17   - public OfflineEvent(Object source) {
18   - super(source);
19   - }
20   -
21   - private String deviceId;
22   -
23   - private String from;
24   -
25   - public String getDeviceId() {
26   - return deviceId;
27   - }
28   -
29   - public void setDeviceId(String deviceId) {
30   - this.deviceId = deviceId;
31   - }
32   -
33   - public String getFrom() {
34   - return from;
35   - }
36   -
37   - public void setFrom(String from) {
38   - this.from = from;
39   - }
40   -}
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java deleted 100644 → 0
1   -package com.genersoft.iot.vmp.gb28181.event.offline;
2   -
3   -import com.genersoft.iot.vmp.conf.UserSetting;
4   -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
5   -import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
6   -import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
7   -import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
8   -import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
9   -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
10   -import com.genersoft.iot.vmp.service.IMediaServerService;
11   -import org.slf4j.Logger;
12   -import org.slf4j.LoggerFactory;
13   -import org.springframework.beans.factory.annotation.Autowired;
14   -import org.springframework.context.ApplicationListener;
15   -import org.springframework.stereotype.Component;
16   -
17   -import com.genersoft.iot.vmp.common.VideoManagerConstants;
18   -import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
19   -import com.genersoft.iot.vmp.utils.redis.RedisUtil;
20   -
21   -import java.util.List;
22   -
23   -/**
24   - * @description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源:
25   - * 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.RegisterRequestProcessor}
26   - * 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.event.offline.OfflineEventListener}
27   - * @author: swwheihei
28   - * @date: 2020年5月6日 下午1:51:23
29   - */
30   -@Component
31   -public class OfflineEventListener implements ApplicationListener<OfflineEvent> {
32   -
33   - private final static Logger logger = LoggerFactory.getLogger(OfflineEventListener.class);
34   -
35   - @Autowired
36   - private IVideoManagerStorage storager;
37   -
38   - @Autowired
39   - private VideoStreamSessionManager streamSession;
40   -
41   - @Autowired
42   - private RedisUtil redis;
43   -
44   - @Autowired
45   - private UserSetting userSetting;
46   -
47   - @Autowired
48   - private EventPublisher eventPublisher;
49   -
50   -
51   - @Autowired
52   - private IMediaServerService mediaServerService;
53   -
54   -
55   - @Autowired
56   - private ZLMRTPServerFactory zlmrtpServerFactory;
57   -
58   - @Override
59   - public void onApplicationEvent(OfflineEvent event) {
60   -
61   - logger.info("设备离线事件触发,deviceId:" + event.getDeviceId() + ",from:" + event.getFrom());
62   -
63   - String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + event.getDeviceId();
64   -
65   - switch (event.getFrom()) {
66   - // 心跳超时触发的离线事件,说明redis中已删除,无需处理
67   - case VideoManagerConstants.EVENT_OUTLINE_TIMEOUT:
68   - break;
69   - // 设备主动注销触发的离线事件,需要删除redis中的超时监听
70   - case VideoManagerConstants.EVENT_OUTLINE_UNREGISTER:
71   - redis.del(key);
72   - break;
73   - default:
74   - boolean exist = redis.hasKey(key);
75   - if (exist) {
76   - redis.del(key);
77   - }
78   - }
79   -
80   - List<DeviceChannel> deviceChannelList = storager.queryOnlineChannelsByDeviceId(event.getDeviceId());
81   - eventPublisher.catalogEventPublish(null, deviceChannelList, CatalogEvent.OFF);
82   - // 处理离线监听
83   - storager.outline(event.getDeviceId());
84   -
85   - // TODO 离线取消订阅
86   -
87   - // 离线释放所有ssrc
88   - List<SsrcTransaction> ssrcTransactions = streamSession.getSsrcTransactionForAll(event.getDeviceId(), null, null, null);
89   - if (ssrcTransactions != null && ssrcTransactions.size() > 0) {
90   - for (SsrcTransaction ssrcTransaction : ssrcTransactions) {
91   - mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc());
92   - mediaServerService.closeRTPServer(event.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
93   - streamSession.remove(event.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
94   - }
95   - }
96   -
97   - }
98   -}
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java deleted 100644 → 0
1   -package com.genersoft.iot.vmp.gb28181.event.online;
2   -
3   -import com.genersoft.iot.vmp.gb28181.bean.Device;
4   -import org.springframework.context.ApplicationEvent;
5   -
6   -/**
7   - * @description: 在线事件类
8   - * @author: swwheihei
9   - * @date: 2020年5月6日 上午11:32:56
10   - */
11   -public class OnlineEvent extends ApplicationEvent {
12   -
13   - /**
14   - *
15   - */
16   - private static final long serialVersionUID = 1L;
17   -
18   - public OnlineEvent(Object source) {
19   - super(source);
20   - }
21   -
22   - private Device device;
23   -
24   - private String from;
25   -
26   - private int expires;
27   -
28   - public Device getDevice() {
29   - return device;
30   - }
31   -
32   - public void setDevice(Device device) {
33   - this.device = device;
34   - }
35   -
36   - public String getFrom() {
37   - return from;
38   - }
39   -
40   - public void setFrom(String from) {
41   - this.from = from;
42   - }
43   -
44   - public int getExpires() {
45   - return expires;
46   - }
47   -
48   - public void setExpires(int expires) {
49   - this.expires = expires;
50   - }
51   -}
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java deleted 100644 → 0
1   -package com.genersoft.iot.vmp.gb28181.event.online;
2   -
3   -import com.genersoft.iot.vmp.conf.SipConfig;
4   -import com.genersoft.iot.vmp.conf.UserSetting;
5   -import com.genersoft.iot.vmp.gb28181.bean.Device;
6   -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
7   -import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
8   -import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
9   -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
10   -import com.genersoft.iot.vmp.service.IDeviceService;
11   -import org.slf4j.Logger;
12   -import org.slf4j.LoggerFactory;
13   -import org.springframework.beans.factory.annotation.Autowired;
14   -import org.springframework.context.ApplicationListener;
15   -import org.springframework.stereotype.Component;
16   -
17   -import com.genersoft.iot.vmp.common.VideoManagerConstants;
18   -import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
19   -import com.genersoft.iot.vmp.utils.redis.RedisUtil;
20   -
21   -import java.text.SimpleDateFormat;
22   -import java.util.List;
23   -
24   -/**
25   - * @description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源:
26   - * 1、设备主动注销,发送注销指令
27   - * 2、设备未知原因离线,心跳超时
28   - * @author: swwheihei
29   - * @date: 2020年5月6日 下午1:51:23
30   - */
31   -@Component
32   -public class OnlineEventListener implements ApplicationListener<OnlineEvent> {
33   -
34   - private final static Logger logger = LoggerFactory.getLogger(OnlineEventListener.class);
35   -
36   - @Autowired
37   - private IVideoManagerStorage storager;
38   -
39   - @Autowired
40   - private IDeviceService deviceService;
41   -
42   - @Autowired
43   - private RedisUtil redis;
44   -
45   - @Autowired
46   - private SipConfig sipConfig;
47   -
48   - @Autowired
49   - private UserSetting userSetting;
50   -
51   - @Autowired
52   - private EventPublisher eventPublisher;
53   -
54   - @Autowired
55   - private SIPCommander cmder;
56   -
57   -
58   - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
59   -
60   - @Override
61   - public void onApplicationEvent(OnlineEvent event) {
62   -
63   - logger.info("设备上线事件触发,deviceId:" + event.getDevice().getDeviceId() + ",from:" + event.getFrom());
64   - Device device = event.getDevice();
65   - if (device == null) {
66   - return;
67   - }
68   - String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + event.getDevice().getDeviceId();
69   - Device deviceInStore = storager.queryVideoDevice(device.getDeviceId());
70   - device.setOnline(1);
71   - switch (event.getFrom()) {
72   - // 注册时触发的在线事件,先在redis中增加超时超时监听
73   - case VideoManagerConstants.EVENT_ONLINE_REGISTER:
74   - // 超时时间
75   - redis.set(key, event.getDevice().getDeviceId(), sipConfig.getKeepaliveTimeOut());
76   - device.setRegisterTime(format.format(System.currentTimeMillis()));
77   - if (deviceInStore == null) { //第一次上线
78   - logger.info("[{}] 首次注册,查询设备信息以及通道信息", device.getDeviceId());
79   - cmder.deviceInfoQuery(device);
80   - deviceService.sync(device);
81   - }
82   - break;
83   - // 设备主动发送心跳触发的在线事件
84   - case VideoManagerConstants.EVENT_ONLINE_KEEPLIVE:
85   - boolean exist = redis.hasKey(key);
86   - // 先判断是否还存在,当设备先心跳超时后又发送心跳时,redis没有监听,需要增加
87   - if (!exist) {
88   - redis.set(key, event.getDevice().getDeviceId(), sipConfig.getKeepaliveTimeOut());
89   - } else {
90   - redis.expire(key, sipConfig.getKeepaliveTimeOut());
91   - }
92   - device.setKeepaliveTime(format.format(System.currentTimeMillis()));
93   - break;
94   - // 设备主动发送消息触发的在线事件
95   - case VideoManagerConstants.EVENT_ONLINE_MESSAGE:
96   -
97   - break;
98   - }
99   - // 处理上线监听
100   - storager.updateDevice(device);
101   - // 上线添加订阅
102   - if (device.getSubscribeCycleForCatalog() > 0) {
103   - // 查询在线设备那些开启了订阅,为设备开启定时的目录订阅
104   - deviceService.addCatalogSubscribe(device);
105   - }
106   - if (device.getSubscribeCycleForMobilePosition() > 0) {
107   - deviceService.addMobilePositionSubscribe(device);
108   - }
109   - }
110   -}
src/main/java/com/genersoft/iot/vmp/conf/runner/SipDeviceRunner.java renamed to src/main/java/com/genersoft/iot/vmp/gb28181/task/SipDeviceRunner.java
1   -package com.genersoft.iot.vmp.conf.runner;
  1 +package com.genersoft.iot.vmp.gb28181.task;
2 2  
3 3 import com.genersoft.iot.vmp.conf.UserSetting;
4 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
... ... @@ -10,11 +10,13 @@ import org.springframework.boot.CommandLineRunner;
10 10 import org.springframework.core.annotation.Order;
11 11 import org.springframework.stereotype.Component;
12 12  
  13 +import java.util.ArrayList;
13 14 import java.util.List;
14 15  
15 16  
16 17 /**
17 18 * 系统启动时控制设备
  19 + * @author lin
18 20 */
19 21 @Component
20 22 @Order(value=4)
... ... @@ -34,26 +36,16 @@ public class SipDeviceRunner implements CommandLineRunner {
34 36  
35 37 @Override
36 38 public void run(String... args) throws Exception {
37   - // 读取redis没有心跳信息的则设置为离线,等收到下次心跳设置为在线
38   - // 设置所有设备离线
39   - storager.outlineForAll();
40   - List<String> onlineForAll = redisCatchStorage.getOnlineForAll();
41   - for (String deviceId : onlineForAll) {
42   - storager.online(deviceId);
43   - Device device = redisCatchStorage.getDevice(deviceId);
44   - if (device != null ) {
45   - if (device.getSubscribeCycleForCatalog() > 0) {
46   - // 查询在线设备那些开启了订阅,为设备开启定时的目录订阅
47   - deviceService.addCatalogSubscribe(device);
48   - }
49   - if (device.getSubscribeCycleForMobilePosition() > 0) {
50   - deviceService.addMobilePositionSubscribe(device);
51   - }
  39 + List<Device> deviceList = deviceService.getAllOnlineDevice();
  40 +
  41 + for (Device device : deviceList) {
  42 + if (deviceService.expire(device)){
  43 + deviceService.offline(device.getDeviceId());
  44 + }else {
  45 + deviceService.online(device);
52 46 }
53 47 }
54 48 // 重置cseq计数
55 49 redisCatchStorage.resetAllCSEQ();
56   -
57   -
58 50 }
59 51 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit;
2 2  
  3 +import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
3 4 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
4 5 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
  6 +import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.RegisterRequestProcessor;
  7 +import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd.KeepaliveNotifyMessageHandler;
5 8 import com.genersoft.iot.vmp.gb28181.transmit.event.response.ISIPResponseProcessor;
6 9 import com.genersoft.iot.vmp.gb28181.transmit.event.timeout.ITimeoutProcessor;
7 10 import org.slf4j.Logger;
... ... @@ -11,10 +14,13 @@ import org.springframework.scheduling.annotation.Async;
11 14 import org.springframework.stereotype.Component;
12 15  
13 16 import javax.sip.*;
14   -import javax.sip.header.CSeqHeader;
15   -import javax.sip.header.CallIdHeader;
  17 +import javax.sip.address.SipURI;
  18 +import javax.sip.address.URI;
  19 +import javax.sip.header.*;
  20 +import javax.sip.message.Request;
16 21 import javax.sip.message.Response;
17 22 import java.util.Map;
  23 +import java.util.Objects;
18 24 import java.util.concurrent.ConcurrentHashMap;
19 25  
20 26 /**
... ... @@ -34,10 +40,11 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
34 40 @Autowired
35 41 private SipSubscribe sipSubscribe;
36 42  
  43 + @Autowired
  44 + private EventPublisher eventPublisher;
  45 +
  46 +
37 47  
38   -// @Autowired
39   -// @Qualifier(value = "taskExecutor")
40   -// private ThreadPoolTaskExecutor poolTaskExecutor;
41 48  
42 49 /**
43 50 * 添加 request订阅
... ... @@ -141,9 +148,32 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
141 148 */
142 149 @Override
143 150 public void processTimeout(TimeoutEvent timeoutEvent) {
144   - if(timeoutProcessor != null) {
145   - timeoutProcessor.process(timeoutEvent);
  151 + logger.info("[消息发送超时]");
  152 + ClientTransaction clientTransaction = timeoutEvent.getClientTransaction();
  153 + eventPublisher.requestTimeOut(timeoutEvent);
  154 + if (clientTransaction != null) {
  155 + Request request = clientTransaction.getRequest();
  156 + if (request != null) {
  157 + CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
  158 + if (callIdHeader != null) {
  159 + SipSubscribe.Event subscribe = sipSubscribe.getErrorSubscribe(callIdHeader.getCallId());
  160 + SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(timeoutEvent);
  161 + subscribe.response(eventResult);
  162 + sipSubscribe.removeErrorSubscribe(callIdHeader.getCallId());
  163 + }
  164 + }
146 165 }
  166 +
  167 +// Timeout timeout = timeoutEvent.getTimeout();
  168 +// ServerTransaction serverTransaction = timeoutEvent.getServerTransaction();
  169 +// if (serverTransaction != null) {
  170 +// Request request = serverTransaction.getRequest();
  171 +// URI requestURI = request.getRequestURI();
  172 +// Header header = request.getHeader(FromHeader.NAME);
  173 +// }
  174 +// if(timeoutProcessor != null) {
  175 +// timeoutProcessor.process(timeoutEvent);
  176 +// }
147 177 }
148 178  
149 179 @Override
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
... ... @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
10 10 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
11 11 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
12 12 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
13   -import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
  13 +import com.genersoft.iot.vmp.utils.DateUtil;
14 14 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
15 15 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
16 16 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
... ... @@ -27,7 +27,6 @@ import org.slf4j.Logger;
27 27 import org.slf4j.LoggerFactory;
28 28 import org.springframework.beans.factory.annotation.Autowired;
29 29 import org.springframework.beans.factory.annotation.Qualifier;
30   -import org.springframework.boot.SpringBootVersion;
31 30 import org.springframework.context.annotation.DependsOn;
32 31 import org.springframework.stereotype.Component;
33 32 import org.springframework.util.StringUtils;
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
... ... @@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.*;
4 4 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
5 5 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
6 6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider;
7   -import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
  7 +import com.genersoft.iot.vmp.utils.DateUtil;
8 8 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
9 9 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
10 10 import com.genersoft.iot.vmp.service.IMediaServerService;
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
... ... @@ -23,6 +23,7 @@ import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
23 23 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
24 24 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
25 25 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
  26 +import com.genersoft.iot.vmp.utils.DateUtil;
26 27 import com.genersoft.iot.vmp.utils.SerializeUtils;
27 28 import gov.nist.javax.sdp.TimeDescriptionImpl;
28 29 import gov.nist.javax.sdp.fields.TimeField;
... ... @@ -39,7 +40,6 @@ import javax.sip.header.CallIdHeader;
39 40 import javax.sip.message.Request;
40 41 import javax.sip.message.Response;
41 42 import java.text.ParseException;
42   -import java.text.SimpleDateFormat;
43 43 import java.util.Date;
44 44 import java.util.Vector;
45 45  
... ... @@ -335,9 +335,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
335 335 sendRtpItem.setStreamId(ssrcInfo.getStream());
336 336 // 写入redis, 超时时回复
337 337 redisCatchStorage.updateSendRTPSever(sendRtpItem);
338   - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
339   - playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, format.format(start),
340   - format.format(end), null, result -> {
  338 + playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.format.format(start),
  339 + DateUtil.format.format(end), null, result -> {
341 340 if (result.getCode() != 0){
342 341 logger.warn("录像回放失败");
343 342 if (result.getEvent() != null) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java
... ... @@ -252,14 +252,12 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
252 252 FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
253 253 String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader);
254 254  
255   - Element rootElement = getRootElement(evt);
256 255 Device device = redisCatchStorage.getDevice(deviceId);
257   - if (device == null) {
  256 + if (device == null || device.getOnline() == 0) {
  257 + logger.warn("[收到 目录订阅]:{}, 但是设备已经离线", (device != null ? device.getDeviceId():"" ));
258 258 return;
259 259 }
260   - if (device != null ) {
261   - rootElement = getRootElement(evt, device.getCharset());
262   - }
  260 + Element rootElement = getRootElement(evt, device.getCharset());
263 261 Element deviceListElement = rootElement.element("DeviceList");
264 262 if (deviceListElement == null) {
265 263 return;
... ... @@ -279,39 +277,46 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
279 277 channel.setDeviceId(device.getDeviceId());
280 278 logger.info("[收到 目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId());
281 279 switch (eventElement.getText().toUpperCase()) {
282   - case CatalogEvent.ON: // 上线
  280 + case CatalogEvent.ON:
  281 + // 上线
283 282 logger.info("收到来自设备【{}】的通道【{}】上线通知", device.getDeviceId(), channel.getChannelId());
284 283 storager.deviceChannelOnline(deviceId, channel.getChannelId());
285 284 // 回复200 OK
286 285 responseAck(evt, Response.OK);
287 286 break;
288   - case CatalogEvent.OFF : // 离线
  287 + case CatalogEvent.OFF :
  288 + // 离线
289 289 logger.info("收到来自设备【{}】的通道【{}】离线通知", device.getDeviceId(), channel.getChannelId());
290 290 storager.deviceChannelOffline(deviceId, channel.getChannelId());
291 291 // 回复200 OK
292 292 responseAck(evt, Response.OK);
293 293 break;
294   - case CatalogEvent.VLOST: // 视频丢失
  294 + case CatalogEvent.VLOST:
  295 + // 视频丢失
295 296 logger.info("收到来自设备【{}】的通道【{}】视频丢失通知", device.getDeviceId(), channel.getChannelId());
296 297 storager.deviceChannelOffline(deviceId, channel.getChannelId());
297 298 // 回复200 OK
298 299 responseAck(evt, Response.OK);
299 300 break;
300   - case CatalogEvent.DEFECT: // 故障
  301 + case CatalogEvent.DEFECT:
  302 + // 故障
301 303 // 回复200 OK
302 304 responseAck(evt, Response.OK);
303 305 break;
304   - case CatalogEvent.ADD: // 增加
  306 + case CatalogEvent.ADD:
  307 + // 增加
305 308 logger.info("收到来自设备【{}】的增加通道【{}】通知", device.getDeviceId(), channel.getChannelId());
306 309 storager.updateChannel(deviceId, channel);
307 310 responseAck(evt, Response.OK);
308 311 break;
309   - case CatalogEvent.DEL: // 删除
  312 + case CatalogEvent.DEL:
  313 + // 删除
310 314 logger.info("收到来自设备【{}】的删除通道【{}】通知", device.getDeviceId(), channel.getChannelId());
311 315 storager.delChannel(deviceId, channel.getChannelId());
312 316 responseAck(evt, Response.OK);
313 317 break;
314   - case CatalogEvent.UPDATE: // 更新
  318 + case CatalogEvent.UPDATE:
  319 + // 更新
315 320 logger.info("收到来自设备【{}】的更新通道【{}】通知", device.getDeviceId(), channel.getChannelId());
316 321 storager.updateChannel(deviceId, channel);
317 322 responseAck(evt, Response.OK);
... ... @@ -324,10 +329,6 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
324 329 eventPublisher.catalogEventPublish(null, channel, eventElement.getText().toUpperCase());
325 330  
326 331 }
327   -
328   - if (!redisCatchStorage.deviceIsOnline(deviceId)) {
329   - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
330   - }
331 332 }
332 333 } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
333 334 e.printStackTrace();
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
... ... @@ -9,6 +9,7 @@ import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
9 9 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
10 10 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
11 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
  12 +import com.genersoft.iot.vmp.service.IDeviceService;
12 13 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
13 14 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
14 15 import gov.nist.javax.sip.RequestEventExt;
... ... @@ -60,6 +61,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
60 61 @Autowired
61 62 private SIPProcessorObserver sipProcessorObserver;
62 63  
  64 + @Autowired
  65 + private IDeviceService deviceService;
  66 +
63 67 @Override
64 68 public void afterPropertiesSet() throws Exception {
65 69 // 添加消息处理的订阅
... ... @@ -82,7 +86,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
82 86 Response response = null;
83 87 boolean passwordCorrect = false;
84 88 // 注册标志 0:未携带授权头或者密码错误 1:注册成功 2:注销成功
85   - int registerFlag = 0;
  89 + boolean registerFlag = false;
86 90 FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME);
87 91 AddressImpl address = (AddressImpl) fromHeader.getAddress();
88 92 SipUri uri = (SipUri) address.getURI();
... ... @@ -111,12 +115,8 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
111 115 return;
112 116 }
113 117  
114   - Device deviceInRedis = redisCatchStorage.getDevice(deviceId);
115   - Device device = storager.queryVideoDevice(deviceId);
116   - if (deviceInRedis != null && device == null) {
117   - // redis 存在脏数据
118   - redisCatchStorage.clearCatchByDeviceId(deviceId);
119   - }
  118 + Device device = deviceService.queryDevice(deviceId);
  119 +
120 120 // 携带授权头并且密码正确
121 121 response = getMessageFactory().createResponse(Response.OK, request);
122 122 // 添加date头
... ... @@ -154,20 +154,17 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
154 154 device.setStreamMode("UDP");
155 155 device.setCharset("GB2312");
156 156 device.setDeviceId(deviceId);
157   - device.setFirsRegister(true);
158   - } else {
159   - device.setFirsRegister(device.getOnline() == 0);
160 157 }
161 158 device.setIp(received);
162 159 device.setPort(rPort);
163 160 device.setHostAddress(received.concat(":").concat(String.valueOf(rPort)));
164 161 if (expiresHeader.getExpires() == 0) {
165 162 // 注销成功
166   - registerFlag = 2;
  163 + registerFlag = false;
167 164 } else {
168 165 // 注册成功
169 166 device.setExpires(expiresHeader.getExpires());
170   - registerFlag = 1;
  167 + registerFlag = true;
171 168 // 判断TCP还是UDP
172 169 ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
173 170 String transport = reqViaHeader.getTransport();
... ... @@ -177,12 +174,12 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
177 174 sendResponse(evt, response);
178 175 // 注册成功
179 176 // 保存到redis
180   - if (registerFlag == 1) {
  177 + if (registerFlag) {
181 178 logger.info("[{}] 注册成功! deviceId:" + deviceId, requestAddress);
182   - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_REGISTER, expiresHeader.getExpires());
183   - } else if (registerFlag == 2) {
  179 + deviceService.online(device);
  180 + } else {
184 181 logger.info("[{}] 注销成功! deviceId:" + deviceId, requestAddress);
185   - publisher.outlineEventPublish(deviceId, VideoManagerConstants.EVENT_OUTLINE_UNREGISTER);
  182 + deviceService.offline(deviceId);
186 183 }
187 184 } catch (SipException | InvalidArgumentException | NoSuchAlgorithmException | ParseException e) {
188 185 e.printStackTrace();
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
2 2  
3   -import com.genersoft.iot.vmp.common.VideoManagerConstants;
4 3 import com.genersoft.iot.vmp.gb28181.bean.Device;
5 4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
6 5 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
7 6 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
8 7 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
9 8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
  9 +import com.genersoft.iot.vmp.service.IDeviceService;
10 10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 11 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
  12 +import com.genersoft.iot.vmp.utils.DateUtil;
12 13 import org.dom4j.Element;
13 14 import org.slf4j.Logger;
14 15 import org.slf4j.LoggerFactory;
... ... @@ -23,24 +24,20 @@ import javax.sip.SipException;
23 24 import javax.sip.header.ViaHeader;
24 25 import javax.sip.message.Response;
25 26 import java.text.ParseException;
  27 +import java.util.Calendar;
  28 +import java.util.Date;
26 29  
27 30 @Component
28 31 public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
29 32  
30 33 private Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class);
31   - private final String cmdType = "Keepalive";
  34 + private final static String cmdType = "Keepalive";
32 35  
33 36 @Autowired
34 37 private NotifyMessageHandler notifyMessageHandler;
35 38  
36 39 @Autowired
37   - private EventPublisher publisher;
38   -
39   - @Autowired
40   - private IVideoManagerStorage videoManagerStorager;
41   -
42   - @Autowired
43   - private IRedisCatchStorage redisCatchStorage;
  40 + private IDeviceService deviceService;
44 41  
45 42 @Override
46 43 public void afterPropertiesSet() throws Exception {
... ... @@ -49,29 +46,35 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
49 46  
50 47 @Override
51 48 public void handForDevice(RequestEvent evt, Device device, Element element) {
52   - // 检查设备是否存在并在线, 不在线则设置为在线
  49 + if (device == null) {
  50 + // 未注册的设备不做处理
  51 + return;
  52 + }
53 53 try {
54   - if (device != null ) {
  54 + if (device.getOnline() == 1) {
55 55 // 回复200 OK
56 56 responseAck(evt, Response.OK);
57   - // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息
58   - // 获取到通信地址等信息
59   - ViaHeader viaHeader = (ViaHeader) evt.getRequest().getHeader(ViaHeader.NAME);
60   - String received = viaHeader.getReceived();
61   - int rPort = viaHeader.getRPort();
62   - // 解析本地地址替代
63   - if (StringUtils.isEmpty(received) || rPort == -1) {
64   - received = viaHeader.getHost();
65   - rPort = viaHeader.getPort();
66   - }
67   - if (device.getPort() != rPort) {
68   - device.setPort(rPort);
69   - device.setHostAddress(received.concat(":").concat(String.valueOf(rPort)));
70   - videoManagerStorager.updateDevice(device);
71   - redisCatchStorage.updateDevice(device);
72   - }
73   - if (!redisCatchStorage.deviceIsOnline(device.getDeviceId())) {
74   - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
  57 + }else {
  58 + // 对于已经离线的设备判断他的注册是否已经过期
  59 + if (!deviceService.expire(device)){
  60 + device.setKeepaliveTime(DateUtil.getNow());
  61 + // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息
  62 + // 获取到通信地址等信息
  63 + ViaHeader viaHeader = (ViaHeader) evt.getRequest().getHeader(ViaHeader.NAME);
  64 + String received = viaHeader.getReceived();
  65 + int rPort = viaHeader.getRPort();
  66 + // 解析本地地址替代
  67 + if (StringUtils.isEmpty(received) || rPort == -1) {
  68 + received = viaHeader.getHost();
  69 + rPort = viaHeader.getPort();
  70 + }
  71 + if (device.getPort() != rPort) {
  72 + device.setPort(rPort);
  73 + device.setHostAddress(received.concat(":").concat(String.valueOf(rPort)));
  74 + }
  75 + deviceService.online(device);
  76 + // 回复200 OK
  77 + responseAck(evt, Response.OK);
75 78 }
76 79 }
77 80 } catch (SipException e) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/RecordInfoQueryMessageHandler.java
... ... @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
9 9 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
10 10 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
11 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.QueryMessageHandler;
12   -import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
  12 +import com.genersoft.iot.vmp.utils.DateUtil;
13 13 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
14 14 import com.genersoft.iot.vmp.storager.dao.dto.ChannelSourceInfo;
15 15 import org.dom4j.Element;
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
... ... @@ -28,7 +28,6 @@ import javax.sip.RequestEvent;
28 28 import javax.sip.SipException;
29 29 import javax.sip.message.Response;
30 30 import java.text.ParseException;
31   -import java.text.SimpleDateFormat;
32 31 import java.util.ArrayList;
33 32 import java.util.Iterator;
34 33 import java.util.List;
... ... @@ -39,8 +38,6 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
39 38 private Logger logger = LoggerFactory.getLogger(CatalogResponseMessageHandler.class);
40 39 private final String cmdType = "Catalog";
41 40  
42   - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
43   -
44 41 @Autowired
45 42 private ResponseMessageHandler responseMessageHandler;
46 43  
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceInfoResponseMessageHandler.java
... ... @@ -29,6 +29,9 @@ import java.text.ParseException;
29 29  
30 30 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
31 31  
  32 +/**
  33 + * @author lin
  34 + */
32 35 @Component
33 36 public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
34 37  
... ... @@ -61,6 +64,11 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent
61 64 @Override
62 65 public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
63 66 logger.debug("接收到DeviceInfo应答消息");
  67 + // 检查设备是否存在, 不存在则不回复
  68 + if (device == null || device.getOnline() == 0) {
  69 + logger.warn("[接收到DeviceInfo应答消息,但是设备已经离线]:" + (device != null ? device.getDeviceId():"" ));
  70 + return;
  71 + }
64 72 try {
65 73 rootElement = getRootElement(evt, device.getCharset());
66 74 Element deviceIdElement = rootElement.element("DeviceID");
... ... @@ -82,9 +90,6 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent
82 90 deferredResultHolder.invokeAllResult(msg);
83 91 // 回复200 OK
84 92 responseAck(evt, Response.OK);
85   - if (redisCatchStorage.deviceIsOnline(device.getDeviceId())) {
86   - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
87   - }
88 93 } catch (DocumentException e) {
89 94 e.printStackTrace();
90 95 } catch (InvalidArgumentException e) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceStatusResponseMessageHandler.java
... ... @@ -11,6 +11,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorP
11 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
12 12 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
13 13 import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
  14 +import com.genersoft.iot.vmp.service.IDeviceService;
14 15 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
15 16 import org.dom4j.Element;
16 17 import org.slf4j.Logger;
... ... @@ -24,6 +25,7 @@ import javax.sip.RequestEvent;
24 25 import javax.sip.SipException;
25 26 import javax.sip.message.Response;
26 27 import java.text.ParseException;
  28 +import java.util.Objects;
27 29  
28 30 @Component
29 31 public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
... ... @@ -34,12 +36,11 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen
34 36 @Autowired
35 37 private ResponseMessageHandler responseMessageHandler;
36 38  
37   -
38 39 @Autowired
39 40 private DeferredResultHolder deferredResultHolder;
40 41  
41 42 @Autowired
42   - private EventPublisher publisher;
  43 + private IDeviceService deviceService;
43 44  
44 45 @Autowired
45 46 private IRedisCatchStorage redisCatchStorage;
... ... @@ -53,6 +54,9 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen
53 54 public void handForDevice(RequestEvent evt, Device device, Element element) {
54 55 logger.info("接收到DeviceStatus应答消息");
55 56 // 检查设备是否存在, 不存在则不回复
  57 + if (device == null) {
  58 + return;
  59 + }
56 60 // 回复200 OK
57 61 try {
58 62 responseAck(evt, Response.OK);
... ... @@ -64,20 +68,23 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen
64 68 e.printStackTrace();
65 69 }
66 70 Element deviceIdElement = element.element("DeviceID");
  71 + Element onlineElement = element.element("Online");
67 72 String channelId = deviceIdElement.getText();
68 73 JSONObject json = new JSONObject();
69 74 XmlUtil.node2Json(element, json);
70 75 if (logger.isDebugEnabled()) {
71 76 logger.debug(json.toJSONString());
72 77 }
  78 + String text = onlineElement.getText();
  79 + if (Objects.equals(text.trim().toUpperCase(), "ONLINE")) {
  80 + deviceService.online(device);
  81 + }else {
  82 + deviceService.offline(device.getDeviceId());
  83 + }
73 84 RequestMessage msg = new RequestMessage();
74 85 msg.setKey(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + device.getDeviceId() + channelId);
75 86 msg.setData(json);
76 87 deferredResultHolder.invokeAllResult(msg);
77   -
78   - if (redisCatchStorage.deviceIsOnline(device.getDeviceId())) {
79   - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
80   - }
81 88 }
82 89  
83 90 @Override
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java
... ... @@ -20,7 +20,6 @@ import javax.sip.RequestEvent;
20 20 import javax.sip.SipException;
21 21 import javax.sip.message.Response;
22 22 import java.text.ParseException;
23   -import java.text.SimpleDateFormat;
24 23 import java.util.ArrayList;
25 24 import java.util.Iterator;
26 25 import java.util.List;
... ... @@ -33,8 +32,6 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent
33 32 private Logger logger = LoggerFactory.getLogger(PresetQueryResponseMessageHandler.class);
34 33 private final String cmdType = "PresetQuery";
35 34  
36   - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
37   -
38 35 @Autowired
39 36 private ResponseMessageHandler responseMessageHandler;
40 37  
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java
... ... @@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
11 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
12 12 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
13 13 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
14   -import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
  14 +import com.genersoft.iot.vmp.utils.DateUtil;
15 15 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
16 16 import org.dom4j.DocumentException;
17 17 import org.dom4j.Element;
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
... ... @@ -55,9 +55,6 @@ public class ZLMRunner implements CommandLineRunner {
55 55 @Autowired
56 56 private DynamicTask dynamicTask;
57 57  
58   - @Qualifier("taskExecutor")
59   - @Autowired
60   - private ThreadPoolTaskExecutor taskExecutor;
61 58  
62 59 @Override
63 60 public void run(String... strings) throws Exception {
... ... @@ -105,9 +102,7 @@ public class ZLMRunner implements CommandLineRunner {
105 102 startGetMedia = new HashMap<>();
106 103 }
107 104 startGetMedia.put(mediaServerItem.getId(), true);
108   - taskExecutor.execute(()->{
109   - connectZlmServer(mediaServerItem);
110   - });
  105 + connectZlmServer(mediaServerItem);
111 106 }
112 107 String taskKey = "zlm-connect-timeout";
113 108 dynamicTask.startDelay(taskKey, ()->{
... ... @@ -119,21 +114,37 @@ public class ZLMRunner implements CommandLineRunner {
119 114 startGetMedia = null;
120 115 }
121 116 // TODO 清理数据库中与redis不匹配的zlm
122   - }, 6 * 1000 );
  117 + }, 60 * 1000 );
123 118 }
124 119  
125 120 @Async
126 121 public void connectZlmServer(MediaServerItem mediaServerItem){
127   - ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem, 1);
128   - if (zlmServerConfig != null) {
129   - zlmServerConfig.setIp(mediaServerItem.getIp());
130   - zlmServerConfig.setHttpPort(mediaServerItem.getHttpPort());
  122 + String connectZlmServerTaskKey = "connect-zlm-" + mediaServerItem.getId();
  123 + ZLMServerConfig zlmServerConfigFirst = getMediaServerConfig(mediaServerItem);
  124 + if (zlmServerConfigFirst != null) {
  125 + zlmServerConfigFirst.setIp(mediaServerItem.getIp());
  126 + zlmServerConfigFirst.setHttpPort(mediaServerItem.getHttpPort());
131 127 startGetMedia.remove(mediaServerItem.getId());
132   - mediaServerService.zlmServerOnline(zlmServerConfig);
  128 + mediaServerService.zlmServerOnline(zlmServerConfigFirst);
  129 + }else {
  130 + logger.info("[ {} ]-[ {}:{} ]主动连接失败, 清理相关资源, 开始尝试重试连接",
  131 + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
  132 + publisher.zlmOfflineEventPublish(mediaServerItem.getId());
133 133 }
  134 +
  135 + dynamicTask.startCron(connectZlmServerTaskKey, ()->{
  136 + ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem);
  137 + if (zlmServerConfig != null) {
  138 + dynamicTask.stop(connectZlmServerTaskKey);
  139 + zlmServerConfig.setIp(mediaServerItem.getIp());
  140 + zlmServerConfig.setHttpPort(mediaServerItem.getHttpPort());
  141 + startGetMedia.remove(mediaServerItem.getId());
  142 + mediaServerService.zlmServerOnline(zlmServerConfig);
  143 + }
  144 + }, 2000);
134 145 }
135 146  
136   - public ZLMServerConfig getMediaServerConfig(MediaServerItem mediaServerItem, int index) {
  147 + public ZLMServerConfig getMediaServerConfig(MediaServerItem mediaServerItem) {
137 148 if (startGetMedia == null) { return null;}
138 149 if (!mediaServerItem.isDefaultServer() && mediaServerService.getOne(mediaServerItem.getId()) == null) {
139 150 return null;
... ... @@ -149,53 +160,10 @@ public class ZLMRunner implements CommandLineRunner {
149 160 zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class);
150 161 }
151 162 } else {
152   - logger.error("[ {} ]-[ {}:{} ]第{}次主动连接失败, 2s后重试",
153   - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort(), index);
154   - if (index == 1 && !StringUtils.isEmpty(mediaServerItem.getId())) {
155   - logger.info("[ {} ]-[ {}:{} ]第{}次主动连接失败, 开始清理相关资源",
156   - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort(), index);
157   - publisher.zlmOfflineEventPublish(mediaServerItem.getId());
158   - }
159   - try {
160   - Thread.sleep(2000);
161   - } catch (InterruptedException e) {
162   - e.printStackTrace();
163   - }
164   - zlmServerConfig = getMediaServerConfig(mediaServerItem, index += 1);
  163 + logger.error("[ {} ]-[ {}:{} ]主动连接失败, 2s后重试",
  164 + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
165 165 }
166 166 return zlmServerConfig;
167 167  
168 168 }
169   -
170   - /**
171   - * zlm 连接成功或者zlm重启后
172   - */
173   -// private void zLmRunning(ZLMServerConfig zlmServerConfig){
174   -// logger.info( "[ id: " + zlmServerConfig.getGeneralMediaServerId() + "] zlm接入成功...");
175   -// // 关闭循环获取zlm配置
176   -// startGetMedia = false;
177   -// MediaServerItem mediaServerItem = new MediaServerItem(zlmServerConfig, sipIp);
178   -// storager.updateMediaServer(mediaServerItem);
179   -//
180   -// if (mediaServerItem.isAutoConfig()) setZLMConfig(mediaServerItem);
181   -// zlmServerManger.updateServerCatchFromHook(zlmServerConfig);
182   -//
183   -// // 清空所有session
184   -//// zlmMediaListManager.clearAllSessions();
185   -//
186   -// // 更新流列表
187   -// zlmMediaListManager.updateMediaList(mediaServerItem);
188   -// // 恢复流代理, 只查找这个这个流媒体
189   -// List<StreamProxyItem> streamProxyListForEnable = storager.getStreamProxyListForEnableInMediaServer(
190   -// mediaServerItem.getId(), true);
191   -// for (StreamProxyItem streamProxyDto : streamProxyListForEnable) {
192   -// logger.info("恢复流代理," + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
193   -// JSONObject jsonObject = streamProxyService.addStreamProxyToZlm(streamProxyDto);
194   -// if (jsonObject == null) {
195   -// // 设置为未启用
196   -// logger.info("恢复流代理失败,请检查流地址后重新启用" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
197   -// streamProxyService.stop(streamProxyDto.getApp(), streamProxyDto.getStream());
198   -// }
199   -// }
200   -// }
201 169 }
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMStatusEventListener.java
... ... @@ -7,12 +7,10 @@ import com.genersoft.iot.vmp.service.IStreamPushService;
7 7 import org.slf4j.Logger;
8 8 import org.slf4j.LoggerFactory;
9 9 import org.springframework.beans.factory.annotation.Autowired;
10   -import org.springframework.context.ApplicationListener;
11 10 import org.springframework.context.event.EventListener;
12 11 import org.springframework.scheduling.annotation.Async;
13 12 import org.springframework.stereotype.Component;
14 13  
15   -import java.text.SimpleDateFormat;
16 14  
17 15 /**
18 16 * @description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源:
... ... @@ -38,13 +36,11 @@ public class ZLMStatusEventListener {
38 36 @Autowired
39 37 private IPlayService playService;
40 38  
41   - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
42   -
43 39 @Async
44 40 @EventListener
45 41 public void onApplicationEvent(ZLMOnlineEvent event) {
46 42  
47   - logger.info("ZLM上线事件触发,ID:" + event.getMediaServerId());
  43 + logger.info("【ZLM上线】ID:" + event.getMediaServerId());
48 44 streamPushService.zlmServerOnline(event.getMediaServerId());
49 45 streamProxyService.zlmServerOnline(event.getMediaServerId());
50 46  
... ...
src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java
... ... @@ -3,56 +3,105 @@ package com.genersoft.iot.vmp.service;
3 3 import com.genersoft.iot.vmp.gb28181.bean.Device;
4 4 import com.genersoft.iot.vmp.gb28181.bean.SyncStatus;
5 5  
  6 +import java.util.List;
  7 +
6 8 /**
7 9 * 设备相关业务处理
  10 + * @author lin
8 11 */
9 12 public interface IDeviceService {
10 13  
11 14 /**
  15 + * 设备上线
  16 + * @param device 设备信息
  17 + */
  18 + void online(Device device);
  19 +
  20 + /**
  21 + * 设备下线
  22 + * @param deviceId 设备编号
  23 + */
  24 + void offline(String deviceId);
  25 +
  26 + /**
12 27 * 添加目录订阅
13 28 * @param device 设备信息
14   - * @return
  29 + * @return 布尔
15 30 */
16 31 boolean addCatalogSubscribe(Device device);
17 32  
18 33 /**
19 34 * 移除目录订阅
20 35 * @param device 设备信息
21   - * @return
  36 + * @return 布尔
22 37 */
23 38 boolean removeCatalogSubscribe(Device device);
24 39  
25 40 /**
26 41 * 添加移动位置订阅
27 42 * @param device 设备信息
28   - * @return
  43 + * @return 布尔
29 44 */
30 45 boolean addMobilePositionSubscribe(Device device);
31 46  
32 47 /**
33 48 * 移除移动位置订阅
34 49 * @param device 设备信息
35   - * @return
  50 + * @return 布尔
36 51 */
37 52 boolean removeMobilePositionSubscribe(Device device);
38 53  
39 54 /**
40 55 * 移除移动位置订阅
41 56 * @param deviceId 设备ID
42   - * @return
  57 + * @return 同步状态
43 58 */
44 59 SyncStatus getChannelSyncStatus(String deviceId);
45 60  
46 61 /**
47 62 * 查看是否仍在同步
48 63 * @param deviceId 设备ID
49   - * @return
  64 + * @return 布尔
50 65 */
51 66 Boolean isSyncRunning(String deviceId);
52 67  
53 68 /**
54 69 * 通道同步
55   - * @param device
  70 + * @param device 设备信息
56 71 */
57 72 void sync(Device device);
  73 +
  74 + /**
  75 + * 查询设备信息
  76 + * @param deviceId 设备编号
  77 + * @return 设备信息
  78 + */
  79 + Device queryDevice(String deviceId);
  80 +
  81 + /**
  82 + * 获取所有在线设备
  83 + * @return 设备列表
  84 + */
  85 + List<Device> getAllOnlineDevice();
  86 +
  87 + /**
  88 + * 判断是否注册已经失效
  89 + * @param device 设备信息
  90 + * @return 布尔
  91 + */
  92 + boolean expire(Device device);
  93 +
  94 + /**
  95 + * 检查设备状态
  96 + * @param device 设备信息
  97 + */
  98 + void checkDeviceStatus(Device device);
  99 +
  100 + /**
  101 + * 根据IP和端口获取设备信息
  102 + * @param host IP
  103 + * @param port 端口
  104 + * @return 设备信息
  105 + */
  106 + Device getDeviceByHostAndPort(String host, int port);
58 107 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
... ... @@ -2,13 +2,19 @@ package com.genersoft.iot.vmp.service.impl;
2 2  
3 3 import com.genersoft.iot.vmp.conf.DynamicTask;
4 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
  5 +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
  6 +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
5 7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
6 8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.CatalogResponseMessageHandler;
7 9 import com.genersoft.iot.vmp.service.IDeviceService;
8 10 import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask;
9 11 import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask;
10 12 import com.genersoft.iot.vmp.gb28181.bean.SyncStatus;
  13 +import com.genersoft.iot.vmp.service.IMediaServerService;
  14 +import com.genersoft.iot.vmp.service.IMediaService;
11 15 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  16 +import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
  17 +import com.genersoft.iot.vmp.utils.DateUtil;
12 18 import org.slf4j.Logger;
13 19 import org.slf4j.LoggerFactory;
14 20 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -17,6 +23,11 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
17 23 import org.springframework.stereotype.Service;
18 24  
19 25 import javax.sip.DialogState;
  26 +import javax.sip.TimeoutEvent;
  27 +import java.text.ParseException;
  28 +import java.util.Calendar;
  29 +import java.util.Date;
  30 +import java.util.List;
20 31  
21 32 /**
22 33 * 设备业务(目录订阅)
... ... @@ -26,6 +37,8 @@ public class DeviceServiceImpl implements IDeviceService {
26 37  
27 38 private final static Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class);
28 39  
  40 + private final String registerExpireTaskKeyPrefix = "device-register-expire-";
  41 +
29 42 @Autowired
30 43 private DynamicTask dynamicTask;
31 44  
... ... @@ -38,6 +51,84 @@ public class DeviceServiceImpl implements IDeviceService {
38 51 @Autowired
39 52 private IRedisCatchStorage redisCatchStorage;
40 53  
  54 + @Autowired
  55 + private DeviceMapper deviceMapper;
  56 +
  57 + @Autowired
  58 + private ISIPCommander commander;
  59 +
  60 + @Autowired
  61 + private VideoStreamSessionManager streamSession;
  62 +
  63 + @Autowired
  64 + private IMediaServerService mediaServerService;
  65 +
  66 + @Override
  67 + public void online(Device device) {
  68 + logger.info("[设备上线],deviceId:" + device.getDeviceId());
  69 + Device deviceInRedis = redisCatchStorage.getDevice(device.getDeviceId());
  70 + Device deviceInDb = deviceMapper.getDeviceByDeviceId(device.getDeviceId());
  71 +
  72 + String now = DateUtil.getNow();
  73 + if (deviceInRedis != null && deviceInDb == null) {
  74 + // redis 存在脏数据
  75 + redisCatchStorage.clearCatchByDeviceId(device.getDeviceId());
  76 + device.setCreateTime(now);
  77 + }
  78 + device.setOnline(1);
  79 + device.setRegisterTime(now);
  80 +
  81 + // 第一次上线
  82 + if (device.getCreateTime() == null) {
  83 + logger.info("[设备上线,首次注册]: {},查询设备信息以及通道信息", device.getDeviceId());
  84 + commander.deviceInfoQuery(device);
  85 + sync(device);
  86 + deviceMapper.add(device);
  87 + }else {
  88 + deviceMapper.update(device);
  89 + }
  90 + redisCatchStorage.updateDevice(device);
  91 + // 上线添加订阅
  92 + if (device.getSubscribeCycleForCatalog() > 0) {
  93 + // 查询在线设备那些开启了订阅,为设备开启定时的目录订阅
  94 + addCatalogSubscribe(device);
  95 + }
  96 + if (device.getSubscribeCycleForMobilePosition() > 0) {
  97 + addMobilePositionSubscribe(device);
  98 + }
  99 + // 刷新过期任务
  100 + String registerExpireTaskKey = registerExpireTaskKeyPrefix + device.getDeviceId();
  101 + dynamicTask.stop(registerExpireTaskKey);
  102 + dynamicTask.startDelay(registerExpireTaskKey, ()->{
  103 + offline(device.getDeviceId());
  104 + }, device.getExpires() * 1000);
  105 + }
  106 +
  107 + @Override
  108 + public void offline(String deviceId) {
  109 + Device device = deviceMapper.getDeviceByDeviceId(deviceId);
  110 + if (device == null) {
  111 + return;
  112 + }
  113 + String registerExpireTaskKey = registerExpireTaskKeyPrefix + deviceId;
  114 + dynamicTask.stop(registerExpireTaskKey);
  115 + device.setOnline(0);
  116 + redisCatchStorage.updateDevice(device);
  117 + deviceMapper.update(device);
  118 + // 离线释放所有ssrc
  119 + List<SsrcTransaction> ssrcTransactions = streamSession.getSsrcTransactionForAll(deviceId, null, null, null);
  120 + if (ssrcTransactions != null && ssrcTransactions.size() > 0) {
  121 + for (SsrcTransaction ssrcTransaction : ssrcTransactions) {
  122 + mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc());
  123 + mediaServerService.closeRTPServer(deviceId, ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
  124 + streamSession.remove(deviceId, ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
  125 + }
  126 + }
  127 + // 移除订阅
  128 + removeCatalogSubscribe(device);
  129 + removeMobilePositionSubscribe(device);
  130 + }
  131 +
41 132 @Override
42 133 public boolean addCatalogSubscribe(Device device) {
43 134 if (device == null || device.getSubscribeCycleForCatalog() < 0) {
... ... @@ -49,7 +140,7 @@ public class DeviceServiceImpl implements IDeviceService {
49 140 // 提前开始刷新订阅
50 141 int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForCatalog(),30);
51 142 // 设置最小值为30
52   - dynamicTask.startCron(device.getDeviceId() + "catalog", catalogSubscribeTask, subscribeCycleForCatalog -1);
  143 + dynamicTask.startCron(device.getDeviceId() + "catalog", catalogSubscribeTask, (subscribeCycleForCatalog -1) * 1000);
53 144 return true;
54 145 }
55 146  
... ... @@ -74,7 +165,7 @@ public class DeviceServiceImpl implements IDeviceService {
74 165 // 设置最小值为30
75 166 int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForMobilePosition(),30);
76 167 // 提前开始刷新订阅
77   - dynamicTask.startCron(device.getDeviceId() + "mobile_position" , mobilePositionSubscribeTask, subscribeCycleForCatalog -1 );
  168 + dynamicTask.startCron(device.getDeviceId() + "mobile_position" , mobilePositionSubscribeTask, (subscribeCycleForCatalog -1 ) * 1000);
78 169 return true;
79 170 }
80 171  
... ... @@ -111,4 +202,44 @@ public class DeviceServiceImpl implements IDeviceService {
111 202 catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), errorMsg);
112 203 });
113 204 }
  205 +
  206 + @Override
  207 + public Device queryDevice(String deviceId) {
  208 + return deviceMapper.getDeviceByDeviceId(deviceId);
  209 + }
  210 +
  211 + @Override
  212 + public List<Device> getAllOnlineDevice() {
  213 + return deviceMapper.getOnlineDevices();
  214 + }
  215 +
  216 + @Override
  217 + public boolean expire(Device device) {
  218 + Date registerTimeDate;
  219 + try {
  220 + registerTimeDate = DateUtil.format.parse(device.getRegisterTime());
  221 + } catch (ParseException e) {
  222 + logger.error("设备时间格式化失败:{}->{} ", device.getDeviceId(), device.getRegisterTime() );
  223 + return false;
  224 + }
  225 + int expires = device.getExpires();
  226 + Calendar calendarForExpire = Calendar.getInstance();
  227 + calendarForExpire.setTime(registerTimeDate);
  228 + calendarForExpire.set(Calendar.SECOND, calendarForExpire.get(Calendar.SECOND) + expires);
  229 + return calendarForExpire.before(DateUtil.getNow());
  230 + }
  231 +
  232 + @Override
  233 + public void checkDeviceStatus(Device device) {
  234 + if (device == null || device.getOnline() == 0) {
  235 + return;
  236 + }
  237 + sipCommander.deviceStatusQuery(device, null);
  238 +
  239 + }
  240 +
  241 + @Override
  242 + public Device getDeviceByHostAndPort(String host, int port) {
  243 + return deviceMapper.getDeviceByHostAndPort(host, port);
  244 + }
114 245 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
... ... @@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.service.IStreamProxyService;
18 18 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
19 19 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
20 20 import com.genersoft.iot.vmp.storager.dao.MediaServerMapper;
  21 +import com.genersoft.iot.vmp.utils.DateUtil;
21 22 import com.genersoft.iot.vmp.utils.redis.JedisUtil;
22 23 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
23 24 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
... ... @@ -89,8 +90,6 @@ public class MediaServerServiceImpl implements IMediaServerService {
89 90 @Autowired
90 91 JedisUtil jedisUtil;
91 92  
92   - private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
93   -
94 93 /**
95 94 * 初始化
96 95 */
... ... @@ -231,7 +230,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
231 230 result.sort((serverItem1, serverItem2)->{
232 231 int sortResult = 0;
233 232 try {
234   - sortResult = format.parse(serverItem1.getCreateTime()).compareTo(format.parse(serverItem2.getCreateTime()));
  233 + sortResult = DateUtil.format.parse(serverItem1.getCreateTime()).compareTo(DateUtil.format.parse(serverItem2.getCreateTime()));
235 234 } catch (ParseException e) {
236 235 e.printStackTrace();
237 236 }
... ... @@ -291,8 +290,8 @@ public class MediaServerServiceImpl implements IMediaServerService {
291 290 @Override
292 291 public WVPResult<String> add(MediaServerItem mediaServerItem) {
293 292 WVPResult<String> result = new WVPResult<>();
294   - mediaServerItem.setCreateTime(this.format.format(System.currentTimeMillis()));
295   - mediaServerItem.setUpdateTime(this.format.format(System.currentTimeMillis()));
  293 + mediaServerItem.setCreateTime(DateUtil.getNow());
  294 + mediaServerItem.setUpdateTime(DateUtil.getNow());
296 295 mediaServerItem.setHookAliveInterval(120);
297 296 JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);
298 297 if (responseJSON != null) {
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
... ... @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
13 13 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
14 14 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
15 15 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
16   -import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
  16 +import com.genersoft.iot.vmp.utils.DateUtil;
17 17 import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils;
18 18 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
19 19 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java
... ... @@ -4,20 +4,15 @@ import com.alibaba.fastjson.JSON;
4 4 import com.genersoft.iot.vmp.gb28181.bean.*;
5 5 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
6 6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
7   -import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
8   -import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
9 7 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
10   -import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
  8 +import com.genersoft.iot.vmp.utils.DateUtil;
11 9 import org.slf4j.Logger;
12 10 import org.slf4j.LoggerFactory;
13 11 import org.springframework.beans.factory.annotation.Autowired;
14 12 import org.springframework.data.redis.connection.Message;
15 13 import org.springframework.data.redis.connection.MessageListener;
16   -import org.springframework.http.HttpStatus;
17   -import org.springframework.http.ResponseEntity;
18 14 import org.springframework.stereotype.Component;
19 15  
20   -import java.text.SimpleDateFormat;
21 16  
22 17 @Component
23 18 public class RedisAlarmMsgListener implements MessageListener {
... ... @@ -33,8 +28,6 @@ public class RedisAlarmMsgListener implements MessageListener {
33 28 @Autowired
34 29 private IVideoManagerStorage storage;
35 30  
36   - private final SimpleDateFormat formatForGB = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
37   -
38 31 @Override
39 32 public void onMessage(Message message, byte[] bytes) {
40 33 logger.info("收到来自REDIS的ALARM通知: {}", new String(message.getBody()));
... ... @@ -52,7 +45,7 @@ public class RedisAlarmMsgListener implements MessageListener {
52 45 deviceAlarm.setAlarmDescription(alarmChannelMessage.getAlarmDescription());
53 46 deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn());
54 47 deviceAlarm.setAlarmPriority("1");
55   - deviceAlarm.setAlarmTime(formatForGB.format(System.currentTimeMillis()));
  48 + deviceAlarm.setAlarmTime(DateUtil.getNow());
56 49 deviceAlarm.setAlarmType("1");
57 50 deviceAlarm.setLongitude(0);
58 51 deviceAlarm.setLatitude(0);
... ...
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
... ... @@ -112,23 +112,6 @@ public interface IRedisCatchStorage {
112 112 void clearCatchByDeviceId(String deviceId);
113 113  
114 114 /**
115   - * 获取mediaServer节点
116   - * @param mediaServerId
117   - * @return
118   - */
119   -// MediaServerItem getMediaInfo(String mediaServerId);
120   -
121   - /**
122   - * 设置所有设备离线
123   - */
124   - void outlineForAll();
125   -
126   - /**
127   - * 获取所有在线的
128   - */
129   - List<String> getOnlineForAll();
130   -
131   - /**
132 115 * 在redis添加wvp的信息
133 116 */
134 117 void updateWVPInfo(JSONObject jsonObject, int time);
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
... ... @@ -99,4 +99,9 @@ public interface DeviceMapper {
99 99  
100 100 @Update("UPDATE device SET online=0")
101 101 int outlineForAll();
  102 +
  103 + @Select("SELECT * FROM device WHERE online = 1")
  104 + List<Device> getOnlineDevices();
  105 + @Select("SELECT * FROM device WHERE ip = #{host} AND port=${port}")
  106 + Device getDeviceByHostAndPort(String host, int port);
102 107 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
... ... @@ -14,13 +14,13 @@ import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
14 14 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB;
15 15 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
16 16 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
  17 +import com.genersoft.iot.vmp.utils.DateUtil;
17 18 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
18 19 import org.slf4j.Logger;
19 20 import org.slf4j.LoggerFactory;
20 21 import org.springframework.beans.factory.annotation.Autowired;
21 22 import org.springframework.stereotype.Component;
22 23  
23   -import java.text.SimpleDateFormat;
24 24 import java.util.*;
25 25  
26 26 @SuppressWarnings("rawtypes")
... ... @@ -38,8 +38,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
38 38 @Autowired
39 39 private UserSetting userSetting;
40 40  
41   - private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
42   -
43 41 @Override
44 42 public Long getCSEQ(String method) {
45 43 String key = VideoManagerConstants.SIP_CSEQ_PREFIX + userSetting.getServerId() + "_" + method;
... ... @@ -470,26 +468,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
470 468 }
471 469  
472 470 @Override
473   - public void outlineForAll() {
474   - List<Object> onlineDevices = redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + "*" );
475   - for (int i = 0; i < onlineDevices.size(); i++) {
476   - String key = (String) onlineDevices.get(i);
477   - redis.del(key);
478   - }
479   - }
480   -
481   - @Override
482   - public List<String> getOnlineForAll() {
483   - List<String> result = new ArrayList<>();
484   - List<Object> onlineDevices = redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + "*" );
485   - for (int i = 0; i < onlineDevices.size(); i++) {
486   - String key = (String) onlineDevices.get(i);
487   - result.add((String) redis.get(key));
488   - }
489   - return result;
490   - }
491   -
492   - @Override
493 471 public void updateWVPInfo(JSONObject jsonObject, int time) {
494 472 String key = VideoManagerConstants.WVP_SERVER_PREFIX + userSetting.getServerId();
495 473 redis.set(key, jsonObject, time);
... ... @@ -638,7 +616,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
638 616 public void addCpuInfo(double cpuInfo) {
639 617 String key = VideoManagerConstants.SYSTEM_INFO_CPU_PREFIX + userSetting.getServerId();
640 618 SystemInfoDto<Double> systemInfoDto = new SystemInfoDto<>();
641   - systemInfoDto.setTime(format.format(System.currentTimeMillis()));
  619 + systemInfoDto.setTime(DateUtil.getNow());
642 620 systemInfoDto.setData(cpuInfo);
643 621 redis.lSet(key, systemInfoDto);
644 622 // 每秒一个,最多只存30个
... ... @@ -653,7 +631,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
653 631 public void addMemInfo(double memInfo) {
654 632 String key = VideoManagerConstants.SYSTEM_INFO_MEM_PREFIX + userSetting.getServerId();
655 633 SystemInfoDto<Double> systemInfoDto = new SystemInfoDto<>();
656   - systemInfoDto.setTime(format.format(System.currentTimeMillis()));
  634 + systemInfoDto.setTime(DateUtil.getNow());
657 635 systemInfoDto.setData(memInfo);
658 636 redis.lSet(key, systemInfoDto);
659 637 // 每秒一个,最多只存30个
... ... @@ -668,7 +646,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
668 646 public void addNetInfo(Map<String, String> networkInterfaces) {
669 647 String key = VideoManagerConstants.SYSTEM_INFO_NET_PREFIX + userSetting.getServerId();
670 648 SystemInfoDto<Map<String, String>> systemInfoDto = new SystemInfoDto<>();
671   - systemInfoDto.setTime(format.format(System.currentTimeMillis()));
  649 + systemInfoDto.setTime(DateUtil.getNow());
672 650 systemInfoDto.setData(networkInterfaces);
673 651 redis.lSet(key, systemInfoDto);
674 652 // 每秒一个,最多只存30个
... ... @@ -702,7 +680,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
702 680  
703 681 @Override
704 682 public boolean deviceIsOnline(String deviceId) {
705   - String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + deviceId;
706   - return redis.hasKey(key);
  683 + return getDevice(deviceId).getOnline() == 1;
707 684 }
708 685 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java
... ... @@ -13,6 +13,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
13 13 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
14 14 import com.genersoft.iot.vmp.storager.dao.*;
15 15 import com.genersoft.iot.vmp.storager.dao.dto.ChannelSourceInfo;
  16 +import com.genersoft.iot.vmp.utils.DateUtil;
16 17 import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
17 18 import com.github.pagehelper.PageHelper;
18 19 import com.github.pagehelper.PageInfo;
... ... @@ -26,7 +27,6 @@ import org.springframework.transaction.TransactionStatus;
26 27 import org.springframework.transaction.annotation.Transactional;
27 28 import org.springframework.util.StringUtils;
28 29  
29   -import java.text.SimpleDateFormat;
30 30 import java.util.*;
31 31  
32 32 /**
... ... @@ -91,9 +91,6 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
91 91 @Autowired
92 92 private ParentPlatformMapper parentPlatformMapper;
93 93  
94   - private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
95   -
96   -
97 94 /**
98 95 * 根据设备ID判断设备是否存在
99 96 *
... ... @@ -127,7 +124,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
127 124 */
128 125 @Override
129 126 public synchronized boolean updateDevice(Device device) {
130   - String now = this.format.format(System.currentTimeMillis());
  127 + String now = DateUtil.getNow();
131 128 device.setUpdateTime(now);
132 129 Device deviceByDeviceId = deviceMapper.getDeviceByDeviceId(device.getDeviceId());
133 130 device.setCharset(device.getCharset().toUpperCase());
... ... @@ -140,8 +137,6 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
140 137  
141 138 return deviceMapper.update(device) > 0;
142 139 }
143   -
144   -
145 140 }
146 141  
147 142 @Override
... ... @@ -152,7 +147,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
152 147 if (streamInfo != null) {
153 148 channel.setStreamId(streamInfo.getStream());
154 149 }
155   - String now = this.format.format(System.currentTimeMillis());
  150 + String now = DateUtil.getNow();
156 151 channel.setUpdateTime(now);
157 152 DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId);
158 153 if (deviceChannel == null) {
... ... @@ -178,7 +173,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
178 173 if (streamInfo != null) {
179 174 channel.setStreamId(streamInfo.getStream());
180 175 }
181   - String now = this.format.format(System.currentTimeMillis());
  176 + String now = DateUtil.getNow();
182 177 channel.setUpdateTime(now);
183 178 channel.setCreateTime(now);
184 179 addChannels.add(channel);
... ... @@ -193,7 +188,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
193 188 if (streamInfo != null) {
194 189 channel.setStreamId(streamInfo.getStream());
195 190 }
196   - String now = this.format.format(System.currentTimeMillis());
  191 + String now = DateUtil.getNow();
197 192 channel.setUpdateTime(now);
198 193 if (channelsInStore.get(channel.getChannelId()) != null) {
199 194 updateChannels.add(channel);
... ... @@ -732,7 +727,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
732 727 boolean result = false;
733 728 streamProxyItem.setStreamType("proxy");
734 729 streamProxyItem.setStatus(true);
735   - String now = this.format.format(System.currentTimeMillis());
  730 + String now = DateUtil.getNow();
736 731 streamProxyItem.setCreateTime(now);
737 732 streamProxyItem.setCreateStamp(System.currentTimeMillis());
738 733 try {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java renamed to src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java
1   -package com.genersoft.iot.vmp.gb28181.utils;
2   -
3   -import java.text.ParseException;
4   -import java.text.SimpleDateFormat;
5   -import java.util.Date;
6   -import java.util.Locale;
7   -
8   -/**
9   - * @description:时间工具类,主要处理ISO 8601格式转换
10   - * @author: swwheihei
11   - * @date: 2020年5月8日 下午3:24:42
12   - */
13   -public class DateUtil {
14   -
15   - //private static final String yyyy_MM_dd_T_HH_mm_ss_SSSXXX = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
16   - private static final String yyyy_MM_dd_T_HH_mm_ss_SSSXXX = "yyyy-MM-dd'T'HH:mm:ss";
17   - private static final String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
18   -
19   - public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) {
20   -
21   - SimpleDateFormat oldsdf = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss, Locale.getDefault());
22   - SimpleDateFormat newsdf = new SimpleDateFormat(yyyy_MM_dd_T_HH_mm_ss_SSSXXX, Locale.getDefault());
23   - try {
24   - return newsdf.format(oldsdf.parse(formatTime));
25   - } catch (ParseException e) {
26   - e.printStackTrace();
27   - }
28   - return "";
29   - }
30   -
31   - public static String ISO8601Toyyyy_MM_dd_HH_mm_ss(String formatTime) {
32   -
33   - SimpleDateFormat oldsdf = new SimpleDateFormat(yyyy_MM_dd_T_HH_mm_ss_SSSXXX, Locale.getDefault());
34   - SimpleDateFormat newsdf = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss, Locale.getDefault());
35   - try {
36   - return newsdf.format(oldsdf.parse(formatTime));
37   - } catch (ParseException e) {
38   - e.printStackTrace();
39   - }
40   - return "";
41   - }
42   -
43   - public static long yyyy_MM_dd_HH_mm_ssToTimestamp(String formatTime) {
44   - SimpleDateFormat format=new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss);
45   - //设置要读取的时间字符串格式
46   - Date date;
47   - try {
48   - date = format.parse(formatTime);
49   - Long timestamp=date.getTime()/1000;
50   - //转换为Date类
51   - return timestamp;
52   - } catch (ParseException e) {
53   - e.printStackTrace();
54   - }
55   - return 0;
56   - }
57   -}
  1 +package com.genersoft.iot.vmp.utils;
  2 +
  3 +import java.text.ParseException;
  4 +import java.text.SimpleDateFormat;
  5 +import java.util.Date;
  6 +import java.util.Locale;
  7 +
  8 +/**
  9 + * 全局时间工具类
  10 + * @author swwheihei
  11 + */
  12 +public class DateUtil {
  13 +
  14 + private static final String yyyy_MM_dd_T_HH_mm_ss_SSSXXX = "yyyy-MM-dd'T'HH:mm:ss";
  15 + private static final String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
  16 +
  17 + public static final SimpleDateFormat formatISO8601 = new SimpleDateFormat(yyyy_MM_dd_T_HH_mm_ss_SSSXXX, Locale.getDefault());
  18 + public static final SimpleDateFormat format = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss, Locale.getDefault());
  19 +
  20 + public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) {
  21 +
  22 + try {
  23 + return formatISO8601.format(format.parse(formatTime));
  24 + } catch (ParseException e) {
  25 + e.printStackTrace();
  26 + }
  27 + return "";
  28 + }
  29 +
  30 + public static String ISO8601Toyyyy_MM_dd_HH_mm_ss(String formatTime) {
  31 +
  32 + try {
  33 + return format.format(formatISO8601.parse(formatTime));
  34 + } catch (ParseException e) {
  35 + e.printStackTrace();
  36 + }
  37 + return "";
  38 + }
  39 +
  40 + public static long yyyy_MM_dd_HH_mm_ssToTimestamp(String formatTime) {
  41 + //设置要读取的时间字符串格式
  42 + Date date;
  43 + try {
  44 + date = format.parse(formatTime);
  45 + Long timestamp=date.getTime()/1000;
  46 + //转换为Date类
  47 + return timestamp;
  48 + } catch (ParseException e) {
  49 + e.printStackTrace();
  50 + }
  51 + return 0;
  52 + }
  53 +
  54 + public static String getNow() {
  55 + return format.format(System.currentTimeMillis());
  56 + }
  57 +}
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/alarm/AlarmController.java
... ... @@ -9,6 +9,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
9 9 import com.genersoft.iot.vmp.service.IDeviceAlarmService;
10 10 import com.genersoft.iot.vmp.service.IGbStreamService;
11 11 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
  12 +import com.genersoft.iot.vmp.utils.DateUtil;
12 13 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
13 14 import com.github.pagehelper.PageInfo;
14 15 import io.swagger.annotations.Api;
... ... @@ -23,9 +24,7 @@ import org.springframework.util.StringUtils;
23 24 import org.springframework.web.bind.annotation.*;
24 25  
25 26 import java.text.ParseException;
26   -import java.text.SimpleDateFormat;
27 27 import java.util.Arrays;
28   -import java.util.Date;
29 28 import java.util.List;
30 29  
31 30 @Api(tags = "报警信息管理")
... ... @@ -46,9 +45,6 @@ public class AlarmController {
46 45 @Autowired
47 46 private IVideoManagerStorage storage;
48 47  
49   - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
50   - private SimpleDateFormat formatForGB = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
51   -
52 48 /**
53 49 * 分页查询报警
54 50 *
... ... @@ -104,10 +100,10 @@ public class AlarmController {
104 100  
105 101 try {
106 102 if (startTime != null) {
107   - format.parse(startTime);
  103 + DateUtil.format.parse(startTime);
108 104 }
109 105 if (endTime != null) {
110   - format.parse(endTime);
  106 + DateUtil.format.parse(endTime);
111 107 }
112 108 } catch (ParseException e) {
113 109 return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
... ... @@ -150,7 +146,7 @@ public class AlarmController {
150 146 }
151 147 try {
152 148 if (time != null) {
153   - format.parse(time);
  149 + DateUtil.format.parse(time);
154 150 }
155 151 } catch (ParseException e) {
156 152 return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
... ... @@ -193,7 +189,7 @@ public class AlarmController {
193 189 deviceAlarm.setAlarmDescription("test");
194 190 deviceAlarm.setAlarmMethod("1");
195 191 deviceAlarm.setAlarmPriority("1");
196   - deviceAlarm.setAlarmTime(formatForGB.format(System.currentTimeMillis()));
  192 + deviceAlarm.setAlarmTime(DateUtil.formatISO8601.format(System.currentTimeMillis()));
197 193 deviceAlarm.setAlarmType("1");
198 194 deviceAlarm.setLongitude(115.33333);
199 195 deviceAlarm.setLatitude(39.33333);
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java
... ... @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.vmanager.log;
3 3 import com.genersoft.iot.vmp.conf.UserSetting;
4 4 import com.genersoft.iot.vmp.service.ILogService;
5 5 import com.genersoft.iot.vmp.storager.dao.dto.LogDto;
  6 +import com.genersoft.iot.vmp.utils.DateUtil;
6 7 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
7 8 import com.github.pagehelper.PageInfo;
8 9 import io.swagger.annotations.Api;
... ... @@ -18,7 +19,6 @@ import org.springframework.util.StringUtils;
18 19 import org.springframework.web.bind.annotation.*;
19 20  
20 21 import java.text.ParseException;
21   -import java.text.SimpleDateFormat;
22 22  
23 23 @Api(tags = "日志管理")
24 24 @CrossOrigin
... ... @@ -34,8 +34,6 @@ public class LogController {
34 34 @Autowired
35 35 private UserSetting userSetting;
36 36  
37   - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
38   -
39 37 /**
40 38 * 分页查询日志
41 39 *
... ... @@ -80,10 +78,10 @@ public class LogController {
80 78  
81 79 try {
82 80 if (startTime != null) {
83   - format.parse(startTime);
  81 + DateUtil.format.parse(startTime);
84 82 }
85 83 if (endTime != null) {
86   - format.parse(endTime);
  84 + DateUtil.format.parse(endTime);
87 85 }
88 86 } catch (ParseException e) {
89 87 return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/user/RoleController.java
... ... @@ -2,9 +2,8 @@ package com.genersoft.iot.vmp.vmanager.user;
2 2  
3 3 import com.genersoft.iot.vmp.conf.security.SecurityUtils;
4 4 import com.genersoft.iot.vmp.service.IRoleService;
5   -import com.genersoft.iot.vmp.service.IUserService;
6 5 import com.genersoft.iot.vmp.storager.dao.dto.Role;
7   -import com.genersoft.iot.vmp.storager.dao.dto.User;
  6 +import com.genersoft.iot.vmp.utils.DateUtil;
8 7 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
9 8 import io.swagger.annotations.Api;
10 9 import io.swagger.annotations.ApiImplicitParam;
... ... @@ -13,12 +12,8 @@ import io.swagger.annotations.ApiOperation;
13 12 import org.springframework.beans.factory.annotation.Autowired;
14 13 import org.springframework.http.HttpStatus;
15 14 import org.springframework.http.ResponseEntity;
16   -import org.springframework.security.authentication.AuthenticationManager;
17   -import org.springframework.util.DigestUtils;
18   -import org.springframework.util.StringUtils;
19 15 import org.springframework.web.bind.annotation.*;
20 16  
21   -import java.text.SimpleDateFormat;
22 17 import java.util.List;
23 18  
24 19 @Api(tags = "角色管理")
... ... @@ -30,8 +25,6 @@ public class RoleController {
30 25 @Autowired
31 26 private IRoleService roleService;
32 27  
33   - private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
34   -
35 28 @ApiOperation("添加角色")
36 29 @ApiImplicitParams({
37 30 @ApiImplicitParam(name = "name", required = true, value = "角色名", dataTypeClass = String.class),
... ... @@ -53,8 +46,8 @@ public class RoleController {
53 46 Role role = new Role();
54 47 role.setName(name);
55 48 role.setAuthority(authority);
56   - role.setCreateTime(format.format(System.currentTimeMillis()));
57   - role.setUpdateTime(format.format(System.currentTimeMillis()));
  49 + role.setCreateTime(DateUtil.getNow());
  50 + role.setUpdateTime(DateUtil.getNow());
58 51  
59 52 int addResult = roleService.add(role);
60 53  
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/user/UserController.java
... ... @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.service.IRoleService;
6 6 import com.genersoft.iot.vmp.service.IUserService;
7 7 import com.genersoft.iot.vmp.storager.dao.dto.Role;
8 8 import com.genersoft.iot.vmp.storager.dao.dto.User;
  9 +import com.genersoft.iot.vmp.utils.DateUtil;
9 10 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
10 11 import io.swagger.annotations.Api;
11 12 import io.swagger.annotations.ApiImplicitParam;
... ... @@ -20,7 +21,6 @@ import org.springframework.util.StringUtils;
20 21 import org.springframework.web.bind.annotation.*;
21 22  
22 23 import javax.security.sasl.AuthenticationException;
23   -import java.text.SimpleDateFormat;
24 24 import java.util.List;
25 25  
26 26 @Api(tags = "用户管理")
... ... @@ -38,8 +38,6 @@ public class UserController {
38 38 @Autowired
39 39 private IRoleService roleService;
40 40  
41   - private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
42   -
43 41 @ApiOperation("登录")
44 42 @ApiImplicitParams({
45 43 @ApiImplicitParam(name = "username", required = true, value = "用户名", dataTypeClass = String.class),
... ... @@ -135,8 +133,8 @@ public class UserController {
135 133 return new ResponseEntity<>(result, HttpStatus.OK);
136 134 }
137 135 user.setRole(role);
138   - user.setCreateTime(format.format(System.currentTimeMillis()));
139   - user.setUpdateTime(format.format(System.currentTimeMillis()));
  136 + user.setCreateTime(DateUtil.getNow());
  137 + user.setUpdateTime(DateUtil.getNow());
140 138 int addResult = userService.addUser(user);
141 139  
142 140 result.setCode(addResult > 0 ? 0 : -1);
... ...
src/test/java/com/genersoft/iot/vmp/service/impl/DeviceAlarmServiceImplTest.java
... ... @@ -2,12 +2,12 @@ package com.genersoft.iot.vmp.service.impl;
2 2  
3 3 import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
4 4 import com.genersoft.iot.vmp.service.IDeviceAlarmService;
  5 +import com.genersoft.iot.vmp.utils.DateUtil;
5 6 import org.junit.runner.RunWith;
6 7 import org.springframework.boot.test.context.SpringBootTest;
7 8 import org.springframework.test.context.junit4.SpringRunner;
8 9  
9 10 import javax.annotation.Resource;
10   -import java.text.SimpleDateFormat;
11 11 import java.util.Date;
12 12  
13 13  
... ... @@ -18,8 +18,6 @@ class DeviceAlarmServiceImplTest {
18 18 @Resource
19 19 private IDeviceAlarmService deviceAlarmService;
20 20  
21   - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
22   -
23 21 @org.junit.jupiter.api.Test
24 22 void getAllAlarm() {
25 23 // deviceAlarmService.getAllAlarm(0, 10000, "11111111111111111111",null,null,null, null, null);
... ... @@ -67,7 +65,7 @@ class DeviceAlarmServiceImplTest {
67 65 */
68 66 deviceAlarm.setAlarmMethod((int)(Math.random()*7 + 1) + "");
69 67 Date date = randomDate("2021-01-01 00:00:00", "2021-06-01 00:00:00");
70   - deviceAlarm.setAlarmTime(format.format(date));
  68 + deviceAlarm.setAlarmTime(DateUtil.format.format(date));
71 69 /**
72 70 * 报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级 警情-
73 71 */
... ... @@ -90,8 +88,8 @@ class DeviceAlarmServiceImplTest {
90 88 private Date randomDate(String beginDate, String endDate) {
91 89 try {
92 90  
93   - Date start = format.parse(beginDate);//构造开始日期
94   - Date end = format.parse(endDate);//构造结束日期
  91 + Date start = DateUtil.format.parse(beginDate);//构造开始日期
  92 + Date end = DateUtil.format.parse(endDate);//构造结束日期
95 93 //getTime()表示返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
96 94 if (start.getTime() >= end.getTime()) {
97 95 return null;
... ...
src/test/java/com/genersoft/iot/vmp/service/impl/RoleServiceImplTest.java
... ... @@ -4,12 +4,12 @@ import com.genersoft.iot.vmp.service.IRoleService;
4 4 import com.genersoft.iot.vmp.service.IUserService;
5 5 import com.genersoft.iot.vmp.storager.dao.dto.Role;
6 6 import com.genersoft.iot.vmp.storager.dao.dto.User;
  7 +import com.genersoft.iot.vmp.utils.DateUtil;
7 8 import org.junit.runner.RunWith;
8 9 import org.springframework.boot.test.context.SpringBootTest;
9 10 import org.springframework.test.context.junit4.SpringRunner;
10 11  
11 12 import javax.annotation.Resource;
12   -import java.text.SimpleDateFormat;
13 13 import java.util.List;
14 14  
15 15  
... ... @@ -20,7 +20,6 @@ class RoleServiceImplTest {
20 20 @Resource
21 21 private IRoleService roleService;
22 22  
23   - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
24 23 @org.junit.jupiter.api.Test
25 24 void getAllUser() {
26 25 List<Role> all = roleService.getAll();
... ... @@ -35,8 +34,8 @@ class RoleServiceImplTest {
35 34 Role role = new Role();
36 35 role.setName("test+" + i);
37 36 role.setAuthority("adadadda");
38   - role.setCreateTime(format.format(System.currentTimeMillis()));
39   - role.setUpdateTime(format.format(System.currentTimeMillis()));
  37 + role.setCreateTime(DateUtil.getNow());
  38 + role.setUpdateTime(DateUtil.getNow());
40 39 roleService.add(role);
41 40 }
42 41 }
... ...
src/test/java/com/genersoft/iot/vmp/service/impl/UserServiceImplTest.java
1 1 package com.genersoft.iot.vmp.service.impl;
2 2  
3   -import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
4   -import com.genersoft.iot.vmp.service.IDeviceAlarmService;
5 3 import com.genersoft.iot.vmp.service.IUserService;
6 4 import com.genersoft.iot.vmp.storager.dao.dto.Role;
7 5 import com.genersoft.iot.vmp.storager.dao.dto.User;
  6 +import com.genersoft.iot.vmp.utils.DateUtil;
8 7 import org.junit.runner.RunWith;
9 8 import org.springframework.boot.test.context.SpringBootTest;
10 9 import org.springframework.test.context.junit4.SpringRunner;
11 10  
12 11 import javax.annotation.Resource;
13   -import java.text.SimpleDateFormat;
14   -import java.util.Date;
15 12 import java.util.List;
16 13  
17 14  
... ... @@ -22,7 +19,6 @@ class UserServiceImplTest {
22 19 @Resource
23 20 private IUserService userService;
24 21  
25   - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
26 22  
27 23 @org.junit.jupiter.api.Test
28 24 void getAllUser() {
... ... @@ -42,8 +38,8 @@ class UserServiceImplTest {
42 38 Role role = new Role();
43 39 role.setId(1);
44 40 user.setRole(role);
45   - user.setCreateTime(format.format(System.currentTimeMillis()));
46   - user.setUpdateTime(format.format(System.currentTimeMillis()));
  41 + user.setCreateTime(DateUtil.getNow());
  42 + user.setUpdateTime(DateUtil.getNow());
47 43 userService.addUser(user);
48 44 }
49 45 }
... ... @@ -62,7 +58,7 @@ class UserServiceImplTest {
62 58 Role role = new Role();
63 59 role.setId(2);
64 60 user.setRole(role);
65   - user.setUpdateTime(format.format(System.currentTimeMillis()));
  61 + user.setUpdateTime(DateUtil.getNow());
66 62 userService.updateUsers(user);
67 63 }
68 64  
... ...
web_src/src/components/channelList.vue
... ... @@ -237,10 +237,10 @@ export default {
237 237 that.initData();
238 238 }, 1000)
239 239  
240   - } else {
241   - that.$message.error(res.data.msg);
242 240 }
243 241 }).catch(function (e) {
  242 + that.isLoging = false;
  243 + that.$message.error("请求超时");
244 244 });
245 245 },
246 246 queryRecords: function (itemData) {
... ...