From f6893cf95b15531dfc45950fea7e780e045ba2ae Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期三, 11 五月 2022 18:37:24 +0800
Subject: [PATCH] 优化设备在线状态

---
 src/main/java/com/genersoft/iot/vmp/gb28181/event/device/RequestTimeoutEvent.java                                                    |   25 +
 src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java                                                                         |   13 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java                                                      |    3 
 src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMStatusEventListener.java                                                      |    6 
 src/main/java/com/genersoft/iot/vmp/conf/ThreadPoolTaskConfig.java                                                                   |    3 
 src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java                                                                |    2 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java   |    2 
 src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java                                                                  |    8 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java        |   61 +-
 src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java                                                                |   34 -
 src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java                                                                   |    5 
 src/test/java/com/genersoft/iot/vmp/service/impl/DeviceAlarmServiceImplTest.java                                                     |   10 
 src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java                                                       |   17 
 src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java                                                         |   33 -
 src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java                                                                            |    8 
 src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java                                                                 |   17 
 src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java                                   |   25 
 src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java                                                         |    9 
 src/test/java/com/genersoft/iot/vmp/service/impl/UserServiceImplTest.java                                                            |   12 
 src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java                                                                            |   20 
 src/test/java/com/genersoft/iot/vmp/service/impl/RoleServiceImplTest.java                                                            |    7 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceInfoResponseMessageHandler.java   |   11 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java  |    3 
 src/main/java/com/genersoft/iot/vmp/gb28181/event/device/RequestTimeoutEventImpl.java                                                |   41 ++
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java                                                                         |   84 +---
 src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java                                                              |  135 +++++++
 src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java                                                                     |    7 
 src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java                                                                |    2 
 src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java                                                                              |   57 +++
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java                                                       |   44 ++
 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/alarm/AlarmController.java                                                      |   14 
 src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java                                                                        |    5 
 src/main/java/com/genersoft/iot/vmp/vmanager/user/RoleController.java                                                                |   13 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceStatusResponseMessageHandler.java |   19 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java                                |   29 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java      |    3 
 src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java                                                          |   11 
 src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java                                                                |    2 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java                                  |    7 
 src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java                                                                      |   63 +++
 /dev/null                                                                                                                            |   57 ---
 src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java                                                                            |    7 
 src/main/java/com/genersoft/iot/vmp/gb28181/task/SipDeviceRunner.java                                                                |   51 ++
 web_src/src/components/channelList.vue                                                                                               |    4 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java                                           |    2 
 src/main/java/com/genersoft/iot/vmp/vmanager/user/UserController.java                                                                |    8 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java                                  |   33 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/RecordInfoQueryMessageHandler.java         |    2 
 48 files changed, 612 insertions(+), 422 deletions(-)

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 ef4492f..eb98f6f 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 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 6180974..5f4ac22 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.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.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
-import java.text.SimpleDateFormat;
 
 /**
  * @author lin
@@ -26,7 +26,6 @@
 
     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 @@
             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 052f533..2812f92 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 @@
      * 寰幆鎵ц鐨勪换鍔�
      * @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 蹇呴』绛夊緟涓婁竴涓换鍔$粨鏉熸墠寮�濮嬭鏃秔eriod锛� 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 @@
         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 @@
         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 bdd1503..85f4684 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 @@
         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 71aed27..7377702 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 @@
      * 鍏佽绾跨▼绌洪棽鏃堕棿锛堝崟浣嶏細榛樿涓虹锛�
      */
     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/conf/runner/SipDeviceRunner.java b/src/main/java/com/genersoft/iot/vmp/conf/runner/SipDeviceRunner.java
