diff --git a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java index ef4492f8..eb98f6f2 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java +++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java @@ -47,8 +47,6 @@ public class VideoManagerConstants { public static final String PLATFORM_SEND_RTP_INFO_PREFIX = "VMP_PLATFORM_SEND_RTP_INFO_"; public static final String EVENT_ONLINE_REGISTER = "1"; - - public static final String EVENT_ONLINE_KEEPLIVE = "2"; public static final String EVENT_ONLINE_MESSAGE = "3"; diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java b/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java index 61809743..5f4ac22e 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java @@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.common.ApiSaveConstant; import com.genersoft.iot.vmp.conf.security.SecurityUtils; import com.genersoft.iot.vmp.service.ILogService; import com.genersoft.iot.vmp.storager.dao.dto.LogDto; +import com.genersoft.iot.vmp.utils.DateUtil; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,7 +17,6 @@ import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.text.SimpleDateFormat; /** * @author lin @@ -26,7 +26,6 @@ public class ApiAccessFilter extends OncePerRequestFilter { private final static Logger logger = LoggerFactory.getLogger(ApiAccessFilter.class); - private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Autowired private UserSetting userSetting; @@ -58,7 +57,7 @@ public class ApiAccessFilter extends OncePerRequestFilter { logDto.setTiming(System.currentTimeMillis() - start); logDto.setType(servletRequest.getMethod()); logDto.setUri(servletRequest.getRequestURI()); - logDto.setCreateTime(format.format(System.currentTimeMillis())); + logDto.setCreateTime(DateUtil.getNow()); logService.add(logDto); // logger.warn("[Api Access] [{}] [{}] [{}] [{}] [{}] {}ms", // uriName, servletRequest.getMethod(), servletRequest.getRequestURI(), servletRequest.getRemoteAddr(), HttpStatus.valueOf(servletResponse.getStatus()), diff --git a/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java b/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java index 052f5336..2812f92c 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java @@ -43,27 +43,27 @@ public class DynamicTask { * 循环执行的任务 * @param key 任务ID * @param task 任务 - * @param cycleForCatalog 间隔 + * @param cycleForCatalog 间隔 毫秒 * @return */ public void startCron(String key, Runnable task, int cycleForCatalog) { ScheduledFuture future = futureMap.get(key); if (future != null) { if (future.isCancelled()) { - logger.info("任务【{}】已存在但是关闭状态!!!", key); + logger.debug("任务【{}】已存在但是关闭状态!!!", key); } else { - logger.info("任务【{}】已存在且已启动!!!", key); + logger.debug("任务【{}】已存在且已启动!!!", key); return; } } // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔 - future = threadPoolTaskScheduler.scheduleAtFixedRate(task, cycleForCatalog * 1000L); + future = threadPoolTaskScheduler.scheduleAtFixedRate(task, cycleForCatalog); if (future != null){ futureMap.put(key, future); runnableMap.put(key, task); - logger.info("任务【{}】启动成功!!!", key); + logger.debug("任务【{}】启动成功!!!", key); }else { - logger.info("任务【{}】启动失败!!!", key); + logger.debug("任务【{}】启动失败!!!", key); } } @@ -81,9 +81,9 @@ public class DynamicTask { ScheduledFuture future = futureMap.get(key); if (future != null) { if (future.isCancelled()) { - logger.info("任务【{}】已存在但是关闭状态!!!", key); + logger.debug("任务【{}】已存在但是关闭状态!!!", key); } else { - logger.info("任务【{}】已存在且已启动!!!", key); + logger.debug("任务【{}】已存在且已启动!!!", key); return; } } @@ -92,9 +92,9 @@ public class DynamicTask { if (future != null){ futureMap.put(key, future); runnableMap.put(key, task); - logger.info("任务【{}】启动成功!!!", key); + logger.debug("任务【{}】启动成功!!!", key); }else { - logger.info("任务【{}】启动失败!!!", key); + logger.debug("任务【{}】启动失败!!!", key); } } diff --git a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java index bdd15034..85f46849 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java @@ -1,12 +1,11 @@ package com.genersoft.iot.vmp.conf; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.utils.DateUtil; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; -import java.text.SimpleDateFormat; -import java.util.Date; @Configuration("mediaConfig") public class MediaConfig{ @@ -206,9 +205,8 @@ public class MediaConfig{ mediaServerItem.setRecordAssistPort(recordAssistPort); mediaServerItem.setHookAliveInterval(120); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - mediaServerItem.setCreateTime(format.format(System.currentTimeMillis())); - mediaServerItem.setUpdateTime(format.format(System.currentTimeMillis())); + mediaServerItem.setCreateTime(DateUtil.getNow()); + mediaServerItem.setUpdateTime(DateUtil.getNow()); return mediaServerItem; } diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ThreadPoolTaskConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/ThreadPoolTaskConfig.java index 71aed27f..7377702f 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/ThreadPoolTaskConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/ThreadPoolTaskConfig.java @@ -35,10 +35,11 @@ public class ThreadPoolTaskConfig { * 允许线程空闲时间(单位:默认为秒) */ private static final int keepAliveTime = 30; + /** * 缓冲队列大小 */ - private static final int queueCapacity = 500; + private static final int queueCapacity = 10000; /** * 线程池名前缀 */ diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java index 58772d9c..2b93d702 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java @@ -48,8 +48,15 @@ public class SipLayer{ Properties properties = new Properties(); properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP"); properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getMonitorIp()); + /** + * 完整配置参考 gov.nist.javax.sip.SipStackImpl,需要下载源码 + * gov/nist/javax/sip/SipStackImpl.class + */ properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true"); properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); // 接收所有notify请求,即使没有订阅 + properties.setProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG", "true"); // 为_NULL _对话框传递_终止的_事件 + properties.setProperty("gov.nist.javax.sip.RELEASE_REFERENCES_STRATEGY", "Normal"); // 会话清理策略 + properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "10"); /** * sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE = * 0; public static final int TRACE_MESSAGES = 16; public static final int diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java index 81b96662..e8eab8c2 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java @@ -99,11 +99,6 @@ public class Device { */ private String mediaServerId; - /** - * 首次注册 - */ - private boolean firsRegister; - /** * 字符集, 支持 UTF-8 与 GB2312 */ @@ -279,14 +274,6 @@ public class Device { this.mediaServerId = mediaServerId; } - public boolean isFirsRegister() { - return firsRegister; - } - - public void setFirsRegister(boolean firsRegister) { - this.firsRegister = firsRegister; - } - public String getCharset() { return charset; } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java index ca7fd54c..3349cdc5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java @@ -1,10 +1,10 @@ package com.genersoft.iot.vmp.gb28181.bean; +import com.genersoft.iot.vmp.utils.DateUtil; import org.jetbrains.annotations.NotNull; import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.Date; /** @@ -116,10 +116,9 @@ public class RecordItem implements Comparable{ @Override public int compareTo(@NotNull RecordItem recordItem) { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { - Date startTime_now = sdf.parse(startTime); - Date startTime_param = sdf.parse(recordItem.getStartTime()); + Date startTime_now = DateUtil.format.parse(startTime); + Date startTime_param = DateUtil.format.parse(recordItem.getStartTime()); if (startTime_param.compareTo(startTime_now) > 0) { return -1; }else { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java index e804be28..2736be2d 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java @@ -61,7 +61,7 @@ public class SubscribeHolder { // 添加任务处理GPS定时推送 dynamicTask.startCron(key, new MobilePositionSubscribeHandlerTask(redisCatchStorage, sipCommanderForPlatform, storager, platformId, subscribeInfo.getSn(), key, this, dynamicTask), - subscribeInfo.getGpsInterval()); + subscribeInfo.getGpsInterval() * 1000); String taskOverdueKey = taskOverduePrefix + "MobilePosition_" + platformId; dynamicTask.stop(taskOverdueKey); // 添加任务处理订阅过期 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java index ffe477f0..eaf674fa 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.gb28181.event; import com.genersoft.iot.vmp.gb28181.bean.*; -import com.genersoft.iot.vmp.gb28181.event.offline.OfflineEvent; +import com.genersoft.iot.vmp.gb28181.event.device.RequestTimeoutEvent; import com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire.PlatformKeepaliveExpireEvent; import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformCycleRegisterEvent; import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformNotRegisterEvent; @@ -11,12 +11,11 @@ import com.genersoft.iot.vmp.media.zlm.event.ZLMOfflineEvent; import com.genersoft.iot.vmp.media.zlm.event.ZLMOnlineEvent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEvent; -import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent; +import javax.sip.TimeoutEvent; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -32,28 +31,6 @@ public class EventPublisher { @Autowired private ApplicationEventPublisher applicationEventPublisher; - - public void onlineEventPublish(Device device, String from, int expires) { - OnlineEvent onEvent = new OnlineEvent(this); - onEvent.setDevice(device); - onEvent.setFrom(from); - onEvent.setExpires(expires); - applicationEventPublisher.publishEvent(onEvent); - } - - public void onlineEventPublish(Device device, String from) { - OnlineEvent onEvent = new OnlineEvent(this); - onEvent.setDevice(device); - onEvent.setFrom(from); - applicationEventPublisher.publishEvent(onEvent); - } - - public void outlineEventPublish(String deviceId, String from){ - OfflineEvent outEvent = new OfflineEvent(this); - outEvent.setDeviceId(deviceId); - outEvent.setFrom(from); - applicationEventPublisher.publishEvent(outEvent); - } /** * 平台心跳到期事件 @@ -115,6 +92,13 @@ public class EventPublisher { } + public void requestTimeOut(TimeoutEvent timeoutEvent) { + RequestTimeoutEvent requestTimeoutEvent = new RequestTimeoutEvent(this); + requestTimeoutEvent.setTimeoutEvent(timeoutEvent); + applicationEventPublisher.publishEvent(requestTimeoutEvent); + } + + /** * * @param platformId diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/device/RequestTimeoutEvent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/device/RequestTimeoutEvent.java new file mode 100644 index 00000000..c4d3baba --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/device/RequestTimeoutEvent.java @@ -0,0 +1,25 @@ +package com.genersoft.iot.vmp.gb28181.event.device; + +import org.springframework.context.ApplicationEvent; + +import javax.sip.TimeoutEvent; + +/** + * @author lin + */ +public class RequestTimeoutEvent extends ApplicationEvent { + public RequestTimeoutEvent(Object source) { + super(source); + } + + + private TimeoutEvent timeoutEvent; + + public TimeoutEvent getTimeoutEvent() { + return timeoutEvent; + } + + public void setTimeoutEvent(TimeoutEvent timeoutEvent) { + this.timeoutEvent = timeoutEvent; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/device/RequestTimeoutEventImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/device/RequestTimeoutEventImpl.java new file mode 100644 index 00000000..9382c2f6 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/device/RequestTimeoutEventImpl.java @@ -0,0 +1,41 @@ +package com.genersoft.iot.vmp.gb28181.event.device; + +import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; +import com.genersoft.iot.vmp.service.IDeviceService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +import javax.sip.ClientTransaction; +import javax.sip.address.SipURI; +import javax.sip.header.CallIdHeader; +import javax.sip.header.ToHeader; +import javax.sip.message.Request; + +/** + * @author lin + */ +@Component +public class RequestTimeoutEventImpl implements ApplicationListener { + + @Autowired + private IDeviceService deviceService; + + @Override + public void onApplicationEvent(RequestTimeoutEvent event) { + ClientTransaction clientTransaction = event.getTimeoutEvent().getClientTransaction(); + if (clientTransaction != null) { + Request request = clientTransaction.getRequest(); + if (request != null) { + String host = ((SipURI) request.getRequestURI()).getHost(); + int port = ((SipURI) request.getRequestURI()).getPort(); + Device device = deviceService.getDeviceByHostAndPort(host, port); + if (device == null) { + return; + } + deviceService.offline(device.getDeviceId()); + } + } + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java index ef78d371..8516fc78 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java @@ -17,9 +17,8 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; /** - * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件 - * @author: swwheihei - * @date: 2020年5月6日 上午11:35:46 + * 设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件 + * @author swwheihei */ @Component public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEventMessageListener { @@ -55,25 +54,18 @@ public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEvent // 平台心跳到期,需要重发, 判断是否已经多次未收到心跳回复, 多次未收到,则重新发起注册, 注册尝试多次未得到回复,则认为平台离线 String PLATFORM_KEEPLIVEKEY_PREFIX = VideoManagerConstants.PLATFORM_KEEPALIVE_PREFIX + userSetting.getServerId() + "_"; String PLATFORM_REGISTER_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_PREFIX + userSetting.getServerId() + "_"; - String KEEPLIVEKEY_PREFIX = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_"; String REGISTER_INFO_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_"; if (expiredKey.startsWith(PLATFORM_KEEPLIVEKEY_PREFIX)) { - String platformGBId = expiredKey.substring(PLATFORM_KEEPLIVEKEY_PREFIX.length(),expiredKey.length()); - ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGBId); + String platformGbId = expiredKey.substring(PLATFORM_KEEPLIVEKEY_PREFIX.length()); + ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGbId); if (platform != null) { - publisher.platformKeepaliveExpireEventPublish(platformGBId); + publisher.platformKeepaliveExpireEventPublish(platformGbId); } }else if (expiredKey.startsWith(PLATFORM_REGISTER_PREFIX)) { - String platformGBId = expiredKey.substring(PLATFORM_REGISTER_PREFIX.length(),expiredKey.length()); - ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGBId); + String platformGbId = expiredKey.substring(PLATFORM_REGISTER_PREFIX.length(),expiredKey.length()); + ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGbId); if (platform != null) { - publisher.platformRegisterCycleEventPublish(platformGBId); - } - }else if (expiredKey.startsWith(KEEPLIVEKEY_PREFIX)){ - String deviceId = expiredKey.substring(KEEPLIVEKEY_PREFIX.length(),expiredKey.length()); - Device device = storager.queryVideoDevice(deviceId); - if (device != null) { - publisher.outlineEventPublish(deviceId, KEEPLIVEKEY_PREFIX); + publisher.platformRegisterCycleEventPublish(platformGbId); } }else if (expiredKey.startsWith(REGISTER_INFO_PREFIX)) { String callId = expiredKey.substring(REGISTER_INFO_PREFIX.length()); @@ -85,6 +77,5 @@ public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEvent sipSubscribe.getErrorSubscribe(callId).response(eventResult); } } - } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java deleted file mode 100644 index 9e8c6471..00000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.genersoft.iot.vmp.gb28181.event.offline; - -import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener; -import com.genersoft.iot.vmp.conf.UserSetting; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.connection.Message; -import org.springframework.data.redis.listener.RedisMessageListenerContainer; -import org.springframework.stereotype.Component; - -import com.genersoft.iot.vmp.common.VideoManagerConstants; -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; - -/** - * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件 - * @author: swwheihei - * @date: 2020年5月6日 上午11:35:46 - */ -@Component -public class KeepliveTimeoutListener extends RedisKeyExpirationEventMessageListener { - - private Logger logger = LoggerFactory.getLogger(KeepliveTimeoutListener.class); - - @Autowired - private EventPublisher publisher; - - @Autowired - private UserSetting userSetting; - - public KeepliveTimeoutListener(RedisMessageListenerContainer listenerContainer, UserSetting userSetting) { - super(listenerContainer, userSetting); - } - - @Override - public void init() { - if (!userSetting.getRedisConfig()) { - // 配置springboot默认Config为空,即不让应用去修改redis的默认配置,因为Redis服务出于安全会禁用CONFIG命令给远程用户使用 - setKeyspaceNotificationsConfigParameter(""); - } - super.init(); - } - - - /** - * 监听失效的key,key格式为keeplive_deviceId - * @param message - * @param pattern - */ - @Override - public void onMessage(Message message, byte[] pattern) { - // 获取失效的key - String expiredKey = message.toString(); - String KEEPLIVEKEY_PREFIX = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_"; - if(!expiredKey.startsWith(KEEPLIVEKEY_PREFIX)){ - logger.debug("收到redis过期监听,但开头不是"+KEEPLIVEKEY_PREFIX+",忽略"); - return; - } - - String deviceId = expiredKey.substring(KEEPLIVEKEY_PREFIX.length(),expiredKey.length()); - publisher.outlineEventPublish(deviceId, VideoManagerConstants.EVENT_OUTLINE_TIMEOUT); - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java deleted file mode 100644 index 9dfeffca..00000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.genersoft.iot.vmp.gb28181.event.offline; - -import org.springframework.context.ApplicationEvent; - -/** - * @description: 离线事件类 - * @author: swwheihei - * @date: 2020年5月6日 上午11:33:13 - */ -public class OfflineEvent extends ApplicationEvent { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public OfflineEvent(Object source) { - super(source); - } - - private String deviceId; - - private String from; - - public String getDeviceId() { - return deviceId; - } - - public void setDeviceId(String deviceId) { - this.deviceId = deviceId; - } - - public String getFrom() { - return from; - } - - public void setFrom(String from) { - this.from = from; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java deleted file mode 100644 index 46332566..00000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.genersoft.iot.vmp.gb28181.event.offline; - -import com.genersoft.iot.vmp.conf.UserSetting; -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; -import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; -import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; -import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; -import com.genersoft.iot.vmp.service.IMediaServerService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.stereotype.Component; - -import com.genersoft.iot.vmp.common.VideoManagerConstants; -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; -import com.genersoft.iot.vmp.utils.redis.RedisUtil; - -import java.util.List; - -/** - * @description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源: - * 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.RegisterRequestProcessor} - * 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.event.offline.OfflineEventListener} - * @author: swwheihei - * @date: 2020年5月6日 下午1:51:23 - */ -@Component -public class OfflineEventListener implements ApplicationListener { - - private final static Logger logger = LoggerFactory.getLogger(OfflineEventListener.class); - - @Autowired - private IVideoManagerStorage storager; - - @Autowired - private VideoStreamSessionManager streamSession; - - @Autowired - private RedisUtil redis; - - @Autowired - private UserSetting userSetting; - - @Autowired - private EventPublisher eventPublisher; - - - @Autowired - private IMediaServerService mediaServerService; - - - @Autowired - private ZLMRTPServerFactory zlmrtpServerFactory; - - @Override - public void onApplicationEvent(OfflineEvent event) { - - logger.info("设备离线事件触发,deviceId:" + event.getDeviceId() + ",from:" + event.getFrom()); - - String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + event.getDeviceId(); - - switch (event.getFrom()) { - // 心跳超时触发的离线事件,说明redis中已删除,无需处理 - case VideoManagerConstants.EVENT_OUTLINE_TIMEOUT: - break; - // 设备主动注销触发的离线事件,需要删除redis中的超时监听 - case VideoManagerConstants.EVENT_OUTLINE_UNREGISTER: - redis.del(key); - break; - default: - boolean exist = redis.hasKey(key); - if (exist) { - redis.del(key); - } - } - - List deviceChannelList = storager.queryOnlineChannelsByDeviceId(event.getDeviceId()); - eventPublisher.catalogEventPublish(null, deviceChannelList, CatalogEvent.OFF); - // 处理离线监听 - storager.outline(event.getDeviceId()); - - // TODO 离线取消订阅 - - // 离线释放所有ssrc - List ssrcTransactions = streamSession.getSsrcTransactionForAll(event.getDeviceId(), null, null, null); - if (ssrcTransactions != null && ssrcTransactions.size() > 0) { - for (SsrcTransaction ssrcTransaction : ssrcTransactions) { - mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc()); - mediaServerService.closeRTPServer(event.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream()); - streamSession.remove(event.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream()); - } - } - - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java deleted file mode 100644 index 9aa9f8d7..00000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.genersoft.iot.vmp.gb28181.event.online; - -import com.genersoft.iot.vmp.gb28181.bean.Device; -import org.springframework.context.ApplicationEvent; - -/** - * @description: 在线事件类 - * @author: swwheihei - * @date: 2020年5月6日 上午11:32:56 - */ -public class OnlineEvent extends ApplicationEvent { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public OnlineEvent(Object source) { - super(source); - } - - private Device device; - - private String from; - - private int expires; - - public Device getDevice() { - return device; - } - - public void setDevice(Device device) { - this.device = device; - } - - public String getFrom() { - return from; - } - - public void setFrom(String from) { - this.from = from; - } - - public int getExpires() { - return expires; - } - - public void setExpires(int expires) { - this.expires = expires; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java deleted file mode 100644 index f32637e5..00000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.genersoft.iot.vmp.gb28181.event.online; - -import com.genersoft.iot.vmp.conf.SipConfig; -import com.genersoft.iot.vmp.conf.UserSetting; -import com.genersoft.iot.vmp.gb28181.bean.Device; -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; -import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; -import com.genersoft.iot.vmp.service.IDeviceService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.stereotype.Component; - -import com.genersoft.iot.vmp.common.VideoManagerConstants; -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; -import com.genersoft.iot.vmp.utils.redis.RedisUtil; - -import java.text.SimpleDateFormat; -import java.util.List; - -/** - * @description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源: - * 1、设备主动注销,发送注销指令 - * 2、设备未知原因离线,心跳超时 - * @author: swwheihei - * @date: 2020年5月6日 下午1:51:23 - */ -@Component -public class OnlineEventListener implements ApplicationListener { - - private final static Logger logger = LoggerFactory.getLogger(OnlineEventListener.class); - - @Autowired - private IVideoManagerStorage storager; - - @Autowired - private IDeviceService deviceService; - - @Autowired - private RedisUtil redis; - - @Autowired - private SipConfig sipConfig; - - @Autowired - private UserSetting userSetting; - - @Autowired - private EventPublisher eventPublisher; - - @Autowired - private SIPCommander cmder; - - - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - - @Override - public void onApplicationEvent(OnlineEvent event) { - - logger.info("设备上线事件触发,deviceId:" + event.getDevice().getDeviceId() + ",from:" + event.getFrom()); - Device device = event.getDevice(); - if (device == null) { - return; - } - String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + event.getDevice().getDeviceId(); - Device deviceInStore = storager.queryVideoDevice(device.getDeviceId()); - device.setOnline(1); - switch (event.getFrom()) { - // 注册时触发的在线事件,先在redis中增加超时超时监听 - case VideoManagerConstants.EVENT_ONLINE_REGISTER: - // 超时时间 - redis.set(key, event.getDevice().getDeviceId(), sipConfig.getKeepaliveTimeOut()); - device.setRegisterTime(format.format(System.currentTimeMillis())); - if (deviceInStore == null) { //第一次上线 - logger.info("[{}] 首次注册,查询设备信息以及通道信息", device.getDeviceId()); - cmder.deviceInfoQuery(device); - deviceService.sync(device); - } - break; - // 设备主动发送心跳触发的在线事件 - case VideoManagerConstants.EVENT_ONLINE_KEEPLIVE: - boolean exist = redis.hasKey(key); - // 先判断是否还存在,当设备先心跳超时后又发送心跳时,redis没有监听,需要增加 - if (!exist) { - redis.set(key, event.getDevice().getDeviceId(), sipConfig.getKeepaliveTimeOut()); - } else { - redis.expire(key, sipConfig.getKeepaliveTimeOut()); - } - device.setKeepaliveTime(format.format(System.currentTimeMillis())); - break; - // 设备主动发送消息触发的在线事件 - case VideoManagerConstants.EVENT_ONLINE_MESSAGE: - - break; - } - // 处理上线监听 - storager.updateDevice(device); - // 上线添加订阅 - if (device.getSubscribeCycleForCatalog() > 0) { - // 查询在线设备那些开启了订阅,为设备开启定时的目录订阅 - deviceService.addCatalogSubscribe(device); - } - if (device.getSubscribeCycleForMobilePosition() > 0) { - deviceService.addMobilePositionSubscribe(device); - } - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/conf/runner/SipDeviceRunner.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipDeviceRunner.java similarity index 54% rename from src/main/java/com/genersoft/iot/vmp/conf/runner/SipDeviceRunner.java rename to src/main/java/com/genersoft/iot/vmp/gb28181/task/SipDeviceRunner.java index 4a897968..91d8c3da 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/runner/SipDeviceRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipDeviceRunner.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.conf.runner; +package com.genersoft.iot.vmp.gb28181.task; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.Device; @@ -10,11 +10,13 @@ import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import java.util.ArrayList; import java.util.List; /** * 系统启动时控制设备 + * @author lin */ @Component @Order(value=4) @@ -34,26 +36,16 @@ public class SipDeviceRunner implements CommandLineRunner { @Override public void run(String... args) throws Exception { - // 读取redis没有心跳信息的则设置为离线,等收到下次心跳设置为在线 - // 设置所有设备离线 - storager.outlineForAll(); - List onlineForAll = redisCatchStorage.getOnlineForAll(); - for (String deviceId : onlineForAll) { - storager.online(deviceId); - Device device = redisCatchStorage.getDevice(deviceId); - if (device != null ) { - if (device.getSubscribeCycleForCatalog() > 0) { - // 查询在线设备那些开启了订阅,为设备开启定时的目录订阅 - deviceService.addCatalogSubscribe(device); - } - if (device.getSubscribeCycleForMobilePosition() > 0) { - deviceService.addMobilePositionSubscribe(device); - } + List deviceList = deviceService.getAllOnlineDevice(); + + for (Device device : deviceList) { + if (deviceService.expire(device)){ + deviceService.offline(device.getDeviceId()); + }else { + deviceService.online(device); } } // 重置cseq计数 redisCatchStorage.resetAllCSEQ(); - - } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index a9c9089c..a06a73d0 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -1,7 +1,10 @@ package com.genersoft.iot.vmp.gb28181.transmit; +import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; +import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.RegisterRequestProcessor; +import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd.KeepaliveNotifyMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.response.ISIPResponseProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.timeout.ITimeoutProcessor; import org.slf4j.Logger; @@ -11,10 +14,13 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import javax.sip.*; -import javax.sip.header.CSeqHeader; -import javax.sip.header.CallIdHeader; +import javax.sip.address.SipURI; +import javax.sip.address.URI; +import javax.sip.header.*; +import javax.sip.message.Request; import javax.sip.message.Response; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; /** @@ -34,10 +40,11 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { @Autowired private SipSubscribe sipSubscribe; + @Autowired + private EventPublisher eventPublisher; + + -// @Autowired -// @Qualifier(value = "taskExecutor") -// private ThreadPoolTaskExecutor poolTaskExecutor; /** * 添加 request订阅 @@ -141,9 +148,32 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { */ @Override public void processTimeout(TimeoutEvent timeoutEvent) { - if(timeoutProcessor != null) { - timeoutProcessor.process(timeoutEvent); + logger.info("[消息发送超时]"); + ClientTransaction clientTransaction = timeoutEvent.getClientTransaction(); + eventPublisher.requestTimeOut(timeoutEvent); + if (clientTransaction != null) { + Request request = clientTransaction.getRequest(); + if (request != null) { + CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME); + if (callIdHeader != null) { + SipSubscribe.Event subscribe = sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()); + SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(timeoutEvent); + subscribe.response(eventResult); + sipSubscribe.removeErrorSubscribe(callIdHeader.getCallId()); + } + } } + +// Timeout timeout = timeoutEvent.getTimeout(); +// ServerTransaction serverTransaction = timeoutEvent.getServerTransaction(); +// if (serverTransaction != null) { +// Request request = serverTransaction.getRequest(); +// URI requestURI = request.getRequestURI(); +// Header header = request.getHeader(FromHeader.NAME); +// } +// if(timeoutProcessor != null) { +// timeoutProcessor.process(timeoutEvent); +// } } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index ea8f2025..567bcac7 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; -import com.genersoft.iot.vmp.gb28181.utils.DateUtil; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; @@ -27,7 +27,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.SpringBootVersion; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java index 2aafd98d..a4fd5079 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java @@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider; -import com.genersoft.iot.vmp.gb28181.utils.DateUtil; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index bb46a71c..1ba1b3e7 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -23,6 +23,7 @@ import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.SerializeUtils; import gov.nist.javax.sdp.TimeDescriptionImpl; import gov.nist.javax.sdp.fields.TimeField; @@ -39,7 +40,6 @@ import javax.sip.header.CallIdHeader; import javax.sip.message.Request; import javax.sip.message.Response; import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.Date; import java.util.Vector; @@ -335,9 +335,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements sendRtpItem.setStreamId(ssrcInfo.getStream()); // 写入redis, 超时时回复 redisCatchStorage.updateSendRTPSever(sendRtpItem); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, format.format(start), - format.format(end), null, result -> { + playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.format.format(start), + DateUtil.format.format(end), null, result -> { if (result.getCode() != 0){ logger.warn("录像回放失败"); if (result.getEvent() != null) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java index 98cb3aa9..e923a54a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java @@ -252,14 +252,12 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader); - Element rootElement = getRootElement(evt); Device device = redisCatchStorage.getDevice(deviceId); - if (device == null) { + if (device == null || device.getOnline() == 0) { + logger.warn("[收到 目录订阅]:{}, 但是设备已经离线", (device != null ? device.getDeviceId():"" )); return; } - if (device != null ) { - rootElement = getRootElement(evt, device.getCharset()); - } + Element rootElement = getRootElement(evt, device.getCharset()); Element deviceListElement = rootElement.element("DeviceList"); if (deviceListElement == null) { return; @@ -279,39 +277,46 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements channel.setDeviceId(device.getDeviceId()); logger.info("[收到 目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId()); switch (eventElement.getText().toUpperCase()) { - case CatalogEvent.ON: // 上线 + case CatalogEvent.ON: + // 上线 logger.info("收到来自设备【{}】的通道【{}】上线通知", device.getDeviceId(), channel.getChannelId()); storager.deviceChannelOnline(deviceId, channel.getChannelId()); // 回复200 OK responseAck(evt, Response.OK); break; - case CatalogEvent.OFF : // 离线 + case CatalogEvent.OFF : + // 离线 logger.info("收到来自设备【{}】的通道【{}】离线通知", device.getDeviceId(), channel.getChannelId()); storager.deviceChannelOffline(deviceId, channel.getChannelId()); // 回复200 OK responseAck(evt, Response.OK); break; - case CatalogEvent.VLOST: // 视频丢失 + case CatalogEvent.VLOST: + // 视频丢失 logger.info("收到来自设备【{}】的通道【{}】视频丢失通知", device.getDeviceId(), channel.getChannelId()); storager.deviceChannelOffline(deviceId, channel.getChannelId()); // 回复200 OK responseAck(evt, Response.OK); break; - case CatalogEvent.DEFECT: // 故障 + case CatalogEvent.DEFECT: + // 故障 // 回复200 OK responseAck(evt, Response.OK); break; - case CatalogEvent.ADD: // 增加 + case CatalogEvent.ADD: + // 增加 logger.info("收到来自设备【{}】的增加通道【{}】通知", device.getDeviceId(), channel.getChannelId()); storager.updateChannel(deviceId, channel); responseAck(evt, Response.OK); break; - case CatalogEvent.DEL: // 删除 + case CatalogEvent.DEL: + // 删除 logger.info("收到来自设备【{}】的删除通道【{}】通知", device.getDeviceId(), channel.getChannelId()); storager.delChannel(deviceId, channel.getChannelId()); responseAck(evt, Response.OK); break; - case CatalogEvent.UPDATE: // 更新 + case CatalogEvent.UPDATE: + // 更新 logger.info("收到来自设备【{}】的更新通道【{}】通知", device.getDeviceId(), channel.getChannelId()); storager.updateChannel(deviceId, channel); responseAck(evt, Response.OK); @@ -324,10 +329,6 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements eventPublisher.catalogEventPublish(null, channel, eventElement.getText().toUpperCase()); } - - if (!redisCatchStorage.deviceIsOnline(deviceId)) { - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE); - } } } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { e.printStackTrace(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index ce5ca439..4f5f96a7 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/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; import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; +import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import gov.nist.javax.sip.RequestEventExt; @@ -60,6 +61,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @Autowired private SIPProcessorObserver sipProcessorObserver; + @Autowired + private IDeviceService deviceService; + @Override public void afterPropertiesSet() throws Exception { // 添加消息处理的订阅 @@ -82,7 +86,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen Response response = null; boolean passwordCorrect = false; // 注册标志 0:未携带授权头或者密码错误 1:注册成功 2:注销成功 - int registerFlag = 0; + boolean registerFlag = false; FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); AddressImpl address = (AddressImpl) fromHeader.getAddress(); SipUri uri = (SipUri) address.getURI(); @@ -111,12 +115,8 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen return; } - Device deviceInRedis = redisCatchStorage.getDevice(deviceId); - Device device = storager.queryVideoDevice(deviceId); - if (deviceInRedis != null && device == null) { - // redis 存在脏数据 - redisCatchStorage.clearCatchByDeviceId(deviceId); - } + Device device = deviceService.queryDevice(deviceId); + // 携带授权头并且密码正确 response = getMessageFactory().createResponse(Response.OK, request); // 添加date头 @@ -154,20 +154,17 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen device.setStreamMode("UDP"); device.setCharset("GB2312"); device.setDeviceId(deviceId); - device.setFirsRegister(true); - } else { - device.setFirsRegister(device.getOnline() == 0); } device.setIp(received); device.setPort(rPort); device.setHostAddress(received.concat(":").concat(String.valueOf(rPort))); if (expiresHeader.getExpires() == 0) { // 注销成功 - registerFlag = 2; + registerFlag = false; } else { // 注册成功 device.setExpires(expiresHeader.getExpires()); - registerFlag = 1; + registerFlag = true; // 判断TCP还是UDP ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); String transport = reqViaHeader.getTransport(); @@ -177,12 +174,12 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen sendResponse(evt, response); // 注册成功 // 保存到redis - if (registerFlag == 1) { + if (registerFlag) { logger.info("[{}] 注册成功! deviceId:" + deviceId, requestAddress); - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_REGISTER, expiresHeader.getExpires()); - } else if (registerFlag == 2) { + deviceService.online(device); + } else { logger.info("[{}] 注销成功! deviceId:" + deviceId, requestAddress); - publisher.outlineEventPublish(deviceId, VideoManagerConstants.EVENT_OUTLINE_UNREGISTER); + deviceService.offline(deviceId); } } catch (SipException | InvalidArgumentException | NoSuchAlgorithmException | ParseException e) { e.printStackTrace(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java index 08a77518..56a4c49b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java @@ -1,14 +1,15 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd; -import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; +import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; +import com.genersoft.iot.vmp.utils.DateUtil; import org.dom4j.Element; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,24 +24,20 @@ import javax.sip.SipException; import javax.sip.header.ViaHeader; import javax.sip.message.Response; import java.text.ParseException; +import java.util.Calendar; +import java.util.Date; @Component public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { private Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class); - private final String cmdType = "Keepalive"; + private final static String cmdType = "Keepalive"; @Autowired private NotifyMessageHandler notifyMessageHandler; @Autowired - private EventPublisher publisher; - - @Autowired - private IVideoManagerStorage videoManagerStorager; - - @Autowired - private IRedisCatchStorage redisCatchStorage; + private IDeviceService deviceService; @Override public void afterPropertiesSet() throws Exception { @@ -49,29 +46,35 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp @Override public void handForDevice(RequestEvent evt, Device device, Element element) { - // 检查设备是否存在并在线, 不在线则设置为在线 + if (device == null) { + // 未注册的设备不做处理 + return; + } try { - if (device != null ) { + if (device.getOnline() == 1) { // 回复200 OK responseAck(evt, Response.OK); - // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息 - // 获取到通信地址等信息 - ViaHeader viaHeader = (ViaHeader) evt.getRequest().getHeader(ViaHeader.NAME); - String received = viaHeader.getReceived(); - int rPort = viaHeader.getRPort(); - // 解析本地地址替代 - if (StringUtils.isEmpty(received) || rPort == -1) { - received = viaHeader.getHost(); - rPort = viaHeader.getPort(); - } - if (device.getPort() != rPort) { - device.setPort(rPort); - device.setHostAddress(received.concat(":").concat(String.valueOf(rPort))); - videoManagerStorager.updateDevice(device); - redisCatchStorage.updateDevice(device); - } - if (!redisCatchStorage.deviceIsOnline(device.getDeviceId())) { - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE); + }else { + // 对于已经离线的设备判断他的注册是否已经过期 + if (!deviceService.expire(device)){ + device.setKeepaliveTime(DateUtil.getNow()); + // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息 + // 获取到通信地址等信息 + ViaHeader viaHeader = (ViaHeader) evt.getRequest().getHeader(ViaHeader.NAME); + String received = viaHeader.getReceived(); + int rPort = viaHeader.getRPort(); + // 解析本地地址替代 + if (StringUtils.isEmpty(received) || rPort == -1) { + received = viaHeader.getHost(); + rPort = viaHeader.getPort(); + } + if (device.getPort() != rPort) { + device.setPort(rPort); + device.setHostAddress(received.concat(":").concat(String.valueOf(rPort))); + } + deviceService.online(device); + // 回复200 OK + responseAck(evt, Response.OK); } } } catch (SipException e) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/RecordInfoQueryMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/RecordInfoQueryMessageHandler.java index efd6ffdf..4b6c9026 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/RecordInfoQueryMessageHandler.java +++ b/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; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.QueryMessageHandler; -import com.genersoft.iot.vmp.gb28181.utils.DateUtil; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.dao.dto.ChannelSourceInfo; import org.dom4j.Element; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java index 56b42caf..891b21da 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java +++ b/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; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -39,8 +38,6 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp private Logger logger = LoggerFactory.getLogger(CatalogResponseMessageHandler.class); private final String cmdType = "Catalog"; - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - @Autowired private ResponseMessageHandler responseMessageHandler; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceInfoResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceInfoResponseMessageHandler.java index 276be490..eb2c7b8f 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceInfoResponseMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceInfoResponseMessageHandler.java @@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; +import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import org.dom4j.DocumentException; @@ -29,6 +30,9 @@ import java.text.ParseException; import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText; +/** + * @author lin + */ @Component public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { @@ -53,6 +57,9 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent @Autowired private EventPublisher publisher; + @Autowired + private IDeviceService deviceService; + @Override public void afterPropertiesSet() throws Exception { responseMessageHandler.addHandler(cmdType, this); @@ -61,6 +68,11 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent @Override public void handForDevice(RequestEvent evt, Device device, Element rootElement) { logger.debug("接收到DeviceInfo应答消息"); + // 检查设备是否存在, 不存在则不回复 + if (device == null || device.getOnline() == 0) { + logger.warn("[接收到DeviceInfo应答消息,但是设备已经离线]:" + (device != null ? device.getDeviceId():"" )); + return; + } try { rootElement = getRootElement(evt, device.getCharset()); Element deviceIdElement = rootElement.element("DeviceID"); @@ -74,7 +86,8 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent if (StringUtils.isEmpty(device.getStreamMode())) { device.setStreamMode("UDP"); } - storager.updateDevice(device); + deviceService.updateDevice(device); +// storager.updateDevice(device); RequestMessage msg = new RequestMessage(); msg.setKey(key); @@ -82,9 +95,6 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent deferredResultHolder.invokeAllResult(msg); // 回复200 OK responseAck(evt, Response.OK); - if (redisCatchStorage.deviceIsOnline(device.getDeviceId())) { - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE); - } } catch (DocumentException e) { e.printStackTrace(); } catch (InvalidArgumentException e) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceStatusResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceStatusResponseMessageHandler.java index 4e2f7f74..1fed401a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceStatusResponseMessageHandler.java +++ b/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 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; +import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import org.dom4j.Element; import org.slf4j.Logger; @@ -24,6 +25,7 @@ import javax.sip.RequestEvent; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; +import java.util.Objects; @Component public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { @@ -34,12 +36,11 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen @Autowired private ResponseMessageHandler responseMessageHandler; - @Autowired private DeferredResultHolder deferredResultHolder; @Autowired - private EventPublisher publisher; + private IDeviceService deviceService; @Autowired private IRedisCatchStorage redisCatchStorage; @@ -53,6 +54,9 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen public void handForDevice(RequestEvent evt, Device device, Element element) { logger.info("接收到DeviceStatus应答消息"); // 检查设备是否存在, 不存在则不回复 + if (device == null) { + return; + } // 回复200 OK try { responseAck(evt, Response.OK); @@ -64,20 +68,23 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen e.printStackTrace(); } Element deviceIdElement = element.element("DeviceID"); + Element onlineElement = element.element("Online"); String channelId = deviceIdElement.getText(); JSONObject json = new JSONObject(); XmlUtil.node2Json(element, json); if (logger.isDebugEnabled()) { logger.debug(json.toJSONString()); } + String text = onlineElement.getText(); + if (Objects.equals(text.trim().toUpperCase(), "ONLINE")) { + deviceService.online(device); + }else { + deviceService.offline(device.getDeviceId()); + } RequestMessage msg = new RequestMessage(); msg.setKey(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + device.getDeviceId() + channelId); msg.setData(json); deferredResultHolder.invokeAllResult(msg); - - if (redisCatchStorage.deviceIsOnline(device.getDeviceId())) { - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE); - } } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java index 1c9ec21b..36626004 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java +++ b/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; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -33,8 +32,6 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent private Logger logger = LoggerFactory.getLogger(PresetQueryResponseMessageHandler.class); private final String cmdType = "PresetQuery"; - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - @Autowired private ResponseMessageHandler responseMessageHandler; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java index 45b7e56b..2de8ef16 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java +++ b/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; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; -import com.genersoft.iot.vmp.gb28181.utils.DateUtil; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import org.dom4j.DocumentException; import org.dom4j.Element; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java index 12829e90..02612093 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java @@ -55,9 +55,6 @@ public class ZLMRunner implements CommandLineRunner { @Autowired private DynamicTask dynamicTask; - @Qualifier("taskExecutor") - @Autowired - private ThreadPoolTaskExecutor taskExecutor; @Override public void run(String... strings) throws Exception { @@ -105,9 +102,7 @@ public class ZLMRunner implements CommandLineRunner { startGetMedia = new HashMap<>(); } startGetMedia.put(mediaServerItem.getId(), true); - taskExecutor.execute(()->{ - connectZlmServer(mediaServerItem); - }); + connectZlmServer(mediaServerItem); } String taskKey = "zlm-connect-timeout"; dynamicTask.startDelay(taskKey, ()->{ @@ -119,21 +114,37 @@ public class ZLMRunner implements CommandLineRunner { startGetMedia = null; } // TODO 清理数据库中与redis不匹配的zlm - }, 6 * 1000 ); + }, 60 * 1000 ); } @Async public void connectZlmServer(MediaServerItem mediaServerItem){ - ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem, 1); - if (zlmServerConfig != null) { - zlmServerConfig.setIp(mediaServerItem.getIp()); - zlmServerConfig.setHttpPort(mediaServerItem.getHttpPort()); + String connectZlmServerTaskKey = "connect-zlm-" + mediaServerItem.getId(); + ZLMServerConfig zlmServerConfigFirst = getMediaServerConfig(mediaServerItem); + if (zlmServerConfigFirst != null) { + zlmServerConfigFirst.setIp(mediaServerItem.getIp()); + zlmServerConfigFirst.setHttpPort(mediaServerItem.getHttpPort()); startGetMedia.remove(mediaServerItem.getId()); - mediaServerService.zlmServerOnline(zlmServerConfig); + mediaServerService.zlmServerOnline(zlmServerConfigFirst); + }else { + logger.info("[ {} ]-[ {}:{} ]主动连接失败, 清理相关资源, 开始尝试重试连接", + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + publisher.zlmOfflineEventPublish(mediaServerItem.getId()); } + + dynamicTask.startCron(connectZlmServerTaskKey, ()->{ + ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem); + if (zlmServerConfig != null) { + dynamicTask.stop(connectZlmServerTaskKey); + zlmServerConfig.setIp(mediaServerItem.getIp()); + zlmServerConfig.setHttpPort(mediaServerItem.getHttpPort()); + startGetMedia.remove(mediaServerItem.getId()); + mediaServerService.zlmServerOnline(zlmServerConfig); + } + }, 2000); } - public ZLMServerConfig getMediaServerConfig(MediaServerItem mediaServerItem, int index) { + public ZLMServerConfig getMediaServerConfig(MediaServerItem mediaServerItem) { if (startGetMedia == null) { return null;} if (!mediaServerItem.isDefaultServer() && mediaServerService.getOne(mediaServerItem.getId()) == null) { return null; @@ -149,53 +160,10 @@ public class ZLMRunner implements CommandLineRunner { zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); } } else { - logger.error("[ {} ]-[ {}:{} ]第{}次主动连接失败, 2s后重试", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort(), index); - if (index == 1 && !StringUtils.isEmpty(mediaServerItem.getId())) { - logger.info("[ {} ]-[ {}:{} ]第{}次主动连接失败, 开始清理相关资源", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort(), index); - publisher.zlmOfflineEventPublish(mediaServerItem.getId()); - } - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - zlmServerConfig = getMediaServerConfig(mediaServerItem, index += 1); + logger.error("[ {} ]-[ {}:{} ]主动连接失败, 2s后重试", + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); } return zlmServerConfig; } - - /** - * zlm 连接成功或者zlm重启后 - */ -// private void zLmRunning(ZLMServerConfig zlmServerConfig){ -// logger.info( "[ id: " + zlmServerConfig.getGeneralMediaServerId() + "] zlm接入成功..."); -// // 关闭循环获取zlm配置 -// startGetMedia = false; -// MediaServerItem mediaServerItem = new MediaServerItem(zlmServerConfig, sipIp); -// storager.updateMediaServer(mediaServerItem); -// -// if (mediaServerItem.isAutoConfig()) setZLMConfig(mediaServerItem); -// zlmServerManger.updateServerCatchFromHook(zlmServerConfig); -// -// // 清空所有session -//// zlmMediaListManager.clearAllSessions(); -// -// // 更新流列表 -// zlmMediaListManager.updateMediaList(mediaServerItem); -// // 恢复流代理, 只查找这个这个流媒体 -// List streamProxyListForEnable = storager.getStreamProxyListForEnableInMediaServer( -// mediaServerItem.getId(), true); -// for (StreamProxyItem streamProxyDto : streamProxyListForEnable) { -// logger.info("恢复流代理," + streamProxyDto.getApp() + "/" + streamProxyDto.getStream()); -// JSONObject jsonObject = streamProxyService.addStreamProxyToZlm(streamProxyDto); -// if (jsonObject == null) { -// // 设置为未启用 -// logger.info("恢复流代理失败,请检查流地址后重新启用" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream()); -// streamProxyService.stop(streamProxyDto.getApp(), streamProxyDto.getStream()); -// } -// } -// } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMStatusEventListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMStatusEventListener.java index ca6fdfe4..b193add9 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMStatusEventListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMStatusEventListener.java @@ -7,12 +7,10 @@ import com.genersoft.iot.vmp.service.IStreamPushService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; -import java.text.SimpleDateFormat; /** * @description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源: @@ -38,13 +36,11 @@ public class ZLMStatusEventListener { @Autowired private IPlayService playService; - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - @Async @EventListener public void onApplicationEvent(ZLMOnlineEvent event) { - logger.info("ZLM上线事件触发,ID:" + event.getMediaServerId()); + logger.info("【ZLM上线】ID:" + event.getMediaServerId()); streamPushService.zlmServerOnline(event.getMediaServerId()); streamProxyService.zlmServerOnline(event.getMediaServerId()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java b/src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java index 5621d2aa..72af803d 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java @@ -3,56 +3,111 @@ package com.genersoft.iot.vmp.service; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.SyncStatus; +import java.util.List; + /** * 设备相关业务处理 + * @author lin */ public interface IDeviceService { + /** + * 设备上线 + * @param device 设备信息 + */ + void online(Device device); + + /** + * 设备下线 + * @param deviceId 设备编号 + */ + void offline(String deviceId); + /** * 添加目录订阅 * @param device 设备信息 - * @return + * @return 布尔 */ boolean addCatalogSubscribe(Device device); /** * 移除目录订阅 * @param device 设备信息 - * @return + * @return 布尔 */ boolean removeCatalogSubscribe(Device device); /** * 添加移动位置订阅 * @param device 设备信息 - * @return + * @return 布尔 */ boolean addMobilePositionSubscribe(Device device); /** * 移除移动位置订阅 * @param device 设备信息 - * @return + * @return 布尔 */ boolean removeMobilePositionSubscribe(Device device); /** * 移除移动位置订阅 * @param deviceId 设备ID - * @return + * @return 同步状态 */ SyncStatus getChannelSyncStatus(String deviceId); /** * 查看是否仍在同步 * @param deviceId 设备ID - * @return + * @return 布尔 */ Boolean isSyncRunning(String deviceId); /** * 通道同步 - * @param device + * @param device 设备信息 */ void sync(Device device); + + /** + * 查询设备信息 + * @param deviceId 设备编号 + * @return 设备信息 + */ + Device queryDevice(String deviceId); + + /** + * 获取所有在线设备 + * @return 设备列表 + */ + List getAllOnlineDevice(); + + /** + * 判断是否注册已经失效 + * @param device 设备信息 + * @return 布尔 + */ + boolean expire(Device device); + + /** + * 检查设备状态 + * @param device 设备信息 + */ + void checkDeviceStatus(Device device); + + /** + * 根据IP和端口获取设备信息 + * @param host IP + * @param port 端口 + * @return 设备信息 + */ + Device getDeviceByHostAndPort(String host, int port); + + /** + * 更新设备 + * @param device 设备信息 + */ + void updateDevice(Device device); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java index 39a59f80..2bf1b276 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java @@ -2,21 +2,33 @@ package com.genersoft.iot.vmp.service.impl; import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.CatalogResponseMessageHandler; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask; import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask; import com.genersoft.iot.vmp.gb28181.bean.SyncStatus; +import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; +import com.genersoft.iot.vmp.storager.dao.DeviceMapper; +import com.genersoft.iot.vmp.utils.DateUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; import javax.sip.DialogState; +import javax.sip.TimeoutEvent; +import java.text.ParseException; +import java.util.Calendar; +import java.util.Date; +import java.util.List; /** * 设备业务(目录订阅) @@ -26,6 +38,8 @@ public class DeviceServiceImpl implements IDeviceService { private final static Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class); + private final String registerExpireTaskKeyPrefix = "device-register-expire-"; + @Autowired private DynamicTask dynamicTask; @@ -38,6 +52,90 @@ public class DeviceServiceImpl implements IDeviceService { @Autowired private IRedisCatchStorage redisCatchStorage; + @Autowired + private DeviceMapper deviceMapper; + + @Autowired + private ISIPCommander commander; + + @Autowired + private VideoStreamSessionManager streamSession; + + @Autowired + private IMediaServerService mediaServerService; + + @Override + public void online(Device device) { + logger.info("[设备上线],deviceId:" + device.getDeviceId()); + Device deviceInRedis = redisCatchStorage.getDevice(device.getDeviceId()); + Device deviceInDb = deviceMapper.getDeviceByDeviceId(device.getDeviceId()); + + String now = DateUtil.getNow(); + if (deviceInRedis != null && deviceInDb == null) { + // redis 存在脏数据 + redisCatchStorage.clearCatchByDeviceId(device.getDeviceId()); + + } + if (device.getRegisterTime() == null) { + device.setRegisterTime(now); + } + if(device.getUpdateTime() == null) { + device.setUpdateTime(now); + } + device.setOnline(1); + + // 第一次上线 + if (device.getCreateTime() == null) { + device.setCreateTime(now); + logger.info("[设备上线,首次注册]: {},查询设备信息以及通道信息", device.getDeviceId()); + commander.deviceInfoQuery(device); + sync(device); + deviceMapper.add(device); + }else { + deviceMapper.update(device); + } + redisCatchStorage.updateDevice(device); + // 上线添加订阅 + if (device.getSubscribeCycleForCatalog() > 0) { + // 查询在线设备那些开启了订阅,为设备开启定时的目录订阅 + addCatalogSubscribe(device); + } + if (device.getSubscribeCycleForMobilePosition() > 0) { + addMobilePositionSubscribe(device); + } + // 刷新过期任务 + String registerExpireTaskKey = registerExpireTaskKeyPrefix + device.getDeviceId(); + dynamicTask.stop(registerExpireTaskKey); + dynamicTask.startDelay(registerExpireTaskKey, ()->{ + offline(device.getDeviceId()); + }, device.getExpires() * 1000); + } + + @Override + public void offline(String deviceId) { + Device device = deviceMapper.getDeviceByDeviceId(deviceId); + if (device == null) { + return; + } + String registerExpireTaskKey = registerExpireTaskKeyPrefix + deviceId; + dynamicTask.stop(registerExpireTaskKey); + device.setOnline(0); + redisCatchStorage.updateDevice(device); + deviceMapper.update(device); + // 离线释放所有ssrc + List ssrcTransactions = streamSession.getSsrcTransactionForAll(deviceId, null, null, null); + if (ssrcTransactions != null && ssrcTransactions.size() > 0) { + for (SsrcTransaction ssrcTransaction : ssrcTransactions) { + mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc()); + mediaServerService.closeRTPServer(deviceId, ssrcTransaction.getChannelId(), ssrcTransaction.getStream()); + streamSession.remove(deviceId, ssrcTransaction.getChannelId(), ssrcTransaction.getStream()); + } + } + // 移除订阅 + removeCatalogSubscribe(device); + removeMobilePositionSubscribe(device); + } + @Override public boolean addCatalogSubscribe(Device device) { if (device == null || device.getSubscribeCycleForCatalog() < 0) { @@ -49,7 +147,7 @@ public class DeviceServiceImpl implements IDeviceService { // 提前开始刷新订阅 int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForCatalog(),30); // 设置最小值为30 - dynamicTask.startCron(device.getDeviceId() + "catalog", catalogSubscribeTask, subscribeCycleForCatalog -1); + dynamicTask.startCron(device.getDeviceId() + "catalog", catalogSubscribeTask, (subscribeCycleForCatalog -1) * 1000); return true; } @@ -74,7 +172,7 @@ public class DeviceServiceImpl implements IDeviceService { // 设置最小值为30 int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForMobilePosition(),30); // 提前开始刷新订阅 - dynamicTask.startCron(device.getDeviceId() + "mobile_position" , mobilePositionSubscribeTask, subscribeCycleForCatalog -1 ); + dynamicTask.startCron(device.getDeviceId() + "mobile_position" , mobilePositionSubscribeTask, (subscribeCycleForCatalog -1 ) * 1000); return true; } @@ -111,4 +209,101 @@ public class DeviceServiceImpl implements IDeviceService { catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), errorMsg); }); } + + @Override + public Device queryDevice(String deviceId) { + return deviceMapper.getDeviceByDeviceId(deviceId); + } + + @Override + public List getAllOnlineDevice() { + return deviceMapper.getOnlineDevices(); + } + + @Override + public boolean expire(Device device) { + Date registerTimeDate; + try { + registerTimeDate = DateUtil.format.parse(device.getRegisterTime()); + } catch (ParseException e) { + logger.error("设备时间格式化失败:{}->{} ", device.getDeviceId(), device.getRegisterTime() ); + return false; + } + int expires = device.getExpires(); + Calendar calendarForExpire = Calendar.getInstance(); + calendarForExpire.setTime(registerTimeDate); + calendarForExpire.set(Calendar.SECOND, calendarForExpire.get(Calendar.SECOND) + expires); + return calendarForExpire.before(DateUtil.getNow()); + } + + @Override + public void checkDeviceStatus(Device device) { + if (device == null || device.getOnline() == 0) { + return; + } + sipCommander.deviceStatusQuery(device, null); + + } + + @Override + public Device getDeviceByHostAndPort(String host, int port) { + return deviceMapper.getDeviceByHostAndPort(host, port); + } + + @Override + public void updateDevice(Device device) { + + Device deviceInStore = deviceMapper.getDeviceByDeviceId(device.getDeviceId()); + if (deviceInStore == null) { + logger.warn("更新设备时未找到设备信息"); + return; + } + if (!StringUtils.isEmpty(device.getName())) { + deviceInStore.setName(device.getName()); + } + if (!StringUtils.isEmpty(device.getCharset())) { + deviceInStore.setCharset(device.getCharset()); + } + if (!StringUtils.isEmpty(device.getMediaServerId())) { + deviceInStore.setMediaServerId(device.getMediaServerId()); + } + + // 目录订阅相关的信息 + if (device.getSubscribeCycleForCatalog() > 0) { + if (deviceInStore.getSubscribeCycleForCatalog() == 0 || deviceInStore.getSubscribeCycleForCatalog() != device.getSubscribeCycleForCatalog()) { + deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog()); + // 开启订阅 + addCatalogSubscribe(deviceInStore); + } + }else if (device.getSubscribeCycleForCatalog() == 0) { + if (deviceInStore.getSubscribeCycleForCatalog() != 0) { + deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog()); + // 取消订阅 + removeCatalogSubscribe(deviceInStore); + } + } + + // 移动位置订阅相关的信息 + if (device.getSubscribeCycleForMobilePosition() > 0) { + if (deviceInStore.getSubscribeCycleForMobilePosition() == 0 || deviceInStore.getSubscribeCycleForMobilePosition() != device.getSubscribeCycleForMobilePosition()) { + deviceInStore.setMobilePositionSubmissionInterval(device.getMobilePositionSubmissionInterval()); + deviceInStore.setSubscribeCycleForMobilePosition(device.getSubscribeCycleForMobilePosition()); + // 开启订阅 + addMobilePositionSubscribe(deviceInStore); + } + }else if (device.getSubscribeCycleForMobilePosition() == 0) { + if (deviceInStore.getSubscribeCycleForMobilePosition() != 0) { + // 取消订阅 + removeMobilePositionSubscribe(deviceInStore); + } + } + + String now = DateUtil.getNow(); + device.setUpdateTime(now); + device.setCharset(device.getCharset().toUpperCase()); + device.setUpdateTime(DateUtil.getNow()); + if (deviceMapper.update(device) > 0) { + redisCatchStorage.updateDevice(device); + } + } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java index e311890c..a690c1bd 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java @@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.dao.MediaServerMapper; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.redis.JedisUtil; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; @@ -89,8 +90,6 @@ public class MediaServerServiceImpl implements IMediaServerService { @Autowired JedisUtil jedisUtil; - private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - /** * 初始化 */ @@ -231,7 +230,7 @@ public class MediaServerServiceImpl implements IMediaServerService { result.sort((serverItem1, serverItem2)->{ int sortResult = 0; try { - sortResult = format.parse(serverItem1.getCreateTime()).compareTo(format.parse(serverItem2.getCreateTime())); + sortResult = DateUtil.format.parse(serverItem1.getCreateTime()).compareTo(DateUtil.format.parse(serverItem2.getCreateTime())); } catch (ParseException e) { e.printStackTrace(); } @@ -291,8 +290,8 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override public WVPResult add(MediaServerItem mediaServerItem) { WVPResult result = new WVPResult<>(); - mediaServerItem.setCreateTime(this.format.format(System.currentTimeMillis())); - mediaServerItem.setUpdateTime(this.format.format(System.currentTimeMillis())); + mediaServerItem.setCreateTime(DateUtil.getNow()); + mediaServerItem.setUpdateTime(DateUtil.getNow()); mediaServerItem.setHookAliveInterval(120); JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); if (responseJSON != null) { diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index f2b6c282..4372f8eb 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; -import com.genersoft.iot.vmp.gb28181.utils.DateUtil; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java index 2bff8643..ef5932d4 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java @@ -4,20 +4,15 @@ import com.alibaba.fastjson.JSON; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; -import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; +import com.genersoft.iot.vmp.utils.DateUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.MessageListener; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; -import java.text.SimpleDateFormat; @Component public class RedisAlarmMsgListener implements MessageListener { @@ -33,8 +28,6 @@ public class RedisAlarmMsgListener implements MessageListener { @Autowired private IVideoManagerStorage storage; - private final SimpleDateFormat formatForGB = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); - @Override public void onMessage(Message message, byte[] bytes) { logger.info("收到来自REDIS的ALARM通知: {}", new String(message.getBody())); @@ -52,7 +45,7 @@ public class RedisAlarmMsgListener implements MessageListener { deviceAlarm.setAlarmDescription(alarmChannelMessage.getAlarmDescription()); deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn()); deviceAlarm.setAlarmPriority("1"); - deviceAlarm.setAlarmTime(formatForGB.format(System.currentTimeMillis())); + deviceAlarm.setAlarmTime(DateUtil.getNow()); deviceAlarm.setAlarmType("1"); deviceAlarm.setLongitude(0); deviceAlarm.setLatitude(0); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java index 67697c8d..4a3aa78b 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java @@ -111,23 +111,6 @@ public interface IRedisCatchStorage { */ void clearCatchByDeviceId(String deviceId); - /** - * 获取mediaServer节点 - * @param mediaServerId - * @return - */ -// MediaServerItem getMediaInfo(String mediaServerId); - - /** - * 设置所有设备离线 - */ - void outlineForAll(); - - /** - * 获取所有在线的 - */ - List getOnlineForAll(); - /** * 在redis添加wvp的信息 */ diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java index a29b7ae9..d94669b8 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java @@ -25,22 +25,6 @@ public interface IVideoManagerStorage { * @return true:存在 false:不存在 */ public boolean exists(String deviceId); - - /** - * 视频设备创建 - * - * @param device 设备对象 - * @return true:创建成功 false:创建失败 - */ - public boolean create(Device device); - - /** - * 视频设备更新 - * - * @param device 设备对象 - * @return true:创建成功 false:创建失败 - */ - public boolean updateDevice(Device device); /** * 添加设备通道 diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java index 97cf2ccf..37d951e2 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java @@ -99,4 +99,9 @@ public interface DeviceMapper { @Update("UPDATE device SET online=0") int outlineForAll(); + + @Select("SELECT * FROM device WHERE online = 1") + List getOnlineDevices(); + @Select("SELECT * FROM device WHERE ip = #{host} AND port=${port}") + Device getDeviceByHostAndPort(String host, int port); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java index ae7647f8..39daeda9 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -14,13 +14,13 @@ import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.text.SimpleDateFormat; import java.util.*; @SuppressWarnings("rawtypes") @@ -38,8 +38,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @Autowired private UserSetting userSetting; - private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - @Override public Long getCSEQ(String method) { String key = VideoManagerConstants.SIP_CSEQ_PREFIX + userSetting.getServerId() + "_" + method; @@ -469,26 +467,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { } } - @Override - public void outlineForAll() { - List onlineDevices = redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + "*" ); - for (int i = 0; i < onlineDevices.size(); i++) { - String key = (String) onlineDevices.get(i); - redis.del(key); - } - } - - @Override - public List getOnlineForAll() { - List result = new ArrayList<>(); - List onlineDevices = redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + "*" ); - for (int i = 0; i < onlineDevices.size(); i++) { - String key = (String) onlineDevices.get(i); - result.add((String) redis.get(key)); - } - return result; - } - @Override public void updateWVPInfo(JSONObject jsonObject, int time) { String key = VideoManagerConstants.WVP_SERVER_PREFIX + userSetting.getServerId(); @@ -638,7 +616,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { public void addCpuInfo(double cpuInfo) { String key = VideoManagerConstants.SYSTEM_INFO_CPU_PREFIX + userSetting.getServerId(); SystemInfoDto systemInfoDto = new SystemInfoDto<>(); - systemInfoDto.setTime(format.format(System.currentTimeMillis())); + systemInfoDto.setTime(DateUtil.getNow()); systemInfoDto.setData(cpuInfo); redis.lSet(key, systemInfoDto); // 每秒一个,最多只存30个 @@ -653,7 +631,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { public void addMemInfo(double memInfo) { String key = VideoManagerConstants.SYSTEM_INFO_MEM_PREFIX + userSetting.getServerId(); SystemInfoDto systemInfoDto = new SystemInfoDto<>(); - systemInfoDto.setTime(format.format(System.currentTimeMillis())); + systemInfoDto.setTime(DateUtil.getNow()); systemInfoDto.setData(memInfo); redis.lSet(key, systemInfoDto); // 每秒一个,最多只存30个 @@ -668,7 +646,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { public void addNetInfo(Map networkInterfaces) { String key = VideoManagerConstants.SYSTEM_INFO_NET_PREFIX + userSetting.getServerId(); SystemInfoDto> systemInfoDto = new SystemInfoDto<>(); - systemInfoDto.setTime(format.format(System.currentTimeMillis())); + systemInfoDto.setTime(DateUtil.getNow()); systemInfoDto.setData(networkInterfaces); redis.lSet(key, systemInfoDto); // 每秒一个,最多只存30个 @@ -702,7 +680,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @Override public boolean deviceIsOnline(String deviceId) { - String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + deviceId; - return redis.hasKey(key); + return getDevice(deviceId).getOnline() == 1; } } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java index 2dc88f8d..eea07e94 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java @@ -13,6 +13,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.dao.*; import com.genersoft.iot.vmp.storager.dao.dto.ChannelSourceInfo; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; @@ -26,7 +27,6 @@ import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; -import java.text.SimpleDateFormat; import java.util.*; /** @@ -91,9 +91,6 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { @Autowired private ParentPlatformMapper parentPlatformMapper; - private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - - /** * 根据设备ID判断设备是否存在 * @@ -105,45 +102,6 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { return deviceMapper.getDeviceByDeviceId(deviceId) != null; } - /** - * 视频设备创建 - * - * @param device 设备对象 - * @return true:创建成功 false:创建失败 - */ - @Override - public synchronized boolean create(Device device) { - redisCatchStorage.updateDevice(device); - return deviceMapper.add(device) > 0; - } - - - - /** - * 视频设备更新 - * - * @param device 设备对象 - * @return true:更新成功 false:更新失败 - */ - @Override - public synchronized boolean updateDevice(Device device) { - String now = this.format.format(System.currentTimeMillis()); - device.setUpdateTime(now); - Device deviceByDeviceId = deviceMapper.getDeviceByDeviceId(device.getDeviceId()); - device.setCharset(device.getCharset().toUpperCase()); - if (deviceByDeviceId == null) { - device.setCreateTime(now); - redisCatchStorage.updateDevice(device); - return deviceMapper.add(device) > 0; - }else { - redisCatchStorage.updateDevice(device); - - return deviceMapper.update(device) > 0; - } - - - } - @Override public synchronized void updateChannel(String deviceId, DeviceChannel channel) { String channelId = channel.getChannelId(); @@ -152,7 +110,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { if (streamInfo != null) { channel.setStreamId(streamInfo.getStream()); } - String now = this.format.format(System.currentTimeMillis()); + String now = DateUtil.getNow(); channel.setUpdateTime(now); DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId); if (deviceChannel == null) { @@ -178,7 +136,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { if (streamInfo != null) { channel.setStreamId(streamInfo.getStream()); } - String now = this.format.format(System.currentTimeMillis()); + String now = DateUtil.getNow(); channel.setUpdateTime(now); channel.setCreateTime(now); addChannels.add(channel); @@ -193,7 +151,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { if (streamInfo != null) { channel.setStreamId(streamInfo.getStream()); } - String now = this.format.format(System.currentTimeMillis()); + String now = DateUtil.getNow(); channel.setUpdateTime(now); if (channelsInStore.get(channel.getChannelId()) != null) { updateChannels.add(channel); @@ -732,7 +690,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { boolean result = false; streamProxyItem.setStreamType("proxy"); streamProxyItem.setStatus(true); - String now = this.format.format(System.currentTimeMillis()); + String now = DateUtil.getNow(); streamProxyItem.setCreateTime(now); streamProxyItem.setCreateStamp(System.currentTimeMillis()); try { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java b/src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java similarity index 52% rename from src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java rename to src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java index 604c0835..1be0f407 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java @@ -1,57 +1,57 @@ -package com.genersoft.iot.vmp.gb28181.utils; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; - -/** - * @description:时间工具类,主要处理ISO 8601格式转换 - * @author: swwheihei - * @date: 2020年5月8日 下午3:24:42 - */ -public class DateUtil { - - //private static final String yyyy_MM_dd_T_HH_mm_ss_SSSXXX = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"; - private static final String yyyy_MM_dd_T_HH_mm_ss_SSSXXX = "yyyy-MM-dd'T'HH:mm:ss"; - private static final String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss"; - - public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) { - - SimpleDateFormat oldsdf = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss, Locale.getDefault()); - SimpleDateFormat newsdf = new SimpleDateFormat(yyyy_MM_dd_T_HH_mm_ss_SSSXXX, Locale.getDefault()); - try { - return newsdf.format(oldsdf.parse(formatTime)); - } catch (ParseException e) { - e.printStackTrace(); - } - return ""; - } - - public static String ISO8601Toyyyy_MM_dd_HH_mm_ss(String formatTime) { - - SimpleDateFormat oldsdf = new SimpleDateFormat(yyyy_MM_dd_T_HH_mm_ss_SSSXXX, Locale.getDefault()); - SimpleDateFormat newsdf = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss, Locale.getDefault()); - try { - return newsdf.format(oldsdf.parse(formatTime)); - } catch (ParseException e) { - e.printStackTrace(); - } - return ""; - } - - public static long yyyy_MM_dd_HH_mm_ssToTimestamp(String formatTime) { - SimpleDateFormat format=new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss); - //设置要读取的时间字符串格式 - Date date; - try { - date = format.parse(formatTime); - Long timestamp=date.getTime()/1000; - //转换为Date类 - return timestamp; - } catch (ParseException e) { - e.printStackTrace(); - } - return 0; - } -} +package com.genersoft.iot.vmp.utils; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +/** + * 全局时间工具类 + * @author swwheihei + */ +public class DateUtil { + + private static final String yyyy_MM_dd_T_HH_mm_ss_SSSXXX = "yyyy-MM-dd'T'HH:mm:ss"; + private static final String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss"; + + public static final SimpleDateFormat formatISO8601 = new SimpleDateFormat(yyyy_MM_dd_T_HH_mm_ss_SSSXXX, Locale.getDefault()); + public static final SimpleDateFormat format = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss, Locale.getDefault()); + + public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) { + + try { + return formatISO8601.format(format.parse(formatTime)); + } catch (ParseException e) { + e.printStackTrace(); + } + return ""; + } + + public static String ISO8601Toyyyy_MM_dd_HH_mm_ss(String formatTime) { + + try { + return format.format(formatISO8601.parse(formatTime)); + } catch (ParseException e) { + e.printStackTrace(); + } + return ""; + } + + public static long yyyy_MM_dd_HH_mm_ssToTimestamp(String formatTime) { + //设置要读取的时间字符串格式 + Date date; + try { + date = format.parse(formatTime); + Long timestamp=date.getTime()/1000; + //转换为Date类 + return timestamp; + } catch (ParseException e) { + e.printStackTrace(); + } + return 0; + } + + public static String getNow() { + return format.format(System.currentTimeMillis()); + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java index 7d11b15c..fa12f5d9 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java @@ -169,7 +169,7 @@ public class MobilePositionController { Device device = storager.queryVideoDevice(deviceId); device.setSubscribeCycleForMobilePosition(Integer.parseInt(expires)); device.setMobilePositionSubmissionInterval(Integer.parseInt(interval)); - storager.updateDevice(device); + deviceService.updateDevice(device); String result = msg; if (deviceService.removeMobilePositionSubscribe(device)) { result += ",成功"; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/alarm/AlarmController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/alarm/AlarmController.java index addc431e..56864dbc 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/alarm/AlarmController.java +++ b/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; import com.genersoft.iot.vmp.service.IDeviceAlarmService; import com.genersoft.iot.vmp.service.IGbStreamService; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.github.pagehelper.PageInfo; import io.swagger.annotations.Api; @@ -23,9 +24,7 @@ import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.Arrays; -import java.util.Date; import java.util.List; @Api(tags = "报警信息管理") @@ -46,9 +45,6 @@ public class AlarmController { @Autowired private IVideoManagerStorage storage; - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private SimpleDateFormat formatForGB = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); - /** * 分页查询报警 * @@ -104,10 +100,10 @@ public class AlarmController { try { if (startTime != null) { - format.parse(startTime); + DateUtil.format.parse(startTime); } if (endTime != null) { - format.parse(endTime); + DateUtil.format.parse(endTime); } } catch (ParseException e) { return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); @@ -150,7 +146,7 @@ public class AlarmController { } try { if (time != null) { - format.parse(time); + DateUtil.format.parse(time); } } catch (ParseException e) { return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); @@ -193,7 +189,7 @@ public class AlarmController { deviceAlarm.setAlarmDescription("test"); deviceAlarm.setAlarmMethod("1"); deviceAlarm.setAlarmPriority("1"); - deviceAlarm.setAlarmTime(formatForGB.format(System.currentTimeMillis())); + deviceAlarm.setAlarmTime(DateUtil.formatISO8601.format(System.currentTimeMillis())); deviceAlarm.setAlarmType("1"); deviceAlarm.setLongitude(115.33333); deviceAlarm.setLatitude(39.33333); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java index d6e614d9..3e538486 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java @@ -288,7 +288,8 @@ public class DeviceQuery { public ResponseEntity updateTransport(@PathVariable String deviceId, @PathVariable String streamMode){ Device device = storager.queryVideoDevice(deviceId); device.setStreamMode(streamMode); - storager.updateDevice(device); +// storager.updateDevice(device); + deviceService.updateDevice(device); return new ResponseEntity<>(null,HttpStatus.OK); } @@ -305,51 +306,12 @@ public class DeviceQuery { public ResponseEntity> updateDevice(Device device){ if (device != null && device.getDeviceId() != null) { - Device deviceInStore = storager.queryVideoDevice(device.getDeviceId()); - if (!StringUtils.isEmpty(device.getName())) { - deviceInStore.setName(device.getName()); - } - if (!StringUtils.isEmpty(device.getCharset())) { - deviceInStore.setCharset(device.getCharset()); - } - if (!StringUtils.isEmpty(device.getMediaServerId())) { - deviceInStore.setMediaServerId(device.getMediaServerId()); - } - // 目录订阅相关的信息 - if (device.getSubscribeCycleForCatalog() > 0) { - if (deviceInStore.getSubscribeCycleForCatalog() == 0 || deviceInStore.getSubscribeCycleForCatalog() != device.getSubscribeCycleForCatalog()) { - deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog()); - // 开启订阅 - deviceService.addCatalogSubscribe(deviceInStore); - } - }else if (device.getSubscribeCycleForCatalog() == 0) { - if (deviceInStore.getSubscribeCycleForCatalog() != 0) { - deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog()); - // 取消订阅 - deviceService.removeCatalogSubscribe(deviceInStore); - } - } - - // 移动位置订阅相关的信息 - if (device.getSubscribeCycleForMobilePosition() > 0) { - if (deviceInStore.getSubscribeCycleForMobilePosition() == 0 || deviceInStore.getSubscribeCycleForMobilePosition() != device.getSubscribeCycleForMobilePosition()) { - deviceInStore.setMobilePositionSubmissionInterval(device.getMobilePositionSubmissionInterval()); - deviceInStore.setSubscribeCycleForMobilePosition(device.getSubscribeCycleForMobilePosition()); - // 开启订阅 - deviceService.addMobilePositionSubscribe(deviceInStore); - } - }else if (device.getSubscribeCycleForMobilePosition() == 0) { - if (deviceInStore.getSubscribeCycleForMobilePosition() != 0) { - // 取消订阅 - deviceService.removeMobilePositionSubscribe(deviceInStore); - } - } // TODO 报警订阅相关的信息 - storager.updateDevice(device); - cmder.deviceInfoQuery(device); + deviceService.updateDevice(device); +// cmder.deviceInfoQuery(device); } WVPResult result = new WVPResult<>(); result.setCode(0); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java index 44b16883..65f5f7c7 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.vmanager.log; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.service.ILogService; import com.genersoft.iot.vmp.storager.dao.dto.LogDto; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.github.pagehelper.PageInfo; import io.swagger.annotations.Api; @@ -18,7 +19,6 @@ import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import java.text.ParseException; -import java.text.SimpleDateFormat; @Api(tags = "日志管理") @CrossOrigin @@ -34,8 +34,6 @@ public class LogController { @Autowired private UserSetting userSetting; - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - /** * 分页查询日志 * @@ -80,10 +78,10 @@ public class LogController { try { if (startTime != null) { - format.parse(startTime); + DateUtil.format.parse(startTime); } if (endTime != null) { - format.parse(endTime); + DateUtil.format.parse(endTime); } } catch (ParseException e) { return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/user/RoleController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/user/RoleController.java index 6a75e1dd..887eb46a 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/user/RoleController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/user/RoleController.java @@ -2,9 +2,8 @@ package com.genersoft.iot.vmp.vmanager.user; import com.genersoft.iot.vmp.conf.security.SecurityUtils; import com.genersoft.iot.vmp.service.IRoleService; -import com.genersoft.iot.vmp.service.IUserService; import com.genersoft.iot.vmp.storager.dao.dto.Role; -import com.genersoft.iot.vmp.storager.dao.dto.User; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; @@ -13,12 +12,8 @@ import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.util.DigestUtils; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; -import java.text.SimpleDateFormat; import java.util.List; @Api(tags = "角色管理") @@ -30,8 +25,6 @@ public class RoleController { @Autowired private IRoleService roleService; - private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - @ApiOperation("添加角色") @ApiImplicitParams({ @ApiImplicitParam(name = "name", required = true, value = "角色名", dataTypeClass = String.class), @@ -53,8 +46,8 @@ public class RoleController { Role role = new Role(); role.setName(name); role.setAuthority(authority); - role.setCreateTime(format.format(System.currentTimeMillis())); - role.setUpdateTime(format.format(System.currentTimeMillis())); + role.setCreateTime(DateUtil.getNow()); + role.setUpdateTime(DateUtil.getNow()); int addResult = roleService.add(role); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/user/UserController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/user/UserController.java index 17fe2fb6..152122d2 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/user/UserController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/user/UserController.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.service.IRoleService; import com.genersoft.iot.vmp.service.IUserService; import com.genersoft.iot.vmp.storager.dao.dto.Role; import com.genersoft.iot.vmp.storager.dao.dto.User; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; @@ -20,7 +21,6 @@ import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import javax.security.sasl.AuthenticationException; -import java.text.SimpleDateFormat; import java.util.List; @Api(tags = "用户管理") @@ -38,8 +38,6 @@ public class UserController { @Autowired private IRoleService roleService; - private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - @ApiOperation("登录") @ApiImplicitParams({ @ApiImplicitParam(name = "username", required = true, value = "用户名", dataTypeClass = String.class), @@ -135,8 +133,8 @@ public class UserController { return new ResponseEntity<>(result, HttpStatus.OK); } user.setRole(role); - user.setCreateTime(format.format(System.currentTimeMillis())); - user.setUpdateTime(format.format(System.currentTimeMillis())); + user.setCreateTime(DateUtil.getNow()); + user.setUpdateTime(DateUtil.getNow()); int addResult = userService.addUser(user); result.setCode(addResult > 0 ? 0 : -1); diff --git a/src/test/java/com/genersoft/iot/vmp/service/impl/DeviceAlarmServiceImplTest.java b/src/test/java/com/genersoft/iot/vmp/service/impl/DeviceAlarmServiceImplTest.java index 23b9f6b2..6d6ff37f 100644 --- a/src/test/java/com/genersoft/iot/vmp/service/impl/DeviceAlarmServiceImplTest.java +++ b/src/test/java/com/genersoft/iot/vmp/service/impl/DeviceAlarmServiceImplTest.java @@ -2,12 +2,12 @@ package com.genersoft.iot.vmp.service.impl; import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; import com.genersoft.iot.vmp.service.IDeviceAlarmService; +import com.genersoft.iot.vmp.utils.DateUtil; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; -import java.text.SimpleDateFormat; import java.util.Date; @@ -18,8 +18,6 @@ class DeviceAlarmServiceImplTest { @Resource private IDeviceAlarmService deviceAlarmService; - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - @org.junit.jupiter.api.Test void getAllAlarm() { // deviceAlarmService.getAllAlarm(0, 10000, "11111111111111111111",null,null,null, null, null); @@ -67,7 +65,7 @@ class DeviceAlarmServiceImplTest { */ deviceAlarm.setAlarmMethod((int)(Math.random()*7 + 1) + ""); Date date = randomDate("2021-01-01 00:00:00", "2021-06-01 00:00:00"); - deviceAlarm.setAlarmTime(format.format(date)); + deviceAlarm.setAlarmTime(DateUtil.format.format(date)); /** * 报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级 警情- */ @@ -90,8 +88,8 @@ class DeviceAlarmServiceImplTest { private Date randomDate(String beginDate, String endDate) { try { - Date start = format.parse(beginDate);//构造开始日期 - Date end = format.parse(endDate);//构造结束日期 + Date start = DateUtil.format.parse(beginDate);//构造开始日期 + Date end = DateUtil.format.parse(endDate);//构造结束日期 //getTime()表示返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。 if (start.getTime() >= end.getTime()) { return null; diff --git a/src/test/java/com/genersoft/iot/vmp/service/impl/RoleServiceImplTest.java b/src/test/java/com/genersoft/iot/vmp/service/impl/RoleServiceImplTest.java index 13479fe2..02dedcf5 100644 --- a/src/test/java/com/genersoft/iot/vmp/service/impl/RoleServiceImplTest.java +++ b/src/test/java/com/genersoft/iot/vmp/service/impl/RoleServiceImplTest.java @@ -4,12 +4,12 @@ import com.genersoft.iot.vmp.service.IRoleService; import com.genersoft.iot.vmp.service.IUserService; import com.genersoft.iot.vmp.storager.dao.dto.Role; import com.genersoft.iot.vmp.storager.dao.dto.User; +import com.genersoft.iot.vmp.utils.DateUtil; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; -import java.text.SimpleDateFormat; import java.util.List; @@ -20,7 +20,6 @@ class RoleServiceImplTest { @Resource private IRoleService roleService; - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @org.junit.jupiter.api.Test void getAllUser() { List all = roleService.getAll(); @@ -35,8 +34,8 @@ class RoleServiceImplTest { Role role = new Role(); role.setName("test+" + i); role.setAuthority("adadadda"); - role.setCreateTime(format.format(System.currentTimeMillis())); - role.setUpdateTime(format.format(System.currentTimeMillis())); + role.setCreateTime(DateUtil.getNow()); + role.setUpdateTime(DateUtil.getNow()); roleService.add(role); } } diff --git a/src/test/java/com/genersoft/iot/vmp/service/impl/UserServiceImplTest.java b/src/test/java/com/genersoft/iot/vmp/service/impl/UserServiceImplTest.java index 41148706..3f902dc4 100644 --- a/src/test/java/com/genersoft/iot/vmp/service/impl/UserServiceImplTest.java +++ b/src/test/java/com/genersoft/iot/vmp/service/impl/UserServiceImplTest.java @@ -1,17 +1,14 @@ package com.genersoft.iot.vmp.service.impl; -import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; -import com.genersoft.iot.vmp.service.IDeviceAlarmService; import com.genersoft.iot.vmp.service.IUserService; import com.genersoft.iot.vmp.storager.dao.dto.Role; import com.genersoft.iot.vmp.storager.dao.dto.User; +import com.genersoft.iot.vmp.utils.DateUtil; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; -import java.text.SimpleDateFormat; -import java.util.Date; import java.util.List; @@ -22,7 +19,6 @@ class UserServiceImplTest { @Resource private IUserService userService; - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @org.junit.jupiter.api.Test void getAllUser() { @@ -42,8 +38,8 @@ class UserServiceImplTest { Role role = new Role(); role.setId(1); user.setRole(role); - user.setCreateTime(format.format(System.currentTimeMillis())); - user.setUpdateTime(format.format(System.currentTimeMillis())); + user.setCreateTime(DateUtil.getNow()); + user.setUpdateTime(DateUtil.getNow()); userService.addUser(user); } } @@ -62,7 +58,7 @@ class UserServiceImplTest { Role role = new Role(); role.setId(2); user.setRole(role); - user.setUpdateTime(format.format(System.currentTimeMillis())); + user.setUpdateTime(DateUtil.getNow()); userService.updateUsers(user); } diff --git a/web_src/src/components/channelList.vue b/web_src/src/components/channelList.vue index 7e0637c4..f7e4e406 100644 --- a/web_src/src/components/channelList.vue +++ b/web_src/src/components/channelList.vue @@ -237,10 +237,10 @@ export default { that.initData(); }, 1000) - } else { - that.$message.error(res.data.msg); } }).catch(function (e) { + that.isLoging = false; + that.$message.error("请求超时"); }); }, queryRecords: function (itemData) {