deleted file mode 100644
index 4a89796..0000000
--- a/src/main/java/com/genersoft/iot/vmp/conf/runner/SipDeviceRunner.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.genersoft.iot.vmp.conf.runner;
-
-import com.genersoft.iot.vmp.conf.UserSetting;
-import com.genersoft.iot.vmp.gb28181.bean.Device;
-import com.genersoft.iot.vmp.service.IDeviceService;
-import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
-import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.CommandLineRunner;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Component;
-
-import java.util.List;
-
-
-/**
- * 绯荤粺鍚姩鏃舵帶鍒惰澶�
- */
-@Component
-@Order(value=4)
-public class SipDeviceRunner implements CommandLineRunner {
-
-    @Autowired
-    private IVideoManagerStorage storager;
-
-    @Autowired
-    private IRedisCatchStorage redisCatchStorage;
-
-    @Autowired
-    private UserSetting userSetting;
-
-    @Autowired
-    private IDeviceService deviceService;
-
-    @Override
-    public void run(String... args) throws Exception {
-        // 璇诲彇redis娌℃湁蹇冭烦淇℃伅鐨勫垯璁剧疆涓虹绾匡紝绛夋敹鍒颁笅娆″績璺宠缃负鍦ㄧ嚎
-        // 璁剧疆鎵�鏈夎澶囩绾�
-        storager.outlineForAll();
-        List<String> onlineForAll = redisCatchStorage.getOnlineForAll();
-        for (String deviceId : onlineForAll) {
-            storager.online(deviceId);
-            Device device = redisCatchStorage.getDevice(deviceId);
-            if (device != null ) {
-                if (device.getSubscribeCycleForCatalog() > 0) {
-                    // 鏌ヨ鍦ㄧ嚎璁惧閭d簺寮�鍚簡璁㈤槄锛屼负璁惧寮�鍚畾鏃剁殑鐩綍璁㈤槄
-                    deviceService.addCatalogSubscribe(device);
-                }
-                if (device.getSubscribeCycleForMobilePosition() > 0) {
-                    deviceService.addMobilePositionSubscribe(device);
-                }
-            }
-        }
-        // 閲嶇疆cseq璁℃暟
-        redisCatchStorage.resetAllCSEQ();
-
-
-    }
-}
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 58772d9..2b93d70 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 @@
 		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"); // 鎺ユ敹鎵�鏈塶otify璇锋眰锛屽嵆浣挎病鏈夎闃�
+		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 81b9666..e8eab8c 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
@@ -100,11 +100,6 @@
 	private String mediaServerId;
 
 	/**
-	 * 棣栨娉ㄥ唽
-	 */
-	private boolean firsRegister;
-
-	/**
 	 * 瀛楃闆�, 鏀寔 UTF-8 涓� GB2312
 	 */
 	private String charset ;
@@ -277,14 +272,6 @@
 
 	public void setMediaServerId(String mediaServerId) {
 		this.mediaServerId = mediaServerId;
-	}
-
-	public boolean isFirsRegister() {
-		return firsRegister;
-	}
-
-	public void setFirsRegister(boolean firsRegister) {
-		this.firsRegister = firsRegister;
 	}
 
 	public String getCharset() {
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 ca7fd54..3349cdc 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 @@
 
 	@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 e804be2..2736be2 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 @@
         // 娣诲姞浠诲姟澶勭悊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 ffe477f..eaf674f 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.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 @@
 
 	@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 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 0000000..c4d3bab
--- /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 0000000..9382c2f
--- /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<RequestTimeoutEvent> {
+
+    @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 ef78d37..8516fc7 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.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 @@
         // 骞冲彴蹇冭烦鍒版湡,闇�瑕侀噸鍙�, 鍒ゆ柇鏄惁宸茬粡澶氭鏈敹鍒板績璺冲洖澶�, 澶氭鏈敹鍒�,鍒欓噸鏂板彂璧锋敞鍐�, 娉ㄥ唽灏濊瘯澶氭鏈緱鍒板洖澶�,鍒欒涓哄钩鍙扮绾�
         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 @@
                 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 9e8c647..0000000
--- 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涓虹┖锛屽嵆涓嶈搴旂敤鍘讳慨鏀箁edis鐨勯粯璁ら厤缃紝鍥犱负Redis鏈嶅姟鍑轰簬瀹夊叏浼氱鐢–ONFIG鍛戒护缁欒繙绋嬬敤鎴蜂娇鐢�
-            setKeyspaceNotificationsConfigParameter("");
-        }
-        super.init();
-    }
-
-
-	/**
-     * 鐩戝惉澶辨晥鐨刱ey锛宬ey鏍煎紡涓簁eeplive_deviceId
-     * @param message
-     * @param pattern
-     */
-    @Override
-    public void onMessage(Message message, byte[] pattern) {
-        //  鑾峰彇澶辨晥鐨刱ey
-        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 9dfeffc..0000000
--- 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 4633256..0000000
--- 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<OfflineEvent> {
-
-	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("璁惧绂荤嚎浜嬩欢瑙﹀彂锛宒eviceId锛�" + event.getDeviceId() + ",from:" + event.getFrom());
-
-		String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + event.getDeviceId();
-
-		switch (event.getFrom()) {
-			// 蹇冭烦瓒呮椂瑙﹀彂鐨勭绾夸簨浠讹紝璇存槑redis涓凡鍒犻櫎锛屾棤闇�澶勭悊
-			case VideoManagerConstants.EVENT_OUTLINE_TIMEOUT:
-				break;
-			// 璁惧涓诲姩娉ㄩ攢瑙﹀彂鐨勭绾夸簨浠讹紝闇�瑕佸垹闄edis涓殑瓒呮椂鐩戝惉
-			case VideoManagerConstants.EVENT_OUTLINE_UNREGISTER:
-				redis.del(key);
-				break;
-			default:
-				boolean exist = redis.hasKey(key);
-				if (exist) {
-					redis.del(key);
-				}
-		}
-
-		List<DeviceChannel> deviceChannelList = storager.queryOnlineChannelsByDeviceId(event.getDeviceId());
-		eventPublisher.catalogEventPublish(null, deviceChannelList, CatalogEvent.OFF);
-		// 澶勭悊绂荤嚎鐩戝惉
-		storager.outline(event.getDeviceId());
-
-		// TODO 绂荤嚎鍙栨秷璁㈤槄
-
-		// 绂荤嚎閲婃斁鎵�鏈塻src
-		List<SsrcTransaction> 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 9aa9f8d..0000000
--- 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 f32637e..0000000
--- 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<OnlineEvent> {
-	
-	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("璁惧涓婄嚎浜嬩欢瑙﹀彂锛宒eviceId锛�" + 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()) {
-		// 娉ㄥ唽鏃惰Е鍙戠殑鍦ㄧ嚎浜嬩欢锛屽厛鍦╮edis涓鍔犺秴鏃惰秴鏃剁洃鍚�
-		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);
-			// 鍏堝垽鏂槸鍚﹁繕瀛樺湪锛屽綋璁惧鍏堝績璺宠秴鏃跺悗鍙堝彂閫佸績璺虫椂锛宺edis娌℃湁鐩戝惉锛岄渶瑕佸鍔�
-			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) {
-			// 鏌ヨ鍦ㄧ嚎璁惧閭d簺寮�鍚簡璁㈤槄锛屼负璁惧寮�鍚畾鏃剁殑鐩綍璁㈤槄
-			deviceService.addCatalogSubscribe(device);
-		}
-		if (device.getSubscribeCycleForMobilePosition() > 0) {
-			deviceService.addMobilePositionSubscribe(device);
-		}
-	}
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipDeviceRunner.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipDeviceRunner.java
new file mode 100644
index 0000000..91d8c3d
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipDeviceRunner.java
@@ -0,0 +1,51 @@
+package com.genersoft.iot.vmp.gb28181.task;
+
+import com.genersoft.iot.vmp.conf.UserSetting;
+import com.genersoft.iot.vmp.gb28181.bean.Device;
+import com.genersoft.iot.vmp.service.IDeviceService;
+import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
+import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
+import org.springframework.beans.factory.annotation.Autowired;
+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)
+public class SipDeviceRunner implements CommandLineRunner {
+
+    @Autowired
+    private IVideoManagerStorage storager;
+
+    @Autowired
+    private IRedisCatchStorage redisCatchStorage;
+
+    @Autowired
+    private UserSetting userSetting;
+
+    @Autowired
+    private IDeviceService deviceService;
+
+    @Override
+    public void run(String... args) throws Exception {
+        List<Device> 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 a9c9089..a06a73d 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.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 @@
     @Autowired
     private SipSubscribe sipSubscribe;
 
+    @Autowired
+    private EventPublisher eventPublisher;
 
-//    @Autowired
-//    @Qualifier(value = "taskExecutor")
-//    private ThreadPoolTaskExecutor poolTaskExecutor;
+
+
 
     /**
      * 娣诲姞 request璁㈤槄
@@ -141,9 +148,32 @@
      */
     @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 ea8f202..567bcac 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.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.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 2aafd98..a4fd507 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.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 bb46a71..1ba1b3e 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.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.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 @@
 						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 98cb3aa..e923a54 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 @@
 			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 @@
 					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);
@@ -323,10 +328,6 @@
 					// 杞彂鍙樺寲淇℃伅
 					eventPublisher.catalogEventPublish(null, channel, eventElement.getText().toUpperCase());
 
-				}
-
-				if (!redisCatchStorage.deviceIsOnline(deviceId)) {
-					publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
 				}
 			}
 		} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
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 ce5ca43..4f5f96a 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.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 @@
     @Autowired
     private SIPProcessorObserver sipProcessorObserver;
 
+    @Autowired
+    private IDeviceService deviceService;
+
     @Override
     public void afterPropertiesSet() throws Exception {
         // 娣诲姞娑堟伅澶勭悊鐨勮闃�
@@ -82,7 +86,7 @@
             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 @@
                 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 @@
                 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 @@
             sendResponse(evt, response);
             // 娉ㄥ唽鎴愬姛
             // 淇濆瓨鍒皉edis
-            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 08a7751..56a4c49 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.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 @@
 
     @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();
-                // 瑙f瀽鏈湴鍦板潃鏇夸唬
-                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();
+                    // 瑙f瀽鏈湴鍦板潃鏇夸唬
+                    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 efd6ffd..4b6c902 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.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 56b42ca..891b21d 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.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;
@@ -38,8 +37,6 @@
 
     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 276be49..639d4d9 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
@@ -29,6 +29,9 @@
 
 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
 
+/**
+ * @author lin
+ */
 @Component
 public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
 
@@ -61,6 +64,11 @@
     @Override
     public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
         logger.debug("鎺ユ敹鍒癉eviceInfo搴旂瓟娑堟伅");
+        // 妫�鏌ヨ澶囨槸鍚﹀瓨鍦紝 涓嶅瓨鍦ㄥ垯涓嶅洖澶�
+        if (device == null || device.getOnline() == 0) {
+            logger.warn("[鎺ユ敹鍒癉eviceInfo搴旂瓟娑堟伅,浣嗘槸璁惧宸茬粡绂荤嚎]锛�" + (device != null ? device.getDeviceId():"" ));
+            return;
+        }
         try {
             rootElement = getRootElement(evt, device.getCharset());
             Element deviceIdElement = rootElement.element("DeviceID");
@@ -82,9 +90,6 @@
             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 4e2f7f7..1fed401 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.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.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 @@
     @Autowired
     private ResponseMessageHandler responseMessageHandler;
 
-
     @Autowired
     private DeferredResultHolder deferredResultHolder;
 
     @Autowired
-    private EventPublisher publisher;
+    private IDeviceService deviceService;
 
     @Autowired
     private IRedisCatchStorage redisCatchStorage;
@@ -53,6 +54,9 @@
     public void handForDevice(RequestEvent evt, Device device, Element element) {
         logger.info("鎺ユ敹鍒癉eviceStatus搴旂瓟娑堟伅");
         // 妫�鏌ヨ澶囨槸鍚﹀瓨鍦紝 涓嶅瓨鍦ㄥ垯涓嶅洖澶�
+        if (device == null) {
+            return;
+        }
         // 鍥炲200 OK
         try {
             responseAck(evt, Response.OK);
@@ -64,20 +68,23 @@
             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 1c9ec21..3662600 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.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;
@@ -32,8 +31,6 @@
 
     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 45b7e56..2de8ef1 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.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/gb28181/utils/DateUtil.java b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java
deleted file mode 100644
index 604c083..0000000
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java
+++ /dev/null
@@ -1,57 +0,0 @@
-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;
-			//杞崲涓篋ate绫�
-			return timestamp;
-		} catch (ParseException e) {
-			e.printStackTrace();
-		}
-		return 0;
-	}
-}
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 12829e9..0261209 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 @@
     @Autowired
     private DynamicTask dynamicTask;
 
-    @Qualifier("taskExecutor")
-    @Autowired
-    private ThreadPoolTaskExecutor taskExecutor;
 
     @Override
     public void run(String... strings) throws Exception {
@@ -105,9 +102,7 @@
                 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 @@
                 startGetMedia = null;
             }
         //  TODO 娓呯悊鏁版嵁搴撲腑涓巖edis涓嶅尮閰嶇殑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 @@
                 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 杩炴帴鎴愬姛鎴栬�厇lm閲嶅惎鍚�
-     */
-//    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);
-//
-//        // 娓呯┖鎵�鏈塻ession
-////        zlmMediaListManager.clearAllSessions();
-//
-//        // 鏇存柊娴佸垪琛�
-//        zlmMediaListManager.updateMediaList(mediaServerItem);
-//        // 鎭㈠娴佷唬鐞�, 鍙煡鎵捐繖涓繖涓祦濯掍綋
-//        List<StreamProxyItem> 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 ca6fdfe..b193add 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 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 @@
 	@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涓婄嚎浜嬩欢瑙﹀彂锛孖D锛�" + event.getMediaServerId());
+		logger.info("銆怹LM涓婄嚎銆慖D锛�" + 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 5621d2a..a7c52ba 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,105 @@
 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<Device> getAllOnlineDevice();
+
+    /**
+     * 鍒ゆ柇鏄惁娉ㄥ唽宸茬粡澶辨晥
+     * @param device 璁惧淇℃伅
+     * @return 甯冨皵
+     */
+    boolean expire(Device device);
+
+    /**
+     * 妫�鏌ヨ澶囩姸鎬�
+     * @param device 璁惧淇℃伅
+     */
+    void checkDeviceStatus(Device device);
+
+    /**
+     * 鏍规嵁IP鍜岀鍙h幏鍙栬澶囦俊鎭�
+     * @param host IP
+     * @param port 绔彛
+     * @return 璁惧淇℃伅
+     */
+    Device getDeviceByHostAndPort(String host, int port);
 }
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 39a59f8..ce211c3 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,13 +2,19 @@
 
 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;
@@ -17,6 +23,11 @@
 import org.springframework.stereotype.Service;
 
 import javax.sip.DialogState;
+import javax.sip.TimeoutEvent;
+import java.text.ParseException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
 
 /**
  * 璁惧涓氬姟锛堢洰褰曡闃咃級
@@ -25,6 +36,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 +51,84 @@
     @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("[璁惧涓婄嚎]锛宒eviceId锛�" + 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());
+            device.setCreateTime(now);
+        }
+        device.setOnline(1);
+        device.setRegisterTime(now);
+
+        // 绗竴娆′笂绾�
+        if (device.getCreateTime() == null) {
+            logger.info("[璁惧涓婄嚎,棣栨娉ㄥ唽]: {}锛屾煡璇㈣澶囦俊鎭互鍙婇�氶亾淇℃伅", device.getDeviceId());
+            commander.deviceInfoQuery(device);
+            sync(device);
+            deviceMapper.add(device);
+        }else {
+            deviceMapper.update(device);
+        }
+        redisCatchStorage.updateDevice(device);
+        // 涓婄嚎娣诲姞璁㈤槄
+        if (device.getSubscribeCycleForCatalog() > 0) {
+            // 鏌ヨ鍦ㄧ嚎璁惧閭d簺寮�鍚簡璁㈤槄锛屼负璁惧寮�鍚畾鏃剁殑鐩綍璁㈤槄
+            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);
+        // 绂荤嚎閲婃斁鎵�鏈塻src
+        List<SsrcTransaction> 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 +140,7 @@
         // 鎻愬墠寮�濮嬪埛鏂拌闃�
         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 +165,7 @@
         // 璁剧疆鏈�灏忓�间负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 +202,44 @@
             catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), errorMsg);
         });
     }
+
+    @Override
+    public Device queryDevice(String deviceId) {
+        return deviceMapper.getDeviceByDeviceId(deviceId);
+    }
+
+    @Override
+    public List<Device> 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);
+    }
 }
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 e311890..a690c1b 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.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;
@@ -88,8 +89,6 @@
 
     @Autowired
     JedisUtil jedisUtil;
-
-    private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
     /**
      * 鍒濆鍖�
@@ -231,7 +230,7 @@
         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 @@
     @Override
     public WVPResult<String> add(MediaServerItem mediaServerItem) {
         WVPResult<String> 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 f2b6c28..4372f8e 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.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 2bff864..ef5932d 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.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 {
@@ -32,8 +27,6 @@
 
     @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) {
@@ -52,7 +45,7 @@
         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 67697c8..4a3aa78 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -112,23 +112,6 @@
     void clearCatchByDeviceId(String deviceId);
 
     /**
-     * 鑾峰彇mediaServer鑺傜偣
-     * @param mediaServerId
-     * @return
-     */
-//    MediaServerItem getMediaInfo(String mediaServerId);
-
-    /**
-     * 璁剧疆鎵�鏈夎澶囩绾�
-     */
-    void outlineForAll();
-
-    /**
-     * 鑾峰彇鎵�鏈夊湪绾跨殑
-     */
-    List<String> getOnlineForAll();
-
-    /**
      * 鍦╮edis娣诲姞wvp鐨勪俊鎭�
      */
     void updateWVPInfo(JSONObject jsonObject, int time);
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 97cf2cc..37d951e 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 @@
 
     @Update("UPDATE device SET online=0")
     int outlineForAll();
+
+    @Select("SELECT * FROM device WHERE online = 1")
+    List<Device> 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 ae7647f..39daeda 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.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")
@@ -37,8 +37,6 @@
 
     @Autowired
     private UserSetting userSetting;
-
-    private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
     @Override
     public Long getCSEQ(String method) {
@@ -470,26 +468,6 @@
     }
 
     @Override
-    public void outlineForAll() {
-        List<Object> 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<String> getOnlineForAll() {
-        List<String> result = new ArrayList<>();
-        List<Object> 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();
         redis.set(key, jsonObject, time);
@@ -638,7 +616,7 @@
     public void addCpuInfo(double cpuInfo) {
         String key = VideoManagerConstants.SYSTEM_INFO_CPU_PREFIX + userSetting.getServerId();
         SystemInfoDto<Double> 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 void addMemInfo(double memInfo) {
         String key = VideoManagerConstants.SYSTEM_INFO_MEM_PREFIX + userSetting.getServerId();
         SystemInfoDto<Double> 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 void addNetInfo(Map<String, String> networkInterfaces) {
         String key = VideoManagerConstants.SYSTEM_INFO_NET_PREFIX + userSetting.getServerId();
         SystemInfoDto<Map<String, String>> 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 @@
 
     @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 2dc88f8..b72671a 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.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.annotation.Transactional;
 import org.springframework.util.StringUtils;
 
-import java.text.SimpleDateFormat;
 import java.util.*;
 
 /**    
@@ -91,9 +91,6 @@
 	@Autowired
     private ParentPlatformMapper parentPlatformMapper;
 
-	private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-
-
 	/**
 	 * 鏍规嵁璁惧ID鍒ゆ柇璁惧鏄惁瀛樺湪
 	 *
@@ -127,7 +124,7 @@
 	 */
 	@Override
 	public synchronized boolean updateDevice(Device device) {
-		String now = this.format.format(System.currentTimeMillis());
+		String now = DateUtil.getNow();
 		device.setUpdateTime(now);
 		Device deviceByDeviceId = deviceMapper.getDeviceByDeviceId(device.getDeviceId());
 		device.setCharset(device.getCharset().toUpperCase());
@@ -140,8 +137,6 @@
 
 			return deviceMapper.update(device) > 0;
 		}
-
-
 	}
 
 	@Override
@@ -152,7 +147,7 @@
 		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 +173,7 @@
 					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 +188,7 @@
 					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 +727,7 @@
 		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/utils/DateUtil.java b/src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java
new file mode 100644
index 0000000..1be0f40
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java
@@ -0,0 +1,57 @@
+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;
+			//杞崲涓篋ate绫�
+			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/alarm/AlarmController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/alarm/AlarmController.java
index addc431..56864db 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.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.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 = "鎶ヨ淇℃伅绠$悊")
@@ -45,9 +44,6 @@
 
     @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 @@
 
         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 @@
         }
         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 @@
         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/log/LogController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java
index 44b1688..65f5f7c 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 @@
 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.web.bind.annotation.*;
 
 import java.text.ParseException;
-import java.text.SimpleDateFormat;
 
 @Api(tags = "鏃ュ織绠$悊")
 @CrossOrigin
@@ -33,8 +33,6 @@
 
     @Autowired
     private UserSetting userSetting;
-
-    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
     /**
      *  鍒嗛〉鏌ヨ鏃ュ織
@@ -80,10 +78,10 @@
 
         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 6a75e1d..887eb46 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 @@
 
 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 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 = "瑙掕壊绠$悊")
@@ -29,8 +24,6 @@
 
     @Autowired
     private IRoleService roleService;
-
-    private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
     @ApiOperation("娣诲姞瑙掕壊")
     @ApiImplicitParams({
@@ -53,8 +46,8 @@
         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 17fe2fb..152122d 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.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.web.bind.annotation.*;
 
 import javax.security.sasl.AuthenticationException;
-import java.text.SimpleDateFormat;
 import java.util.List;
 
 @Api(tags = "鐢ㄦ埛绠$悊")
@@ -37,8 +37,6 @@
 
     @Autowired
     private IRoleService roleService;
-
-    private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
     @ApiOperation("鐧诲綍")
     @ApiImplicitParams({
@@ -135,8 +133,8 @@
             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 23b9f6b..6d6ff37 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 @@
 
 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;
 
 
@@ -17,8 +17,6 @@
 
     @Resource
     private IDeviceAlarmService deviceAlarmService;
-
-    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
     @org.junit.jupiter.api.Test
     void getAllAlarm() {
@@ -67,7 +65,7 @@
              */
             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 @@
     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 13479fe..02dedcf 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.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 @@
     @Resource
     private IRoleService roleService;
 
-    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
     @org.junit.jupiter.api.Test
     void getAllUser() {
         List<Role> all = roleService.getAll();
@@ -35,8 +34,8 @@
             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 4114870..3f902dc 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 @@
     @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 @@
             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 @@
         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 7e0637c..f7e4e40 100644
--- a/web_src/src/components/channelList.vue
+++ b/web_src/src/components/channelList.vue
@@ -237,10 +237,10 @@
             that.initData();
           }, 1000)
 
-        } else {
-          that.$message.error(res.data.msg);
         }
       }).catch(function (e) {
+        that.isLoging = false;
+        that.$message.error("璇锋眰瓒呮椂");
       });
     },
     queryRecords: function (itemData) {

--
Gitblit v1.8.0