From d7a1b94f905c5f28c9c8f2d48c3f9e28ebcf9cc4 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期六, 24 九月 2022 21:04:58 +0800
Subject: [PATCH] Merge branch 'wvp-28181-2.0'

---
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java |    7 
 src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/CatalogSubscribeTask.java                                                        |   67 
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java                                                                 |   19 
 src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMStatusEventListener.java                                                        |    4 
 src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java                                                                  |   14 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java              |  222 ++-
 src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGpsMsgListener.java                                                          |    5 
 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java                                                           |   14 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java                                 |   93 -
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java                                         |  117 ++
 src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java                                                        |  102 ++
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java                                                            |    7 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java                                  |    4 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java                           |   12 
 src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java                                                                      |   11 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java                                       |  120 +-
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/control/cmd/DeviceControlQueryMessageHandler.java      |    8 
 src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeTask.java                                                 |   73 
 src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java                                                                              |   10 
 src/main/java/com/genersoft/iot/vmp/gb28181/bean/SipTransactionInfo.java                                                               |   53 +
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java                                                 |    1 
 src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java                                          |   62 -
 src/main/java/com/genersoft/iot/vmp/gb28181/bean/SipMsgInfo.java                                                                       |   56 +
 src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java                                                       |  185 ++-
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ChannelOnlineEvent.java                                                              |    4 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java    |   10 
 src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java                                                              |   44 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/ConfigDownloadResponseMessageHandler.java |    2 
 src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java                                                                  |    7 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceInfoQueryMessageHandler.java           |    2 
 src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusMsgListener.java                                             |   22 
 src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java                                                       |   91 +
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/info/InfoRequestProcessor.java                                 |   14 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceStatusResponseMessageHandler.java   |    2 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java        |    2 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java                                    |  191 +-
 src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java                                                       |    6 
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java                                                                 |   13 
 src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java                                                                   |   13 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java                                    |    6 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/RecordInfoQueryMessageHandler.java           |   11 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/AlarmQueryMessageHandler.java                |    2 
 src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java                                                                           |    1 
 src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java                                                                    |   64 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java     |  152 +-
 src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java                                                                      |   51 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java                                                        |  138 --
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java      |    1 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceControlResponseMessageHandler.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/service/redisMsg/RedisPushStreamStatusListMsgListener.java                                         |  103 ++
 src/main/java/com/genersoft/iot/vmp/gb28181/conf/DefaultProperties.java                                                                |   46 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java          |    2 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java                                      |  146 +-
 src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java                                                         |    6 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java                                                 |   11 
 src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java                                                           |    4 
 web_src/src/components/dialog/devicePlayer.vue                                                                                         |    3 
 src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java                                                                              |    4 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceInfoResponseMessageHandler.java     |    6 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/CatalogQueryMessageHandler.java              |    2 
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java                                                                           |    2 
 src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java                                                                    |   16 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java                                                         |   13 
 src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamResponseListener.java                                              |   75 +
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java                                                                |    3 
 src/main/java/com/genersoft/iot/vmp/conf/redis/RedisConfig.java                                                                        |    2 
 src/main/resources/all-application.yml                                                                                                 |    2 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java                                       |   91 -
 src/main/java/com/genersoft/iot/vmp/gb28181/task/ISubscribeTask.java                                                                   |    2 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java        |    6 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceStatusQueryMessageHandler.java         |    2 
 /dev/null                                                                                                                              |   72 -
 src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java                                                                              |   39 
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java                                                                 |   31 
 web_src/src/components/dialog/recordDownload.vue                                                                                       |    7 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java                                             |  196 +--
 77 files changed, 1,772 insertions(+), 1,239 deletions(-)

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 3438893..03498fd 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
@@ -64,8 +64,8 @@
     @Value("${media.secret}")
     private String secret;
 
-    @Value("${media.stream-none-reader-delay-ms:10000}")
-    private int streamNoneReaderDelayMS = 10000;
+    @Value("${media.stream-none-reader-delay-ms:15000}")
+    private int streamNoneReaderDelayMS = 15000;
 
     @Value("${media.rtp.enable}")
     private boolean rtpEnable;
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
index 017b39d..cad6e69 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
@@ -31,6 +31,8 @@
 
     private Boolean logInDatebase = Boolean.TRUE;
 
+    private Boolean usePushingAsStatus = Boolean.TRUE;
+
     private String serverId = "000000";
 
     private String thirdPartyGBIdReg = "[\\s\\S]*";
@@ -136,4 +138,12 @@
     public void setPlatformPlayTimeout(int platformPlayTimeout) {
         this.platformPlayTimeout = platformPlayTimeout;
     }
+
+    public Boolean isUsePushingAsStatus() {
+        return usePushingAsStatus;
+    }
+
+    public void setUsePushingAsStatus(Boolean usePushingAsStatus) {
+        this.usePushingAsStatus = usePushingAsStatus;
+    }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisConfig.java
index 0b653cf..e412f71 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisConfig.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisConfig.java
@@ -3,7 +3,7 @@
 
 import com.alibaba.fastjson.parser.ParserConfig;
 import com.genersoft.iot.vmp.common.VideoManagerConstants;
-import com.genersoft.iot.vmp.service.impl.*;
+import com.genersoft.iot.vmp.service.redisMsg.*;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.CachingConfigurerSupport;
 import org.springframework.context.annotation.Bean;
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 9b57097..cd8b5d7 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
@@ -1,6 +1,7 @@
 package com.genersoft.iot.vmp.gb28181;
 
 import com.genersoft.iot.vmp.conf.SipConfig;
+import com.genersoft.iot.vmp.gb28181.conf.DefaultProperties;
 import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver;
 import gov.nist.javax.sip.SipProviderImpl;
 import gov.nist.javax.sip.SipStackImpl;
@@ -41,43 +42,7 @@
 	@Bean("sipStack")
 	@DependsOn({"sipFactory"})
 	SipStack createSipStack() throws PeerUnavailableException {
-		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
-		 * sip娑堟伅鐨勮В鏋愬湪 gov.nist.javax.sip.stack.UDPMessageChannel鐨刾rocessIncomingDataPacket鏂规硶
-		 */
-
-//		 * gov/nist/javax/sip/SipStackImpl.class
-		if (logger.isDebugEnabled()) {
-			properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false");
-		}
-		// 鎺ユ敹鎵�鏈塶otify璇锋眰锛屽嵆浣挎病鏈夎闃�
-		properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true");
-		properties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false");
-		properties.setProperty("gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED", "false");
-		// 涓篲NULL _瀵硅瘽妗嗕紶閫抇缁堟鐨刜浜嬩欢
-		properties.setProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG", "true");
-		// 浼氳瘽娓呯悊绛栫暐
-		properties.setProperty("gov.nist.javax.sip.RELEASE_REFERENCES_STRATEGY", "Normal");
-		// 澶勭悊鐢辫鏈嶅姟鍣ㄥ鐞嗙殑鍩轰簬搴曞眰TCP鐨勪繚鎸佺敓瀛樿秴鏃�
-		properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "60");
-		// 鑾峰彇瀹為檯鍐呭闀垮害锛屼笉浣跨敤header涓殑闀垮害淇℃伅
-		properties.setProperty("gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY", "true");
-
-		/**
-		 * sip_server_log.log 鍜� sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE
-		 */
-		properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "ERROR");
-//		properties.setProperty("gov.nist.javax.sip.SIP_MESSAGE_VALVE", "com.genersoft.iot.vmp.gb28181.session.SipMessagePreprocessing");
-//		if (logger.isDebugEnabled()) {
-//			properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "DEBUG");
-//		}
-
-		sipStack = (SipStackImpl) sipFactory.createSipStack(properties);
-
+		sipStack = ( SipStackImpl )sipFactory.createSipStack(DefaultProperties.getProperties(sipConfig.getMonitorIp(), false));
 		return sipStack;
 	}
 
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 a2667fb..3f4c658 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
@@ -381,4 +381,5 @@
 	public void setTreeType(String treeType) {
 		this.treeType = treeType;
 	}
+
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java
index 41e1af7..8f61bc9 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java
@@ -1,5 +1,7 @@
 package com.genersoft.iot.vmp.gb28181.bean;
 
+import gov.nist.javax.sip.message.SIPRequest;
+
 public class SendRtpItem {
 
     /**
@@ -77,9 +79,19 @@
     private String serverId;
 
     /**
-     *  invite鐨刢allId
+     *  invite 鐨� callId
      */
     private String CallId;
+
+    /**
+     *  invite 鐨� fromTag
+     */
+    private String fromTag;
+
+    /**
+     *  invite 鐨� toTag
+     */
+    private String toTag;
 
     /**
      * 鍙戦�佹椂锛宺tp鐨刾t锛坲int8_t锛�,涓嶄紶鏃堕粯璁や负96
@@ -96,14 +108,11 @@
      */
     private boolean onlyAudio = false;
 
+
     /**
      * 鎾斁绫诲瀷
      */
     private InviteStreamType playType;
-
-    private byte[] transaction;
-
-    private byte[] dialog;
 
     public String getIp() {
         return ip;
@@ -225,22 +234,6 @@
         this.playType = playType;
     }
 
-    public byte[] getTransaction() {
-        return transaction;
-    }
-
-    public void setTransaction(byte[] transaction) {
-        this.transaction = transaction;
-    }
-
-    public byte[] getDialog() {
-        return dialog;
-    }
-
-    public void setDialog(byte[] dialog) {
-        this.dialog = dialog;
-    }
-
     public int getPt() {
         return pt;
     }
@@ -272,4 +265,20 @@
     public void setServerId(String serverId) {
         this.serverId = serverId;
     }
+
+    public String getFromTag() {
+        return fromTag;
+    }
+
+    public void setFromTag(String fromTag) {
+        this.fromTag = fromTag;
+    }
+
+    public String getToTag() {
+        return toTag;
+    }
+
+    public void setToTag(String toTag) {
+        this.toTag = toTag;
+    }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SipMsgInfo.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SipMsgInfo.java
new file mode 100644
index 0000000..302539b
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SipMsgInfo.java
@@ -0,0 +1,56 @@
+package com.genersoft.iot.vmp.gb28181.bean;
+
+import org.dom4j.Element;
+
+import javax.sip.RequestEvent;
+
+public class SipMsgInfo {
+    private RequestEvent evt;
+    private  Device device;
+    private ParentPlatform platform;
+    private Element rootElement;
+
+    public SipMsgInfo(RequestEvent evt, Device device, Element rootElement) {
+        this.evt = evt;
+        this.device = device;
+        this.rootElement = rootElement;
+    }
+
+    public SipMsgInfo(RequestEvent evt, ParentPlatform platform, Element rootElement) {
+        this.evt = evt;
+        this.platform = platform;
+        this.rootElement = rootElement;
+    }
+
+    public RequestEvent getEvt() {
+        return evt;
+    }
+
+    public void setEvt(RequestEvent evt) {
+        this.evt = evt;
+    }
+
+    public Device getDevice() {
+        return device;
+    }
+
+    public void setDevice(Device device) {
+        this.device = device;
+    }
+
+    public ParentPlatform getPlatform() {
+        return platform;
+    }
+
+    public void setPlatform(ParentPlatform platform) {
+        this.platform = platform;
+    }
+
+    public Element getRootElement() {
+        return rootElement;
+    }
+
+    public void setRootElement(Element rootElement) {
+        this.rootElement = rootElement;
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SipTransactionInfo.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SipTransactionInfo.java
new file mode 100644
index 0000000..c68be12
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SipTransactionInfo.java
@@ -0,0 +1,53 @@
+package com.genersoft.iot.vmp.gb28181.bean;
+
+import gov.nist.javax.sip.message.SIPRequest;
+
+public class SipTransactionInfo {
+
+    private String callId;
+    private String fromTag;
+    private String toTag;
+    private String viaBranch;
+
+    public SipTransactionInfo(SIPRequest request) {
+        this.callId = request.getCallIdHeader().getCallId();
+        this.fromTag = request.getFromTag();
+        this.toTag = request.getToTag();
+        this.viaBranch = request.getTopmostViaHeader().getBranch();
+    }
+
+    public SipTransactionInfo() {
+    }
+
+    public String getCallId() {
+        return callId;
+    }
+
+    public void setCallId(String callId) {
+        this.callId = callId;
+    }
+
+    public String getFromTag() {
+        return fromTag;
+    }
+
+    public void setFromTag(String fromTag) {
+        this.fromTag = fromTag;
+    }
+
+    public String getToTag() {
+        return toTag;
+    }
+
+    public void setToTag(String toTag) {
+        this.toTag = toTag;
+    }
+
+    public String getViaBranch() {
+        return viaBranch;
+    }
+
+    public void setViaBranch(String viaBranch) {
+        this.viaBranch = viaBranch;
+    }
+}
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 441dff3..ba905b5 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
@@ -5,6 +5,7 @@
 import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask;
 import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeHandlerTask;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
+import com.genersoft.iot.vmp.service.IPlatformService;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -22,15 +23,6 @@
 
     @Autowired
     private DynamicTask dynamicTask;
-
-    @Autowired
-    private IRedisCatchStorage redisCatchStorage;
-
-    @Autowired
-    private ISIPCommanderForPlatform sipCommanderForPlatform;
-
-    @Autowired
-    private IVideoManagerStorage storager;
 
     private final String taskOverduePrefix = "subscribe_overdue_";
 
@@ -62,15 +54,13 @@
         }
         // 娣诲姞浠诲姟澶勭悊璁㈤槄杩囨湡
         dynamicTask.stop(taskOverdueKey);
-
     }
 
     public void putMobilePositionSubscribe(String platformId, SubscribeInfo subscribeInfo) {
         mobilePositionMap.put(platformId, subscribeInfo);
         String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX +  "MobilePosition_" + platformId;
         // 娣诲姞浠诲姟澶勭悊GPS瀹氭椂鎺ㄩ��
-        dynamicTask.startCron(key, new MobilePositionSubscribeHandlerTask(redisCatchStorage, sipCommanderForPlatform,
-                storager,  platformId, subscribeInfo.getSn(), key, this, dynamicTask),
+        dynamicTask.startCron(key, new MobilePositionSubscribeHandlerTask(platformId),
                 subscribeInfo.getGpsInterval() * 1000);
         String taskOverdueKey = taskOverduePrefix +  "MobilePosition_" + platformId;
         // 娣诲姞浠诲姟澶勭悊璁㈤槄杩囨湡
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java
index 1958b44..2c80c62 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java
@@ -1,7 +1,10 @@
 package com.genersoft.iot.vmp.gb28181.bean;
 
 import com.genersoft.iot.vmp.utils.SerializeUtils;
+import gov.nist.javax.sip.message.SIPRequest;
+import gov.nist.javax.sip.message.SIPResponse;
 
+import javax.sip.ClientTransaction;
 import javax.sip.Dialog;
 import javax.sip.RequestEvent;
 import javax.sip.ServerTransaction;
@@ -11,30 +14,24 @@
 public class SubscribeInfo {
 
 
-    public SubscribeInfo(RequestEvent evt, String id) {
+    public SubscribeInfo(ServerTransaction serverTransaction, String id) {
         this.id = id;
-        Request request = evt.getRequest();
-        ExpiresHeader expiresHeader = (ExpiresHeader)request.getHeader(ExpiresHeader.NAME);
-        this.expires = expiresHeader.getExpires();
+        SIPRequest request = (SIPRequest)serverTransaction.getRequest();
+        this.request = request;
+        this.expires = request.getExpires().getExpires();
         EventHeader eventHeader = (EventHeader)request.getHeader(EventHeader.NAME);
         this.eventId = eventHeader.getEventId();
         this.eventType = eventHeader.getEventType();
-        this.transaction = evt.getServerTransaction();
-        this.dialog = evt.getDialog();
-        CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
-        this.callId = callIdHeader.getCallId();
-    }
 
-    public SubscribeInfo() {
     }
 
     private String id;
+
+    private SIPRequest request;
     private int expires;
-    private String callId;
     private String eventId;
     private String eventType;
-    private ServerTransaction transaction;
-    private Dialog dialog;
+    private SIPResponse response;
 
     /**
      * 浠ヤ笅涓哄彲閫夊瓧娈�
@@ -43,29 +40,28 @@
     private String sn;
     private int gpsInterval;
 
-
     public String getId() {
         return id;
-    }
-
-    public int getExpires() {
-        return expires;
-    }
-
-    public String getCallId() {
-        return callId;
     }
 
     public void setId(String id) {
         this.id = id;
     }
 
-    public void setExpires(int expires) {
-        this.expires = expires;
+    public SIPRequest getRequest() {
+        return request;
     }
 
-    public void setCallId(String callId) {
-        this.callId = callId;
+    public void setRequest(SIPRequest request) {
+        this.request = request;
+    }
+
+    public int getExpires() {
+        return expires;
+    }
+
+    public void setExpires(int expires) {
+        this.expires = expires;
     }
 
     public String getEventId() {
@@ -84,20 +80,12 @@
         this.eventType = eventType;
     }
 
-    public ServerTransaction getTransaction() {
-        return transaction;
+    public SIPResponse getResponse() {
+        return response;
     }
 
-    public void setTransaction(ServerTransaction transaction) {
-        this.transaction = transaction;
-    }
-
-    public Dialog getDialog() {
-        return dialog;
-    }
-
-    public void setDialog(Dialog dialog) {
-        this.dialog = dialog;
+    public void setResponse(SIPResponse response) {
+        this.response = response;
     }
 
     public String getSn() {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/conf/DefaultProperties.java b/src/main/java/com/genersoft/iot/vmp/gb28181/conf/DefaultProperties.java
new file mode 100644
index 0000000..e0691e5
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/conf/DefaultProperties.java
@@ -0,0 +1,46 @@
+package com.genersoft.iot.vmp.gb28181.conf;
+
+import java.util.Properties;
+
+/**
+ * 鑾峰彇sip榛樿閰嶇疆
+ * @author lin
+ */
+public class DefaultProperties {
+
+    public static Properties getProperties(String ip, boolean isDebug) {
+        Properties properties = new Properties();
+        properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
+        properties.setProperty("javax.sip.IP_ADDRESS", ip);
+        properties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off");
+        /**
+         * 瀹屾暣閰嶇疆鍙傝�� gov.nist.javax.sip.SipStackImpl锛岄渶瑕佷笅杞芥簮鐮�
+         * gov/nist/javax/sip/SipStackImpl.class
+         * sip娑堟伅鐨勮В鏋愬湪 gov.nist.javax.sip.stack.UDPMessageChannel鐨刾rocessIncomingDataPacket鏂规硶
+         */
+
+//		 * gov/nist/javax/sip/SipStackImpl.class
+        if (isDebug) {
+            properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false");
+        }
+        // 鎺ユ敹鎵�鏈塶otify璇锋眰锛屽嵆浣挎病鏈夎闃�
+        properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true");
+        properties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false");
+        properties.setProperty("gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED", "false");
+        // 涓篲NULL _瀵硅瘽妗嗕紶閫抇缁堟鐨刜浜嬩欢
+        properties.setProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG", "true");
+        // 浼氳瘽娓呯悊绛栫暐
+        properties.setProperty("gov.nist.javax.sip.RELEASE_REFERENCES_STRATEGY", "Normal");
+        // 澶勭悊鐢辫鏈嶅姟鍣ㄥ鐞嗙殑鍩轰簬搴曞眰TCP鐨勪繚鎸佺敓瀛樿秴鏃�
+        properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "60");
+        // 鑾峰彇瀹為檯鍐呭闀垮害锛屼笉浣跨敤header涓殑闀垮害淇℃伅
+        properties.setProperty("gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY", "true");
+
+        /**
+         * sip_server_log.log 鍜� sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE
+         */
+        properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "ERROR");
+
+        return properties;
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
index b3fd82e..69529b0 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
@@ -1,6 +1,7 @@
 package com.genersoft.iot.vmp.gb28181.event;
 
 import com.genersoft.iot.vmp.gb28181.bean.DeviceNotFoundEvent;
+import gov.nist.javax.sip.message.SIPRequest;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.scheduling.annotation.Scheduled;
@@ -104,22 +105,27 @@
                 this.type = EventResultType.timeout;
                 this.msg = "娑堟伅瓒呮椂鏈洖澶�";
                 this.statusCode = -1024;
-                this.dialog = timeoutEvent.getClientTransaction().getDialog();
-                this.callId = this.dialog != null?timeoutEvent.getClientTransaction().getDialog().getCallId().getCallId(): null;
+                if (timeoutEvent.isServerTransaction()) {
+                    this.callId = ((SIPRequest)timeoutEvent.getServerTransaction().getRequest()).getCallIdHeader().getCallId();
+                }else {
+                    this.callId = ((SIPRequest)timeoutEvent.getClientTransaction().getRequest()).getCallIdHeader().getCallId();
+                }
             }else if (event instanceof TransactionTerminatedEvent) {
                 TransactionTerminatedEvent transactionTerminatedEvent = (TransactionTerminatedEvent)event;
                 this.type = EventResultType.transactionTerminated;
                 this.msg = "浜嬪姟宸茬粨鏉�";
                 this.statusCode = -1024;
-                this.callId = transactionTerminatedEvent.getClientTransaction().getDialog().getCallId().getCallId();
-                this.dialog = transactionTerminatedEvent.getClientTransaction().getDialog();
+                if (transactionTerminatedEvent.isServerTransaction()) {
+                    this.callId = ((SIPRequest)transactionTerminatedEvent.getServerTransaction().getRequest()).getCallIdHeader().getCallId();
+                }else {
+                    this.callId = ((SIPRequest)transactionTerminatedEvent.getClientTransaction().getRequest()).getCallIdHeader().getCallId();
+                }
             }else if (event instanceof DialogTerminatedEvent) {
                 DialogTerminatedEvent dialogTerminatedEvent = (DialogTerminatedEvent)event;
                 this.type = EventResultType.dialogTerminated;
                 this.msg = "浼氳瘽宸茬粨鏉�";
                 this.statusCode = -1024;
                 this.callId = dialogTerminatedEvent.getDialog().getCallId().getCallId();
-                this.dialog = dialogTerminatedEvent.getDialog();
             }else if (event instanceof DeviceNotFoundEvent) {
                 DeviceNotFoundEvent deviceNotFoundEvent = (DeviceNotFoundEvent)event;
                 this.type = EventResultType.deviceNotFoundEvent;
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/ISubscribeTask.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/ISubscribeTask.java
index c7a16ee..a4e711d 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/task/ISubscribeTask.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/ISubscribeTask.java
@@ -7,6 +7,4 @@
  */
 public interface ISubscribeTask extends Runnable{
     void stop();
-
-    DialogState getDialogState();
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/CatalogSubscribeTask.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/CatalogSubscribeTask.java
index 577e724..bfa900a 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/CatalogSubscribeTask.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/CatalogSubscribeTask.java
@@ -4,6 +4,7 @@
 import com.genersoft.iot.vmp.gb28181.bean.Device;
 import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
+import gov.nist.javax.sip.message.SIPRequest;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.scheduling.annotation.Async;
@@ -12,6 +13,8 @@
 import javax.sip.Dialog;
 import javax.sip.DialogState;
 import javax.sip.ResponseEvent;
+import javax.sip.header.ToHeader;
+import java.text.ParseException;
 import java.util.Timer;
 import java.util.TimerTask;
 
@@ -23,7 +26,7 @@
     private final Logger logger = LoggerFactory.getLogger(CatalogSubscribeTask.class);
     private Device device;
     private final ISIPCommander sipCommander;
-    private Dialog dialog;
+    private SIPRequest request;
 
     private DynamicTask dynamicTask;
 
@@ -41,24 +44,26 @@
         if (dynamicTask.get(taskKey) != null) {
             dynamicTask.stop(taskKey);
         }
-        sipCommander.catalogSubscribe(device, dialog, eventResult -> {
-            if (eventResult.dialog != null || eventResult.dialog.getState().equals(DialogState.CONFIRMED)) {
-                dialog = eventResult.dialog;
-            }
+        SIPRequest sipRequest = sipCommander.catalogSubscribe(device, request, eventResult -> {
             ResponseEvent event = (ResponseEvent) eventResult.event;
-            if (event.getResponse().getRawContent() != null) {
-                // 鎴愬姛
-                logger.info("[鐩綍璁㈤槄]鎴愬姛锛� {}", device.getDeviceId());
-            }else {
-                // 鎴愬姛
-                logger.info("[鐩綍璁㈤槄]鎴愬姛锛� {}", device.getDeviceId());
+            // 鎴愬姛
+            logger.info("[鐩綍璁㈤槄]鎴愬姛锛� {}", device.getDeviceId());
+            ToHeader toHeader = (ToHeader)event.getResponse().getHeader(ToHeader.NAME);
+            try {
+                this.request.getToHeader().setTag(toHeader.getTag());
+            } catch (ParseException e) {
+                logger.info("[鐩綍璁㈤槄]鎴愬姛锛� 浣嗕负request璁剧疆ToTag澶辫触");
+                this.request = null;
             }
         },eventResult -> {
-            dialog = null;
+            this.request = null;
             // 澶辫触
             logger.warn("[鐩綍璁㈤槄]澶辫触锛屼俊浠ゅ彂閫佸け璐ワ細 {}-{} ", device.getDeviceId(), eventResult.msg);
             dynamicTask.startDelay(taskKey, CatalogSubscribeTask.this, 2000);
         });
+        if (sipRequest != null) {
+            this.request = sipRequest;
+        }
     }
 
     @Override
@@ -74,29 +79,19 @@
         if (dynamicTask.get(taskKey) != null) {
             dynamicTask.stop(taskKey);
         }
-        if (dialog != null && dialog.getState().equals(DialogState.CONFIRMED)) {
-            device.setSubscribeCycleForCatalog(0);
-            sipCommander.catalogSubscribe(device, dialog, eventResult -> {
-                ResponseEvent event = (ResponseEvent) eventResult.event;
-                if (event.getResponse().getRawContent() != null) {
-                    // 鎴愬姛
-                    logger.info("[鍙栨秷鐩綍璁㈤槄璁㈤槄]鎴愬姛锛� {}", device.getDeviceId());
-                }else {
-                    // 鎴愬姛
-                    logger.info("[鍙栨秷鐩綍璁㈤槄璁㈤槄]鎴愬姛锛� {}", device.getDeviceId());
-                }
-            },eventResult -> {
-                // 澶辫触
-                logger.warn("[鍙栨秷鐩綍璁㈤槄璁㈤槄]澶辫触锛屼俊浠ゅ彂閫佸け璐ワ細 {}-{} ", device.getDeviceId(), eventResult.msg);
-            });
-        }
-    }
-
-    @Override
-    public DialogState getDialogState() {
-        if (dialog == null) {
-            return null;
-        }
-        return dialog.getState();
+        device.setSubscribeCycleForCatalog(0);
+        sipCommander.catalogSubscribe(device, request, eventResult -> {
+            ResponseEvent event = (ResponseEvent) eventResult.event;
+            if (event.getResponse().getRawContent() != null) {
+                // 鎴愬姛
+                logger.info("[鍙栨秷鐩綍璁㈤槄璁㈤槄]鎴愬姛锛� {}", device.getDeviceId());
+            }else {
+                // 鎴愬姛
+                logger.info("[鍙栨秷鐩綍璁㈤槄璁㈤槄]鎴愬姛锛� {}", device.getDeviceId());
+            }
+        },eventResult -> {
+            // 澶辫触
+            logger.warn("[鍙栨秷鐩綍璁㈤槄璁㈤槄]澶辫触锛屼俊浠ゅ彂閫佸け璐ワ細 {}-{} ", device.getDeviceId(), eventResult.msg);
+        });
     }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java
index 2ee1037..2e792c1 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java
@@ -4,9 +4,11 @@
 import com.genersoft.iot.vmp.gb28181.bean.*;
 import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
+import com.genersoft.iot.vmp.service.IPlatformService;
 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.utils.SpringBeanFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.scheduling.annotation.Async;
@@ -20,71 +22,23 @@
  */
 public class MobilePositionSubscribeHandlerTask implements ISubscribeTask {
 
-    private Logger logger = LoggerFactory.getLogger(MobilePositionSubscribeHandlerTask.class);
 
-    private IRedisCatchStorage redisCatchStorage;
-    private IVideoManagerStorage storager;
-    private ISIPCommanderForPlatform sipCommanderForPlatform;
-    private SubscribeHolder subscribeHolder;
-    private ParentPlatform platform;
+    private IPlatformService platformService;
+    private String platformId;
 
-    private String sn;
-    private String key;
 
-    public MobilePositionSubscribeHandlerTask(IRedisCatchStorage redisCatchStorage,
-                                              ISIPCommanderForPlatform sipCommanderForPlatform,
-                                              IVideoManagerStorage storager,
-                                              String platformId,
-                                              String sn,
-                                              String key,
-                                              SubscribeHolder subscribeInfo,
-                                              DynamicTask dynamicTask) {
-        this.redisCatchStorage = redisCatchStorage;
-        this.storager = storager;
-        this.platform = storager.queryParentPlatByServerGBId(platformId);
-        this.sn = sn;
-        this.key = key;
-        this.sipCommanderForPlatform = sipCommanderForPlatform;
-        this.subscribeHolder = subscribeInfo;
+    public MobilePositionSubscribeHandlerTask(String platformId) {
+        this.platformService = SpringBeanFactory.getBean("platformServiceImpl");
+        this.platformId = platformId;
     }
 
     @Override
     public void run() {
-
-        if (platform == null) {
-            return;
-        }
-        SubscribeInfo subscribe = subscribeHolder.getMobilePositionSubscribe(platform.getServerGBId());
-        if (subscribe != null) {
-
-            // TODO 鏆傛椂鍙鐞嗚棰戞祦鐨勫洖澶�,鍚庣画澧炲姞瀵瑰浗鏍囪澶囩殑鏀寔
-            List<DeviceChannel> gbStreams = storager.queryGbStreamListInPlatform(platform.getServerGBId());
-            if (gbStreams.size() == 0) {
-                return;
-            }
-            for (DeviceChannel deviceChannel : gbStreams) {
-                String gbId = deviceChannel.getChannelId();
-                GPSMsgInfo gpsMsgInfo = redisCatchStorage.getGpsMsgInfo(gbId);
-                // 鏃犳渶鏂颁綅缃笉鍙戦��
-                if (gpsMsgInfo != null) {
-                    // 缁忕含搴﹂兘涓�0涓嶅彂閫�
-                    if (gpsMsgInfo.getLng() == 0 && gpsMsgInfo.getLat() == 0) {
-                        continue;
-                    }
-                    // 鍙戦�丟PS娑堟伅
-                    sipCommanderForPlatform.sendNotifyMobilePosition(platform, gpsMsgInfo, subscribe);
-                }
-            }
-        }
+        platformService.sendNotifyMobilePosition(this.platformId);
     }
 
     @Override
     public void stop() {
 
-    }
-
-    @Override
-    public DialogState getDialogState() {
-        return null;
     }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeTask.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeTask.java
index e43e59b..5dbdbe6 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeTask.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeTask.java
@@ -4,6 +4,8 @@
 import com.genersoft.iot.vmp.gb28181.bean.Device;
 import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
+import gov.nist.javax.sip.message.SIPRequest;
+import gov.nist.javax.sip.message.SIPResponse;
 import org.dom4j.Element;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -12,6 +14,8 @@
 import javax.sip.Dialog;
 import javax.sip.DialogState;
 import javax.sip.ResponseEvent;
+import javax.sip.header.ToHeader;
+import java.text.ParseException;
 import java.util.Timer;
 import java.util.TimerTask;
 
@@ -21,9 +25,10 @@
  */
 public class MobilePositionSubscribeTask implements ISubscribeTask {
     private final Logger logger = LoggerFactory.getLogger(MobilePositionSubscribeTask.class);
-    private  Device device;
-    private  ISIPCommander sipCommander;
-    private Dialog dialog;
+    private Device device;
+    private ISIPCommander sipCommander;
+
+    private SIPRequest request;
     private DynamicTask dynamicTask;
     private String taskKey = "mobile-position-subscribe-timeout";
 
@@ -38,24 +43,26 @@
         if (dynamicTask.get(taskKey) != null) {
             dynamicTask.stop(taskKey);
         }
-        sipCommander.mobilePositionSubscribe(device, dialog, eventResult -> {
-            if (eventResult.dialog != null || eventResult.dialog.getState().equals(DialogState.CONFIRMED)) {
-                dialog = eventResult.dialog;
-            }
+        SIPRequest sipRequest = sipCommander.mobilePositionSubscribe(device, request, eventResult -> {
+            // 鎴愬姛
+            logger.info("[绉诲姩浣嶇疆璁㈤槄]鎴愬姛锛� {}", device.getDeviceId());
             ResponseEvent event = (ResponseEvent) eventResult.event;
-            if (event.getResponse().getRawContent() != null) {
-                // 鎴愬姛
-                logger.info("[绉诲姩浣嶇疆璁㈤槄]鎴愬姛锛� {}", device.getDeviceId());
-            }else {
-                // 鎴愬姛
-                logger.info("[绉诲姩浣嶇疆璁㈤槄]鎴愬姛锛� {}", device.getDeviceId());
+            ToHeader toHeader = (ToHeader)event.getResponse().getHeader(ToHeader.NAME);
+            try {
+                this.request.getToHeader().setTag(toHeader.getTag());
+            } catch (ParseException e) {
+                logger.info("[绉诲姩浣嶇疆璁㈤槄]鎴愬姛锛� 涓簉equest璁剧疆ToTag澶辫触");
+                this.request = null;
             }
         },eventResult -> {
-            dialog = null;
+            this.request = null;
             // 澶辫触
             logger.warn("[绉诲姩浣嶇疆璁㈤槄]澶辫触锛屼俊浠ゅ彂閫佸け璐ワ細 {}-{} ", device.getDeviceId(), eventResult.msg);
             dynamicTask.startDelay(taskKey, MobilePositionSubscribeTask.this, 2000);
         });
+        if (sipRequest != null) {
+            this.request = sipRequest;
+        }
 
     }
 
@@ -71,29 +78,19 @@
         if (dynamicTask.get(taskKey) != null) {
             dynamicTask.stop(taskKey);
         }
-        if (dialog != null && dialog.getState().equals(DialogState.CONFIRMED)) {
-            logger.info("鍙栨秷绉诲姩璁㈤槄鏃禿ialog鐘舵�佷负{}", dialog.getState());
-            device.setSubscribeCycleForMobilePosition(0);
-            sipCommander.mobilePositionSubscribe(device, dialog, eventResult -> {
-                ResponseEvent event = (ResponseEvent) eventResult.event;
-                if (event.getResponse().getRawContent() != null) {
-                    // 鎴愬姛
-                    logger.info("[鍙栨秷绉诲姩浣嶇疆璁㈤槄]鎴愬姛锛� {}", device.getDeviceId());
-                }else {
-                    // 鎴愬姛
-                    logger.info("[鍙栨秷绉诲姩浣嶇疆璁㈤槄]鎴愬姛锛� {}", device.getDeviceId());
-                }
-            },eventResult -> {
-                // 澶辫触
-                logger.warn("[鍙栨秷绉诲姩浣嶇疆璁㈤槄]澶辫触锛屼俊浠ゅ彂閫佸け璐ワ細 {}-{} ", device.getDeviceId(), eventResult.msg);
-            });
-        }
-    }
-    @Override
-    public DialogState getDialogState() {
-        if (dialog == null) {
-            return null;
-        }
-        return dialog.getState();
+        device.setSubscribeCycleForMobilePosition(0);
+        sipCommander.mobilePositionSubscribe(device, request, eventResult -> {
+            ResponseEvent event = (ResponseEvent) eventResult.event;
+            if (event.getResponse().getRawContent() != null) {
+                // 鎴愬姛
+                logger.info("[鍙栨秷绉诲姩浣嶇疆璁㈤槄]鎴愬姛锛� {}", device.getDeviceId());
+            }else {
+                // 鎴愬姛
+                logger.info("[鍙栨秷绉诲姩浣嶇疆璁㈤槄]鎴愬姛锛� {}", device.getDeviceId());
+            }
+        },eventResult -> {
+            // 澶辫触
+            logger.warn("[鍙栨秷绉诲姩浣嶇疆璁㈤槄]澶辫触锛屼俊浠ゅ彂閫佸け璐ワ細 {}-{} ", device.getDeviceId(), eventResult.msg);
+        });
     }
 }
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 b94daf7..1252adb 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
@@ -69,12 +69,9 @@
      * @param requestEvent RequestEvent浜嬩欢
      */
     @Override
-    @Async
+    @Async("taskExecutor")
     public void processRequest(RequestEvent requestEvent) {
         String method = requestEvent.getRequest().getMethod();
-        if ("NOTIFY".equalsIgnoreCase(requestEvent.getRequest().getMethod())) {
-            System.out.println();
-        }
         ISIPRequestProcessor sipRequestProcessor = requestProcessorMap.get(method);
         if (sipRequestProcessor == null) {
             logger.warn("涓嶆敮鎸佹柟娉晎}鐨剅equest", method);
@@ -89,7 +86,7 @@
      * @param responseEvent responseEvent浜嬩欢
      */
     @Override
-    @Async
+    @Async("taskExecutor")
     public void processResponse(ResponseEvent responseEvent) {
         Response response = responseEvent.getResponse();
         int status = response.getStatusCode();
@@ -173,6 +170,12 @@
 
     @Override
     public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
+//        if (transactionTerminatedEvent.isServerTransaction()) {
+//            ServerTransaction serverTransaction = transactionTerminatedEvent.getServerTransaction();
+//            serverTransaction.get
+//        }
+
+
 //        Transaction transaction = null;
 //        System.out.println("processTransactionTerminated");
 //        if (transactionTerminatedEvent.isServerTransaction()) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
index 07eb0c2..39c74f3 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -7,6 +7,7 @@
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
 import gov.nist.javax.sip.message.SIPRequest;
+import gov.nist.javax.sip.message.SIPRequest;
 import gov.nist.javax.sip.stack.SIPDialog;
 
 import javax.sip.Dialog;
@@ -158,7 +159,7 @@
 	 */
 	void playbackControlCmd(Device device, StreamInfo streamInfo, String content,SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent);
 
-	
+
 	/**
 	 * 璇煶骞挎挱
 	 * 
@@ -311,7 +312,7 @@
 	 * @param device	瑙嗛璁惧
 	 * @return			true = 鍛戒护鍙戦�佹垚鍔�
 	 */
-	boolean mobilePositionSubscribe(Device device, Dialog dialog, SipSubscribe.Event okEvent , SipSubscribe.Event errorEvent);
+	SIPRequest mobilePositionSubscribe(Device device, SIPRequest request, SipSubscribe.Event okEvent , SipSubscribe.Event errorEvent);
 
 	/**
 	 * 璁㈤槄銆佸彇娑堣闃呮姤璀︿俊鎭�
@@ -331,7 +332,7 @@
 	 * @param device		瑙嗛璁惧
 	 * @return				true = 鍛戒护鍙戦�佹垚鍔�
 	 */
-	boolean catalogSubscribe(Device device, Dialog dialog, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent);
+	SIPRequest catalogSubscribe(Device device, SIPRequest request, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent);
 
 	/**
 	 * 鎷夋鎺у埗鍛戒护
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
index 351505f..ab229bd 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
@@ -117,4 +117,5 @@
      * @param callId  callId
      */
     void streamByeCmd(ParentPlatform platform, String callId);
+    void streamByeCmd(ParentPlatform platform, SendRtpItem sendRtpItem);
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
index 6ee3cce..7ecdaf0 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
@@ -2,10 +2,13 @@
 
 import com.genersoft.iot.vmp.conf.SipConfig;
 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
+import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
+import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo;
 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.utils.GitUtil;
 import gov.nist.javax.sip.message.MessageFactoryImpl;
+import gov.nist.javax.sip.message.SIPRequest;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.util.DigestUtils;
@@ -154,8 +157,17 @@
 		return registerRequest;
 	}
 
+	public Request createMessageRequest(ParentPlatform parentPlatform, String content, SendRtpItem sendRtpItem) throws PeerUnavailableException, ParseException, InvalidArgumentException {
+		CallIdHeader callIdHeader = sipFactory.createHeaderFactory().createCallIdHeader(sendRtpItem.getCallId());
+		return createMessageRequest(parentPlatform, content, sendRtpItem.getToTag(), SipUtils.getNewViaTag(), sendRtpItem.getFromTag(), callIdHeader);
+	}
 
 	public Request createMessageRequest(ParentPlatform parentPlatform, String content, String fromTag, String viaTag, CallIdHeader callIdHeader) throws PeerUnavailableException, ParseException, InvalidArgumentException {
+		return createMessageRequest(parentPlatform, content, fromTag, viaTag, null, callIdHeader);
+	}
+
+
+	public Request createMessageRequest(ParentPlatform parentPlatform, String content, String fromTag, String viaTag, String toTag, CallIdHeader callIdHeader) throws PeerUnavailableException, ParseException, InvalidArgumentException {
 		Request request = null;
 		String serverAddress = parentPlatform.getServerIP()+ ":" + parentPlatform.getServerPort();
 		// sipuri
@@ -174,7 +186,7 @@
 		// to
 		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), serverAddress);
 		Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
-		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, null);
+		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag);
 
 		// Forwards
 		MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
@@ -192,4 +204,107 @@
 		request.setContent(content, contentTypeHeader);
 		return request;
 	}
+
+	public SIPRequest createNotifyRequest(ParentPlatform parentPlatform, String content, SubscribeInfo subscribeInfo) throws PeerUnavailableException, ParseException, InvalidArgumentException {
+		SIPRequest request = null;
+		// sipuri
+		SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP()+ ":" + parentPlatform.getServerPort());
+		// via
+		ArrayList<ViaHeader> viaHeaders = new ArrayList<>();
+		ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(), Integer.parseInt(parentPlatform.getDevicePort()),
+				parentPlatform.getTransport(), SipUtils.getNewViaTag());
+		viaHeader.setRPort();
+		viaHeaders.add(viaHeader);
+		// from
+		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(),
+				parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort());
+		Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
+		FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, subscribeInfo.getResponse().getToTag());
+		// to
+		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerGBDomain());
+		Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
+		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, subscribeInfo.getRequest().getFromTag());
+
+		// Forwards
+		MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
+		// ceq
+		CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.NOTIFY);
+		MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
+		// 璁剧疆缂栫爜锛� 闃叉涓枃涔辩爜
+		messageFactory.setDefaultContentEncodingCharset("gb2312");
+
+		CallIdHeader callIdHeader = sipFactory.createHeaderFactory().createCallIdHeader(subscribeInfo.getRequest().getCallIdHeader().getCallId());
+
+		request = (SIPRequest) messageFactory.createRequest(requestURI, Request.NOTIFY, callIdHeader, cSeqHeader, fromHeader,
+				toHeader, viaHeaders, maxForwards);
+
+		request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
+
+		EventHeader event = sipFactory.createHeaderFactory().createEventHeader(subscribeInfo.getEventType());
+		if (subscribeInfo.getEventId() != null) {
+			event.setEventId(subscribeInfo.getEventId());
+		}
+
+		request.addHeader(event);
+
+		SubscriptionStateHeader active = sipFactory.createHeaderFactory().createSubscriptionStateHeader("active");
+		request.setHeader(active);
+
+		String sipAddress = sipConfig.getIp() + ":" + sipConfig.getPort();
+		Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory()
+				.createSipURI(parentPlatform.getDeviceGBId(), sipAddress));
+		request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
+
+		ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
+		request.setContent(content, contentTypeHeader);
+		return request;
+    }
+
+	public SIPRequest createByeRequest(ParentPlatform platform, SendRtpItem sendRtpItem) throws PeerUnavailableException, ParseException, InvalidArgumentException {
+
+		if (sendRtpItem == null ) {
+			return null;
+		}
+
+		SIPRequest request = null;
+		// sipuri
+		SipURI requestURI = sipFactory.createAddressFactory().createSipURI(platform.getServerGBId(), platform.getServerIP()+ ":" + platform.getServerPort());
+		// via
+		ArrayList<ViaHeader> viaHeaders = new ArrayList<>();
+		ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(platform.getDeviceIp(), Integer.parseInt(platform.getDevicePort()),
+				platform.getTransport(), SipUtils.getNewViaTag());
+		viaHeader.setRPort();
+		viaHeaders.add(viaHeader);
+		// from
+		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(),
+				platform.getDeviceIp() + ":" + platform.getDevicePort());
+		Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
+		FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, sendRtpItem.getToTag());
+		// to
+		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(platform.getServerGBId(), platform.getServerGBDomain());
+		Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
+		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, sendRtpItem.getFromTag());
+
+		// Forwards
+		MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
+		// ceq
+		CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.BYE);
+		MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
+		// 璁剧疆缂栫爜锛� 闃叉涓枃涔辩爜
+		messageFactory.setDefaultContentEncodingCharset("gb2312");
+
+		CallIdHeader callIdHeader = sipFactory.createHeaderFactory().createCallIdHeader(sendRtpItem.getCallId());
+
+		request = (SIPRequest) messageFactory.createRequest(requestURI, Request.BYE, callIdHeader, cSeqHeader, fromHeader,
+				toHeader, viaHeaders, maxForwards);
+
+		request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
+
+		String sipAddress = sipConfig.getIp() + ":" + sipConfig.getPort();
+		Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory()
+				.createSipURI(platform.getDeviceGBId(), sipAddress));
+		request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
+
+		return request;
+	}
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
index 21ab374..34c5cbe 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
@@ -16,6 +16,7 @@
 import com.genersoft.iot.vmp.utils.GitUtil;
 import gov.nist.javax.sip.SipProviderImpl;
 import gov.nist.javax.sip.SipStackImpl;
+import gov.nist.javax.sip.message.SIPRequest;
 import gov.nist.javax.sip.stack.SIPDialog;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -199,24 +200,24 @@
 		return request;
 	}
 
-	public Request createSubscribeRequest(Device device, String content, String viaTag, String fromTag, String toTag, Integer expires, String event, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException {
+	public Request createSubscribeRequest(Device device, String content, SIPRequest requestOld, Integer expires, String event, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException {
 		Request request = null;
 		// sipuri
 		SipURI requestURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress());
 		// via
 		ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
 		ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getIp(), sipConfig.getPort(),
-				device.getTransport(), viaTag);
+				device.getTransport(), SipUtils.getNewViaTag());
 		viaHeader.setRPort();
 		viaHeaders.add(viaHeader);
 		// from
 		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain());
 		Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
-		FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag);
+		FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, requestOld == null ? SipUtils.getNewFromTag() :requestOld.getFromTag());
 		// to
 		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress());
 		Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
-		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag);
+		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, requestOld == null ? null :requestOld.getToTag());
 
 		// Forwards
 		MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
@@ -238,7 +239,7 @@
 		// Event
 		EventHeader eventHeader = sipFactory.createHeaderFactory().createEventHeader(event);
 
-		int random = (int)Math.random() * 1000000000;
+		int random = (int) Math.floor(Math.random() * 10000);
 		eventHeader.setEventId(random + "");
 		request.addHeader(eventHeader);
 
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 3933f05..d8875d3 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
@@ -26,6 +26,7 @@
 import gov.nist.javax.sip.SipStackImpl;
 import gov.nist.javax.sip.message.MessageFactoryImpl;
 import gov.nist.javax.sip.message.SIPRequest;
+import gov.nist.javax.sip.stack.SIPClientTransaction;
 import gov.nist.javax.sip.stack.SIPDialog;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -435,7 +436,14 @@
 			}), e ->{
 				// 杩欓噷涓轰緥閬垮厤涓�涓�氶亾鐨勭偣鎾彧鏈変竴涓猚allID杩欎釜鍙傛暟浣跨敤涓�涓浐瀹氬��
 				streamSession.put(device.getDeviceId(), channelId ,"play", stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), ((ResponseEvent)e.event).getClientTransaction(), VideoStreamSessionManager.SessionType.play);
-				streamSession.put(device.getDeviceId(), channelId ,"play", e.dialog);
+				Dialog sipDialog = null;
+				if (e.dialog == null) {
+					SIPClientTransaction clientTransaction = (SIPClientTransaction)((ResponseEvent)e.event).getClientTransaction();
+					sipDialog = new SIPDialog(clientTransaction, clientTransaction.getLastResponse());
+				}else {
+					sipDialog = e.dialog;
+				}
+				streamSession.put(device.getDeviceId(), channelId ,"play", sipDialog);
 				okEvent.response(e);
 			});
 
@@ -1446,7 +1454,7 @@
 	 * @return			true = 鍛戒护鍙戦�佹垚鍔�
 	 */
 	@Override
-	public boolean mobilePositionSubscribe(Device device, Dialog dialog, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent) {
+	public SIPRequest mobilePositionSubscribe(Device device, SIPRequest requestOld, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent) {
 		try {
 			StringBuffer subscribePostitionXml = new StringBuffer(200);
 			String charset = device.getCharset();
@@ -1456,38 +1464,27 @@
 			subscribePostitionXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
 			subscribePostitionXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
 			if (device.getSubscribeCycleForMobilePosition() > 0) {
-				subscribePostitionXml.append("<Interval>" + String.valueOf(device.getMobilePositionSubmissionInterval()) + "</Interval>\r\n");
+				subscribePostitionXml.append("<Interval>" + device.getMobilePositionSubmissionInterval() + "</Interval>\r\n");
 			}
 			subscribePostitionXml.append("</Query>\r\n");
 
-			Request request;
-			if (dialog != null) {
-				SipURI requestURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress());
-				request = dialog.createRequest(Request.SUBSCRIBE);
-				ExpiresHeader expiresHeader = sipFactory.createHeaderFactory().createExpiresHeader(device.getSubscribeCycleForCatalog());
-				request.setExpires(expiresHeader);
+			CallIdHeader callIdHeader;
 
-				request.setRequestURI(requestURI);
-
-				ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
-				request.setContent(subscribePostitionXml.toString(), contentTypeHeader);
-
-				CSeqHeader cSeqHeader = (CSeqHeader)request.getHeader(CSeqHeader.NAME);
-				cSeqHeader.setSeqNumber(redisCatchStorage.getCSEQ());
-				request.removeHeader(CSeqHeader.NAME);
-				request.addHeader(cSeqHeader);
+			if (requestOld != null) {
+				callIdHeader = sipFactory.createHeaderFactory().createCallIdHeader(requestOld.getCallIdHeader().getCallId());
 			}else {
-				CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
+				callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 						: udpSipProvider.getNewCallId();
-				request = headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, device.getSubscribeCycleForMobilePosition(), "presence" ,callIdHeader); //Position;id=" + tm.substring(tm.length() - 4));
 			}
+			SIPRequest request = (SIPRequest)headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), requestOld, device.getSubscribeCycleForMobilePosition(), "presence" ,callIdHeader); //Position;id=" + tm.substring(tm.length() - 4));
+
 			transmitRequest(device, request, errorEvent, okEvent);
 
-			return true;
+			return request;
 
 		} catch ( NumberFormatException | ParseException | InvalidArgumentException	| SipException e) {
 			e.printStackTrace();
-			return false;
+			return null;
 		}
 	}
 
@@ -1537,7 +1534,7 @@
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, expires, "presence" , callIdHeader);
+			Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), null, expires, "presence" , callIdHeader);
 			transmitRequest(device, request);
 
 			return true;
@@ -1549,7 +1546,7 @@
 	}
 
 	@Override
-	public boolean catalogSubscribe(Device device, Dialog dialog, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) {
+	public SIPRequest catalogSubscribe(Device device, SIPRequest requestOld, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) {
 		try {
 			StringBuffer cmdXml = new StringBuffer(200);
 			String charset = device.getCharset();
@@ -1560,40 +1557,24 @@
 			cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
 			cmdXml.append("</Query>\r\n");
 
+			CallIdHeader callIdHeader ;
 
-			Request request;
-			if (dialog != null) {
-				SipURI requestURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress());
-				request = dialog.createRequest(Request.SUBSCRIBE);
-				ExpiresHeader expiresHeader = sipFactory.createHeaderFactory().createExpiresHeader(device.getSubscribeCycleForCatalog());
-				request.setExpires(expiresHeader);
-
-				request.setRequestURI(requestURI);
-
-				ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
-				request.setContent(cmdXml.toString(), contentTypeHeader);
-
-				CSeqHeader cSeqHeader = (CSeqHeader)request.getHeader(CSeqHeader.NAME);
-				cSeqHeader.setSeqNumber(redisCatchStorage.getCSEQ());
-				request.removeHeader(CSeqHeader.NAME);
-				request.addHeader(cSeqHeader);
-
+			if (requestOld != null) {
+				callIdHeader = sipFactory.createHeaderFactory().createCallIdHeader(requestOld.getCallIdHeader().getCallId());
 			}else {
-				CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
+				callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 						: udpSipProvider.getNewCallId();
-
-				// 鏈夋晥鏃堕棿榛樿涓�60绉掍互涓�
-				request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), SipUtils.getNewViaTag(),
-						SipUtils.getNewFromTag(), null, device.getSubscribeCycleForCatalog(), "Catalog" ,
-						callIdHeader);
-
 			}
+
+			// 鏈夋晥鏃堕棿榛樿涓�60绉掍互涓�
+			SIPRequest request = (SIPRequest)headerProvider.createSubscribeRequest(device, cmdXml.toString(), requestOld,  device.getSubscribeCycleForCatalog(), "Catalog" ,
+					callIdHeader);
 			transmitRequest(device, request, errorEvent, okEvent);
-			return true;
+			return request;
 
 		} catch ( NumberFormatException | ParseException | InvalidArgumentException	| SipException e) {
 			e.printStackTrace();
-			return false;
+			return null;
 		}
 	}
 
@@ -1868,62 +1849,5 @@
 			throw new RuntimeException(e);
 		}
 		return true;
-	}
-
-	private void sendNotify(Device device, String catalogXmlContent,
-							SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent,  SipSubscribe.Event okEvent )
-			throws SipException, ParseException {
-		MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
-		String characterSet = device.getCharset();
-		// 璁剧疆缂栫爜锛� 闃叉涓枃涔辩爜
-		messageFactory.setDefaultContentEncodingCharset(characterSet);
-		Dialog dialog  = subscribeInfo.getDialog();
-		if (dialog == null || !dialog.getState().equals(DialogState.CONFIRMED)) {
-			return;
-		}
-		SIPRequest notifyRequest = (SIPRequest)dialog.createRequest(Request.NOTIFY);
-		ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
-		notifyRequest.setContent(catalogXmlContent, contentTypeHeader);
-
-		SubscriptionStateHeader subscriptionState = sipFactory.createHeaderFactory()
-				.createSubscriptionStateHeader(SubscriptionStateHeader.ACTIVE);
-		notifyRequest.addHeader(subscriptionState);
-
-		EventHeader event = sipFactory.createHeaderFactory().createEventHeader(subscribeInfo.getEventType());
-		if (subscribeInfo.getEventId() != null) {
-			event.setEventId(subscribeInfo.getEventId());
-		}
-		notifyRequest.addHeader(event);
-
-		SipURI sipURI = (SipURI) notifyRequest.getRequestURI();
-		if (subscribeInfo.getTransaction() != null) {
-			SIPRequest request = (SIPRequest) subscribeInfo.getTransaction().getRequest();
-			sipURI.setHost(request.getRemoteAddress().getHostAddress());
-			sipURI.setPort(request.getRemotePort());
-		}else {
-			sipURI.setHost(device.getIp());
-			sipURI.setPort(device.getPort());
-		}
-
-		ClientTransaction transaction = null;
-		if ("TCP".equals(device.getTransport())) {
-			transaction = tcpSipProvider.getNewClientTransaction(notifyRequest);
-		} else if ("UDP".equals(device.getTransport())) {
-			transaction = udpSipProvider.getNewClientTransaction(notifyRequest);
-		}
-		// 娣诲姞閿欒璁㈤槄
-		if (errorEvent != null) {
-			sipSubscribe.addErrorSubscribe(subscribeInfo.getCallId(), errorEvent);
-		}
-		// 娣诲姞璁㈤槄
-		if (okEvent != null) {
-			sipSubscribe.addOkSubscribe(subscribeInfo.getCallId(), okEvent);
-		}
-		if (transaction == null) {
-			logger.error("骞冲彴{}鐨凾ransport閿欒锛歿}",device.getDeviceId(), device.getTransport());
-			return;
-		}
-		dialog.sendRequest(transaction);
-
 	}
 }
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 332d72c..cc13d05 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
@@ -1,5 +1,6 @@
 package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
 
+import com.alibaba.fastjson.JSONObject;
 import com.genersoft.iot.vmp.gb28181.bean.*;
 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
@@ -47,7 +48,7 @@
     private final Logger logger = LoggerFactory.getLogger(SIPCommanderFroPlatform.class);
 
     @Autowired
-    private SIPRequestHeaderPlarformProvider headerProviderPlarformProvider;
+    private SIPRequestHeaderPlarformProvider headerProviderPlatformProvider;
 
     @Autowired
     private IRedisCatchStorage redisCatchStorage;
@@ -74,6 +75,9 @@
     @Autowired
     private SipFactory sipFactory;
 
+    @Autowired
+    private SubscribeHolder subscribeHolder;
+
     @Override
     public boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) {
         return register(parentPlatform, null, null, errorEvent, okEvent, false, true);
@@ -98,7 +102,7 @@
                     callIdHeader = udpSipProvider.getNewCallId();
                 }
 
-                request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform,
+                request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform,
                         redisCatchStorage.getCSEQ(), SipUtils.getNewFromTag(),
                         SipUtils.getNewViaTag(), callIdHeader, isRegister);
                 // 灏� callid 鍐欏叆缂撳瓨锛� 绛夋敞鍐屾垚鍔熷彲浠ユ洿鏂扮姸鎬�
@@ -120,7 +124,7 @@
             }else {
                 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
                         : udpSipProvider.getNewCallId();
-                request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, SipUtils.getNewFromTag(), null, callId, www, callIdHeader, isRegister);
+                request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform, SipUtils.getNewFromTag(), null, callId, www, callIdHeader, isRegister);
             }
 
             transmitRequest(parentPlatform, request, null, okEvent);
@@ -154,7 +158,7 @@
             CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
 
-            Request request = headerProviderPlarformProvider.createMessageRequest(
+            Request request = headerProviderPlatformProvider.createMessageRequest(
                     parentPlatform,
                     keepaliveXml.toString(),
                     SipUtils.getNewFromTag(),
@@ -220,7 +224,7 @@
             CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
 
-            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, catalogXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
+            Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, catalogXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
             transmitRequest(parentPlatform, request);
 
         } catch (SipException | ParseException | InvalidArgumentException e) {
@@ -314,7 +318,7 @@
             CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
 
-            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, catalogXml, fromTag, SipUtils.getNewViaTag(), callIdHeader);
+            Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, catalogXml, fromTag, SipUtils.getNewViaTag(), callIdHeader);
             transmitRequest(parentPlatform, request, null, eventResult -> {
                 int indexNext = index + parentPlatform.getCatalogGroup();
                 sendCatalogResponse(channels, parentPlatform, sn, fromTag, indexNext);
@@ -354,7 +358,7 @@
             CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
 
-            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, deviceInfoXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
+            Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceInfoXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
             transmitRequest(parentPlatform, request);
 
         } catch (SipException | ParseException | InvalidArgumentException e) {
@@ -392,7 +396,7 @@
             CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
 
-            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
+            Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
             transmitRequest(parentPlatform, request);
 
         } catch (SipException | ParseException | InvalidArgumentException e) {
@@ -427,11 +431,7 @@
             deviceStatusXml.append("<Altitude>" + gpsMsgInfo.getAltitude() + "</Altitude>\r\n");
             deviceStatusXml.append("</Notify>\r\n");
 
-            CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
-                    : udpSipProvider.getNewCallId();
-            callIdHeader.setCallId(subscribeInfo.getCallId());
-
-            sendNotify(parentPlatform, deviceStatusXml.toString(), subscribeInfo, eventResult -> {
+           sendNotify(parentPlatform, deviceStatusXml.toString(), subscribeInfo, eventResult -> {
                 logger.error("鍙戦�丯OTIFY閫氱煡娑堟伅澶辫触銆傞敊璇細{} {}", eventResult.statusCode, eventResult.msg);
             }, null);
 
@@ -453,8 +453,8 @@
         if (parentPlatform == null) {
             return false;
         }
-        logger.info("[鍙戦�� 鎶ヨ璁㈤槄] {}/{}->{},{}", parentPlatform.getServerGBId(), deviceAlarm.getChannelId(),
-                deviceAlarm.getLongitude(), deviceAlarm.getLatitude());
+        logger.info("[鍙戦�佹姤璀﹂�氱煡] {}/{}->{},{}: {}", parentPlatform.getServerGBId(), deviceAlarm.getChannelId(),
+                deviceAlarm.getLongitude(), deviceAlarm.getLatitude(), JSONObject.toJSON(deviceAlarm));
         try {
             String characterSet = parentPlatform.getCharacterSet();
             StringBuffer deviceStatusXml = new StringBuffer(600);
@@ -477,7 +477,7 @@
             CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
 
-            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), SipUtils.getNewFromTag(), SipUtils.getNewViaTag(), callIdHeader);
+            Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), SipUtils.getNewFromTag(), SipUtils.getNewViaTag(), callIdHeader);
             transmitRequest(parentPlatform, request);
 
         } catch (SipException | ParseException  e) {
@@ -529,18 +529,15 @@
         return true;
     }
 
-    private void sendNotify(ParentPlatform parentPlatform, String catalogXmlContent,
+    private ClientTransaction sendNotify(ParentPlatform parentPlatform, String catalogXmlContent,
                                    SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent,  SipSubscribe.Event okEvent )
             throws NoSuchFieldException, IllegalAccessException, SipException, ParseException, InvalidArgumentException {
 		MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
         String characterSet = parentPlatform.getCharacterSet();
  		// 璁剧疆缂栫爜锛� 闃叉涓枃涔辩爜
 		messageFactory.setDefaultContentEncodingCharset(characterSet);
-        Dialog dialog  = subscribeInfo.getDialog();
-        if (dialog == null || !dialog.getState().equals(DialogState.CONFIRMED)) {
-            return;
-        }
-        SIPRequest notifyRequest = (SIPRequest)dialog.createRequest(Request.NOTIFY);
+
+        SIPRequest notifyRequest = headerProviderPlatformProvider.createNotifyRequest(parentPlatform, catalogXmlContent, subscribeInfo);
 
         notifyRequest.getCSeqHeader().setSeqNumber(redisCatchStorage.getCSEQ());
         
@@ -560,26 +557,32 @@
         sipURI.setHost(parentPlatform.getServerIP());
         sipURI.setPort(parentPlatform.getServerPort());
 
+//        ClientTransaction transaction = subscribeInfo.getClientTransaction();
+//        if (transaction == null || transaction.getState().equals(TransactionState.COMPLETED)) {
+//            if ("TCP".equals(parentPlatform.getTransport())) {
+//                transaction = tcpSipProvider.getNewClientTransaction(notifyRequest);
+//            } else if ("UDP".equals(parentPlatform.getTransport())) {
+//                transaction = udpSipProvider.getNewClientTransaction(notifyRequest);
+//            }
+//        }
+
         ClientTransaction transaction = null;
         if ("TCP".equals(parentPlatform.getTransport())) {
             transaction = tcpSipProvider.getNewClientTransaction(notifyRequest);
         } else if ("UDP".equals(parentPlatform.getTransport())) {
             transaction = udpSipProvider.getNewClientTransaction(notifyRequest);
         }
+
         // 娣诲姞閿欒璁㈤槄
         if (errorEvent != null) {
-            sipSubscribe.addErrorSubscribe(subscribeInfo.getCallId(), errorEvent);
+            sipSubscribe.addErrorSubscribe(subscribeInfo.getRequest().getCallIdHeader().getCallId(), errorEvent);
         }
         // 娣诲姞璁㈤槄
         if (okEvent != null) {
-            sipSubscribe.addOkSubscribe(subscribeInfo.getCallId(), okEvent);
+            sipSubscribe.addOkSubscribe(subscribeInfo.getRequest().getCallIdHeader().getCallId(), okEvent);
         }
-        if (transaction == null) {
-            logger.error("骞冲彴{}鐨凾ransport閿欒锛歿}",parentPlatform.getServerGBId(), parentPlatform.getTransport());
-            return;
-        }
-        dialog.sendRequest(transaction);
-
+        transaction.sendRequest();
+        return transaction;
     }
 
     private  String getCatalogXmlContentForCatalogAddOrUpdate(ParentPlatform parentPlatform, List<DeviceChannel> channels, int sumNum, String type, SubscribeInfo subscribeInfo) {
@@ -755,7 +758,7 @@
             // callid
             CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
-            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, recordXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
+            Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, recordXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
             transmitRequest(parentPlatform, request);
 
         } catch (SipException | ParseException | InvalidArgumentException e) {
@@ -774,36 +777,8 @@
             return false;
         }
 
-        byte[] dialogByteArray = sendRtpItem.getDialog();
-        if (dialogByteArray == null) {
-            return false;
-        }
         try{
-            SIPDialog dialog = (SIPDialog) SerializeUtils.deSerialize(dialogByteArray);
-            SipStack sipStack;
-            if ("TCP".equals(platform.getTransport())) {
-                sipStack = tcpSipProvider.getSipStack();
-            } else {
-                sipStack = udpSipProvider.getSipStack();
-            }
-            SIPDialog sipDialog = ((SipStackImpl) sipStack).putDialog(dialog);
-            if (dialog != sipDialog) {
-                dialog = sipDialog;
-            }
-            if ("TCP".equals(platform.getTransport())) {
-                dialog.setSipProvider(tcpSipProvider);
-            } else {
-                dialog.setSipProvider(udpSipProvider);
-            }
 
-            Field sipStackField = SIPDialog.class.getDeclaredField("sipStack");
-            sipStackField.setAccessible(true);
-            sipStackField.set(dialog, sipStack);
-            Field eventListenersField = SIPDialog.class.getDeclaredField("eventListeners");
-            eventListenersField.setAccessible(true);
-            eventListenersField.set(dialog, new HashSet<>());
-
-            SIPRequest messageRequest = (SIPRequest)dialog.createRequest(Request.MESSAGE);
             String characterSet = platform.getCharacterSet();
             StringBuffer mediaStatusXml = new StringBuffer(200);
             mediaStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
@@ -813,6 +788,10 @@
             mediaStatusXml.append("<DeviceID>" + sendRtpItem.getChannelId() + "</DeviceID>\r\n");
             mediaStatusXml.append("<NotifyType>121</NotifyType>\r\n");
             mediaStatusXml.append("</Notify>\r\n");
+
+            SIPRequest messageRequest = (SIPRequest)headerProviderPlatformProvider.createMessageRequest(platform, mediaStatusXml.toString(),
+                    sendRtpItem);
+
             ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
             messageRequest.setContent(mediaStatusXml.toString(), contentTypeHeader);
             SipURI sipURI = (SipURI) messageRequest.getRequestURI();
@@ -824,17 +803,15 @@
             }else {
                 clientTransaction = udpSipProvider.getNewClientTransaction(messageRequest);
             }
-            dialog.sendRequest(clientTransaction);
+            clientTransaction.sendRequest();
         } catch (SipException e) {
             e.printStackTrace();
             return false;
         } catch (ParseException e) {
             e.printStackTrace();
             return false;
-        } catch (NoSuchFieldException e) {
-            e.printStackTrace();
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
+        } catch (InvalidArgumentException e) {
+            throw new RuntimeException(e);
         }
         return true;
 
@@ -848,61 +825,46 @@
         }
         SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platform.getServerGBId(), null, null, callId);
         if (sendRtpItem != null) {
-            String mediaServerId = sendRtpItem.getMediaServerId();
-            MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
-            if (mediaServerItem != null) {
-                mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
-                zlmrtpServerFactory.closeRTPServer(mediaServerItem, sendRtpItem.getStreamId());
+            streamByeCmd(platform, sendRtpItem);
+        }
+    }
+
+    @Override
+    public void streamByeCmd(ParentPlatform platform, SendRtpItem sendRtpItem) {
+        if (sendRtpItem == null ) {
+            logger.info("[鍚戜笂绾у彂閫丅YE]锛� sendRtpItem 涓篘ULL");
+            return;
+        }
+        if (platform == null) {
+            logger.info("[鍚戜笂绾у彂閫丅YE]锛� platform 涓篘ULL");
+            return;
+        }
+        logger.info("[鍚戜笂绾у彂閫丅YE]锛� {}/{}", platform.getServerGBId(), sendRtpItem.getChannelId());
+        String mediaServerId = sendRtpItem.getMediaServerId();
+        MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
+        if (mediaServerItem != null) {
+            mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
+            zlmrtpServerFactory.closeRTPServer(mediaServerItem, sendRtpItem.getStreamId());
+        }
+        try {
+
+            SIPRequest byeRequest = headerProviderPlatformProvider.createByeRequest(platform, sendRtpItem);
+            if (byeRequest == null) {
+                logger.warn("[鍚戜笂绾у彂閫乥ye]锛氭棤娉曞垱寤� byeRequest");
             }
-            byte[] dialogByteArray = sendRtpItem.getDialog();
-            if (dialogByteArray != null) {
-                SIPDialog dialog = (SIPDialog) SerializeUtils.deSerialize(dialogByteArray);
-                SipStack sipStack;
-                if ("TCP".equals(platform.getTransport())) {
-                    sipStack = tcpSipProvider.getSipStack();
-                } else {
-                    sipStack = udpSipProvider.getSipStack();
-                }
-                SIPDialog sipDialog = ((SipStackImpl) sipStack).putDialog(dialog);
-                if (dialog != sipDialog) {
-                    dialog = sipDialog;
-                }
-                try {
-                    if ("TCP".equals(platform.getTransport())) {
-                        dialog.setSipProvider(tcpSipProvider);
-                    } else {
-                        dialog.setSipProvider(udpSipProvider);
-                    }
-                    Field sipStackField = SIPDialog.class.getDeclaredField("sipStack");
-                    sipStackField.setAccessible(true);
-                    sipStackField.set(dialog, sipStack);
-                    Field eventListenersField = SIPDialog.class.getDeclaredField("eventListeners");
-                    eventListenersField.setAccessible(true);
-                    eventListenersField.set(dialog, new HashSet<>());
-
-                    Request byeRequest = dialog.createRequest(Request.BYE);
-
-                    SipURI byeURI = (SipURI) byeRequest.getRequestURI();
-                    byeURI.setHost(platform.getServerIP());
-                    byeURI.setPort(platform.getServerPort());
-                    ClientTransaction clientTransaction;
-                    if ("TCP".equals(platform.getTransport())) {
-                        clientTransaction = tcpSipProvider.getNewClientTransaction(byeRequest);
-                    } else {
-                        clientTransaction = udpSipProvider.getNewClientTransaction(byeRequest);
-                    }
-                    dialog.sendRequest(clientTransaction);
-                } catch (SipException e) {
-                    e.printStackTrace();
-                } catch (ParseException e) {
-                    e.printStackTrace();
-                } catch (NoSuchFieldException e) {
-                    e.printStackTrace();
-                } catch (IllegalAccessException e) {
-                    e.printStackTrace();
-                }
-
+            ClientTransaction clientTransaction;
+            if ("TCP".equals(platform.getTransport())) {
+                clientTransaction = tcpSipProvider.getNewClientTransaction(byeRequest);
+            } else {
+                clientTransaction = udpSipProvider.getNewClientTransaction(byeRequest);
             }
+            clientTransaction.sendRequest();
+        } catch (SipException e) {
+            e.printStackTrace();
+        } catch (ParseException e) {
+            e.printStackTrace();
+        } catch (InvalidArgumentException e) {
+            throw new RuntimeException(e);
         }
     }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java
index f59f37b..57945e7 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java
@@ -1,9 +1,11 @@
 package com.genersoft.iot.vmp.gb28181.transmit.event.request;
 
 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
+import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
 import gov.nist.javax.sip.SipProviderImpl;
 import gov.nist.javax.sip.SipStackImpl;
 import gov.nist.javax.sip.message.SIPRequest;
+import gov.nist.javax.sip.message.SIPResponse;
 import gov.nist.javax.sip.stack.SIPServerTransaction;
 import org.apache.commons.lang3.ArrayUtils;
 import org.dom4j.Document;
@@ -19,10 +21,7 @@
 import javax.sip.address.Address;
 import javax.sip.address.AddressFactory;
 import javax.sip.address.SipURI;
-import javax.sip.header.ContentTypeHeader;
-import javax.sip.header.ExpiresHeader;
-import javax.sip.header.HeaderFactory;
-import javax.sip.header.ViaHeader;
+import javax.sip.header.*;
 import javax.sip.message.MessageFactory;
 import javax.sip.message.Request;
 import javax.sip.message.Response;
@@ -59,9 +58,6 @@
 	public ServerTransaction getServerTransaction(RequestEvent evt) {
 		Request request = evt.getRequest();
 		ServerTransaction serverTransaction = evt.getServerTransaction();
-		if (serverTransaction != null) {
-			System.out.println(serverTransaction.getState().toString());
-		}
 		// 鍒ゆ柇TCP杩樻槸UDP
 		ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
 		String transport = reqViaHeader.getTransport();
@@ -120,105 +116,107 @@
 		return null;
 	}
 
+	class ResponseAckExtraParam{
+		String content;
+		ContentTypeHeader contentTypeHeader;
+		SipURI sipURI;
+		int expires = -1;
+	}
+
 	/***
 	 * 鍥炲鐘舵�佺爜
 	 * 100 trying
 	 * 200 OK
 	 * 400
 	 * 404
-	 * @param evt
-	 * @throws SipException
-	 * @throws InvalidArgumentException
-	 * @throws ParseException
 	 */
-	public void responseAck(RequestEvent evt, int statusCode) throws SipException, InvalidArgumentException, ParseException {
-		Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
-		ServerTransaction serverTransaction = getServerTransaction(evt);
-		if (serverTransaction == null) {
-			logger.warn("鍥炲澶辫触锛歿}", response);
-			return;
-		}
-		serverTransaction.sendResponse(response);
-		if (statusCode >= 200 && !"NOTIFY".equalsIgnoreCase(evt.getRequest().getMethod())) {
-
-			if (serverTransaction.getDialog() != null) {
-				serverTransaction.getDialog().delete();
-			}
-		}
+	public SIPResponse responseAck(ServerTransaction serverTransaction, int statusCode) throws SipException, InvalidArgumentException, ParseException {
+		return responseAck(serverTransaction, statusCode, null);
 	}
 
-	public void responseAck(RequestEvent evt, int statusCode, String msg) throws SipException, InvalidArgumentException, ParseException {
-		Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
-		response.setReasonPhrase(msg);
-		ServerTransaction serverTransaction = getServerTransaction(evt);
+	public SIPResponse responseAck(ServerTransaction serverTransaction, int statusCode, String msg) throws SipException, InvalidArgumentException, ParseException {
+		return responseAck(serverTransaction, statusCode, msg, null);
+	}
+
+	public SIPResponse responseAck(ServerTransaction serverTransaction, int statusCode, String msg, ResponseAckExtraParam responseAckExtraParam) throws SipException, InvalidArgumentException, ParseException {
+		ToHeader toHeader = (ToHeader) serverTransaction.getRequest().getHeader(ToHeader.NAME);
+		if (toHeader.getTag() == null) {
+			toHeader.setTag(SipUtils.getNewTag());
+		}
+		SIPResponse response = (SIPResponse)getMessageFactory().createResponse(statusCode, serverTransaction.getRequest());
+		if (msg != null) {
+			response.setReasonPhrase(msg);
+		}
+		if (responseAckExtraParam != null) {
+			if (responseAckExtraParam.sipURI != null && serverTransaction.getRequest().getMethod().equals(Request.INVITE)) {
+				logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort());
+				Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(
+						SipFactory.getInstance().createAddressFactory().createSipURI(responseAckExtraParam.sipURI.getUser(),  responseAckExtraParam.sipURI.getHost()+":"+responseAckExtraParam.sipURI.getPort()
+						));
+				response.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress));
+			}
+			if (responseAckExtraParam.contentTypeHeader != null) {
+				response.setContent(responseAckExtraParam.content, responseAckExtraParam.contentTypeHeader);
+			}
+
+			if (serverTransaction.getRequest().getMethod().equals(Request.SUBSCRIBE)) {
+				if (responseAckExtraParam.expires == -1) {
+					logger.error("[鍙傛暟涓嶅叏] 2xx鐨凷UBSCRIBE鍥炲锛屽繀椤昏缃瓻xpires header");
+				}else {
+					ExpiresHeader expiresHeader = SipFactory.getInstance().createHeaderFactory().createExpiresHeader(responseAckExtraParam.expires);
+					response.addHeader(expiresHeader);
+				}
+			}
+		}else {
+			if (serverTransaction.getRequest().getMethod().equals(Request.SUBSCRIBE)) {
+				logger.error("[鍙傛暟涓嶅叏] 2xx鐨凷UBSCRIBE鍥炲锛屽繀椤昏缃瓻xpires header");
+			}
+		}
 		serverTransaction.sendResponse(response);
-		if (statusCode >= 200 && !"NOTIFY".equalsIgnoreCase(evt.getRequest().getMethod())) {
+		if (statusCode >= 200 && !"NOTIFY".equalsIgnoreCase(serverTransaction.getRequest().getMethod())) {
 			if (serverTransaction.getDialog() != null) {
 				serverTransaction.getDialog().delete();
 			}
 		}
+		return response;
 	}
 
 	/**
 	 * 鍥炲甯dp鐨�200
-	 * @param evt
-	 * @param sdp
-	 * @throws SipException
-	 * @throws InvalidArgumentException
-	 * @throws ParseException
 	 */
-	public void responseSdpAck(RequestEvent evt, String sdp, ParentPlatform platform) throws SipException, InvalidArgumentException, ParseException {
-		Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
-		SipFactory sipFactory = SipFactory.getInstance();
-		ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
-		response.setContent(sdp, contentTypeHeader);
+	public SIPResponse responseSdpAck(ServerTransaction serverTransaction, String sdp, ParentPlatform platform) throws SipException, InvalidArgumentException, ParseException {
+
+		ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
 
 		// 鍏煎鍥芥爣涓殑浣跨敤缂栫爜@鍩熷悕浣滀负RequestURI鐨勬儏鍐�
-		SipURI sipURI = (SipURI)evt.getRequest().getRequestURI();
+		SipURI sipURI = (SipURI)serverTransaction.getRequest().getRequestURI();
 		if (sipURI.getPort() == -1) {
-			sipURI = sipFactory.createAddressFactory().createSipURI(platform.getServerGBId(),  platform.getServerIP()+":"+platform.getServerPort());
+			sipURI = SipFactory.getInstance().createAddressFactory().createSipURI(platform.getServerGBId(),  platform.getServerIP()+":"+platform.getServerPort());
 		}
-		logger.debug("responseSdpAck SipURI: {}:{}", sipURI.getHost(), sipURI.getPort());
+		ResponseAckExtraParam responseAckExtraParam = new ResponseAckExtraParam();
+		responseAckExtraParam.contentTypeHeader = contentTypeHeader;
+		responseAckExtraParam.content = sdp;
+		responseAckExtraParam.sipURI = sipURI;
 
-		Address concatAddress = sipFactory.createAddressFactory().createAddress(
-				sipFactory.createAddressFactory().createSipURI(sipURI.getUser(),  sipURI.getHost()+":"+sipURI.getPort()
-				));
-		response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
-		ServerTransaction serverTransaction = getServerTransaction(evt);
-		if (serverTransaction == null) {
-
-		}
-		getServerTransaction(evt).sendResponse(response);
+		return responseAck(serverTransaction, Response.OK, null, responseAckExtraParam);
 	}
 
 	/**
 	 * 鍥炲甯ml鐨�200
-	 * @param evt
-	 * @param xml
-	 * @throws SipException
-	 * @throws InvalidArgumentException
-	 * @throws ParseException
 	 */
-	public Response responseXmlAck(RequestEvent evt, String xml, ParentPlatform platform) throws SipException, InvalidArgumentException, ParseException {
-		Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
-		SipFactory sipFactory = SipFactory.getInstance();
-		ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
-		response.setContent(xml, contentTypeHeader);
+	public SIPResponse responseXmlAck(ServerTransaction serverTransaction, String xml, ParentPlatform platform, Integer expires) throws SipException, InvalidArgumentException, ParseException {
+		ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
 
-		// 鍏煎鍥芥爣涓殑浣跨敤缂栫爜@鍩熷悕浣滀负RequestURI鐨勬儏鍐�
-		SipURI sipURI = (SipURI)evt.getRequest().getRequestURI();
+		SipURI sipURI = (SipURI)serverTransaction.getRequest().getRequestURI();
 		if (sipURI.getPort() == -1) {
-			sipURI = sipFactory.createAddressFactory().createSipURI(platform.getServerGBId(),  platform.getServerIP()+":"+platform.getServerPort());
+			sipURI = SipFactory.getInstance().createAddressFactory().createSipURI(platform.getServerGBId(),  platform.getServerIP()+":"+platform.getServerPort());
 		}
-		logger.debug("responseXmlAck SipURI: {}:{}", sipURI.getHost(), sipURI.getPort());
-
-		Address concatAddress = sipFactory.createAddressFactory().createAddress(
-				sipFactory.createAddressFactory().createSipURI(sipURI.getUser(),  sipURI.getHost()+":"+sipURI.getPort()
-				));
-		response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
-		response.addHeader(evt.getRequest().getHeader(ExpiresHeader.NAME));
-		getServerTransaction(evt).sendResponse(response);
-		return response;
+		ResponseAckExtraParam responseAckExtraParam = new ResponseAckExtraParam();
+		responseAckExtraParam.contentTypeHeader = contentTypeHeader;
+		responseAckExtraParam.content = xml;
+		responseAckExtraParam.sipURI = sipURI;
+		responseAckExtraParam.expires = expires;
+		return responseAck(serverTransaction, Response.OK, null, responseAckExtraParam);
 	}
 
 	public Element getRootElement(RequestEvent evt) throws DocumentException {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
index d49cce3..571186f 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
@@ -16,7 +16,7 @@
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
 import com.genersoft.iot.vmp.service.IMediaServerService;
 import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg;
-import com.genersoft.iot.vmp.service.impl.RedisGbPlayMsgListener;
+import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
 import gov.nist.javax.sip.message.SIPRequest;
@@ -29,6 +29,7 @@
 import org.springframework.stereotype.Component;
 
 import javax.sip.*;
+import javax.sip.RequestEvent;
 import javax.sip.address.SipURI;
 import javax.sip.header.CallIdHeader;
 import javax.sip.header.FromHeader;
@@ -93,47 +94,41 @@
 	 */
 	@Override
 	public void process(RequestEvent evt) {
-		Dialog dialog = evt.getDialog();
-		CallIdHeader callIdHeader = (CallIdHeader) evt.getRequest().getHeader(CallIdHeader.NAME);
-		if (dialog == null) {
-			return;
+		CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
+
+		String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
+		logger.info("[鏀跺埌ACK]锛� platformGbId->{}", platformGbId);
+		ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformGbId);
+		// 鍙栨秷璁剧疆鐨勮秴鏃朵换鍔�
+		dynamicTask.stop(callIdHeader.getCallId());
+		String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
+		SendRtpItem sendRtpItem =  redisCatchStorage.querySendRTPServer(platformGbId, channelId, null, callIdHeader.getCallId());
+		String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
+		MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
+		logger.info("鏀跺埌ACK锛宺tp/{}寮�濮嬪悜涓婄骇鎺ㄦ祦, 鐩爣 {}:{}锛孲SRC={}", sendRtpItem.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc());
+		Map<String, Object> param = new HashMap<>();
+		param.put("vhost","__defaultVhost__");
+		param.put("app",sendRtpItem.getApp());
+		param.put("stream",sendRtpItem.getStreamId());
+		param.put("ssrc", sendRtpItem.getSsrc());
+		param.put("src_port", sendRtpItem.getLocalPort());
+		param.put("pt", sendRtpItem.getPt());
+		param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
+		param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
+		if (!sendRtpItem.isTcp() && parentPlatform.isRtcp()) {
+			// 寮�鍚痳tcp淇濇椿
+			param.put("udp_rtcp_timeout", "1");
 		}
-		if (dialog.getState() == DialogState.CONFIRMED) {
-			String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
-			logger.info("ACK璇锋眰锛� platformGbId->{}", platformGbId);
-			ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformGbId);
-			// 鍙栨秷璁剧疆鐨勮秴鏃朵换鍔�
-			dynamicTask.stop(callIdHeader.getCallId());
-//			String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
-			SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, null, null, callIdHeader.getCallId());
-			String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
-			MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
-			logger.info("[鏀跺埌ACK]锛屽紑濮嬩娇鐢▄}鍚戜笂绾ф帹娴� {}/{}->{}:{}({})", sendRtpItem.isTcp() ? "TCP" : "UDP",
-					sendRtpItem.getApp(), sendRtpItem.getStreamId(),
-					sendRtpItem.getIp(), sendRtpItem.getPort(),
-					sendRtpItem.getSsrc());
-			Map<String, Object> param = new HashMap<>();
-			param.put("vhost", "__defaultVhost__");
-			param.put("app", sendRtpItem.getApp());
-			param.put("stream", sendRtpItem.getStreamId());
-			param.put("ssrc", sendRtpItem.getSsrc());
-			param.put("src_port", sendRtpItem.getLocalPort());
-			param.put("pt", sendRtpItem.getPt());
-			param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
-			param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
-			if (!sendRtpItem.isTcp() && parentPlatform.isRtcp()) {
-				// 寮�鍚痳tcp淇濇椿
-				param.put("udp_rtcp_timeout", "1");
-			}
-			JSONObject jsonObject;
-			if (sendRtpItem.isTcpActive()) {
-				jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param);
-			} else {
-				param.put("is_udp", is_Udp);
-				param.put("dst_url", sendRtpItem.getIp());
-				param.put("dst_port", sendRtpItem.getPort());
-				jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
-			}
+
+		JSONObject jsonObject;
+		if (sendRtpItem.isTcpActive()) {
+			jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param);
+		} else {
+			param.put("is_udp", is_Udp);
+			param.put("dst_url", sendRtpItem.getIp());
+			param.put("dst_port", sendRtpItem.getPort());
+			jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
+		}
 
 			if (jsonObject == null) {
 				logger.error("RTP鎺ㄦ祦澶辫触: 璇锋鏌LM鏈嶅姟");
@@ -155,12 +150,8 @@
 					// 璇煶瀵硅
 					try {
 						cmder.streamByeCmd((SIPDialog) evt.getDialog(), sendRtpItem.getChannelId(), (SIPRequest) evt.getRequest(), null);
-					} catch (SipException e) {
-						throw new RuntimeException(e);
-					} catch (ParseException e) {
-						throw new RuntimeException(e);
-					} catch (InvalidArgumentException e) {
-						throw new RuntimeException(e);
+					} catch (SipException | ParseException | InvalidArgumentException e) {
+						logger.error("[鍛戒护鍙戦�佸け璐 鍋滄璇煶瀵硅: {}", e.getMessage());
 					}
 				} else {
 					// 鍚戜笂绾у钩鍙�
@@ -188,12 +179,8 @@
 		if (jsonObject == null) {
 			logger.error("RTP鎺ㄦ祦澶辫触: 璇锋鏌LM鏈嶅姟");
 		} else if (jsonObject.getInteger("code") == 0) {
+			logger.info("璋冪敤ZLM鎺ㄦ祦鎺ュ彛, 缁撴灉锛� {}",  jsonObject);
 			logger.info("RTP鎺ㄦ祦鎴愬姛[ {}/{} ]锛寋}->{}:{}, " ,param.get("app"), param.get("stream"), jsonObject.getString("local_port"), param.get("dst_url"), param.get("dst_port"));
-			byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());
-			sendRtpItem.setDialog(dialogByteArray);
-			byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());
-			sendRtpItem.setTransaction(transactionByteArray);
-			redisCatchStorage.updateSendRTPSever(sendRtpItem);
 		} else {
 			logger.error("RTP鎺ㄦ祦澶辫触: {}, 鍙傛暟锛歿}",jsonObject.getString("msg"),JSONObject.toJSON(param));
 			if (sendRtpItem.isOnlyAudio()) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
index dc4b273..9adb3bb 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
@@ -82,78 +82,70 @@
 	@Override
 	public void process(RequestEvent evt) {
 		try {
-			responseAck(evt, Response.OK);
-			Dialog dialog = evt.getDialog();
+			responseAck(getServerTransaction(evt), Response.OK);
 			CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
-			if (dialog == null) {
-				return;
-			}
-			if (dialog.getState().equals(DialogState.TERMINATED)) {
-				String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
-				String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
-				SendRtpItem sendRtpItem =  redisCatchStorage.querySendRTPServer(platformGbId, null, null, callIdHeader.getCallId());
-				logger.info("鏀跺埌bye, [{}/{}]", platformGbId, channelId);
-				if (sendRtpItem != null ){
-					String streamId = sendRtpItem.getStreamId();
-					Map<String, Object> param = new HashMap<>();
-					param.put("vhost","__defaultVhost__");
-					param.put("app",sendRtpItem.getApp());
-					param.put("stream",streamId);
-					param.put("ssrc",sendRtpItem.getSsrc());
-					logger.info("鏀跺埌bye:鍋滄鍚戜笂绾ф帹娴侊細" + streamId);
-					MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
-					zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
-					redisCatchStorage.deleteSendRTPServer(platformGbId, sendRtpItem.getChannelId(), callIdHeader.getCallId(), null);
-					redisCatchStorage.deleteSendRTPServer(platformGbId, channelId, callIdHeader.getCallId(), null);
-					zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
-					int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId);
-					if (totalReaderCount <= 0) {
-						logger.info("鏀跺埌bye: {} 鏃犲叾瀹冭鐪嬭�咃紝閫氱煡璁惧鍋滄鎺ㄦ祦", streamId);
-						if (sendRtpItem.getPlayType().equals(InviteStreamType.PLAY)) {
-							cmder.streamByeCmd(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId(), streamId, null);
-						}
-						if (sendRtpItem.isOnlyAudio()) {
-							playService.stopAudioBroadcast(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
-						}
-						if (sendRtpItem.getPlayType().equals(InviteStreamType.PUSH)) {
-							MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0,
-									sendRtpItem.getApp(), sendRtpItem.getStreamId(), sendRtpItem.getChannelId(),
-									sendRtpItem.getPlatformId(), null, null, sendRtpItem.getMediaServerId());
-							redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel);
-						}
+			String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
+			String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
+			SendRtpItem sendRtpItem =  redisCatchStorage.querySendRTPServer(platformGbId, channelId, null, callIdHeader.getCallId());
+			logger.info("[鏀跺埌bye] {}/{}", platformGbId, channelId);
+			if (sendRtpItem != null){
+				String streamId = sendRtpItem.getStreamId();
+				Map<String, Object> param = new HashMap<>();
+				param.put("vhost","__defaultVhost__");
+				param.put("app",sendRtpItem.getApp());
+				param.put("stream",streamId);
+				param.put("ssrc",sendRtpItem.getSsrc());
+				logger.info("[鏀跺埌bye] 鍋滄鍚戜笂绾ф帹娴侊細{}", streamId);
+				MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
+				redisCatchStorage.deleteSendRTPServer(platformGbId, channelId, callIdHeader.getCallId(), null);
+				zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
+				int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId);
+				if (totalReaderCount <= 0) {
+					logger.info("[鏀跺埌bye] {} 鏃犲叾瀹冭鐪嬭�咃紝閫氱煡璁惧鍋滄鎺ㄦ祦", streamId);
+					if (sendRtpItem.getPlayType().equals(InviteStreamType.PLAY)) {
+						cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId, streamId, null);
+					}
+					if (sendRtpItem.isOnlyAudio()) {
+						playService.stopAudioBroadcast(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
+					}
+					if (sendRtpItem.getPlayType().equals(InviteStreamType.PUSH)) {
+						MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0,
+								sendRtpItem.getApp(), sendRtpItem.getStreamId(), sendRtpItem.getChannelId(),
+								sendRtpItem.getPlatformId(), null, null, sendRtpItem.getMediaServerId());
+						redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel);
 					}
 				}
-				// 鍙兘鏄澶囦富鍔ㄥ仠姝�
-				Device device = storager.queryVideoDeviceByChannelId(platformGbId);
-                if (device != null) {
-					storager.stopPlay(device.getDeviceId(), channelId);
-					StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);
-					if (streamInfo != null) {
-						redisCatchStorage.stopPlay(streamInfo);
-						mediaServerService.closeRTPServer(streamInfo.getMediaServerId(), streamInfo.getStream());
-					}
-					SsrcTransaction ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "play", null);
-					if (ssrcTransactionForPlay != null){
-						SIPDialog dialogForPlay = (SIPDialog) SerializeUtils.deSerialize(ssrcTransactionForPlay.getDialog());
-						if (dialogForPlay.getCallId().getCallId().equals(callIdHeader.getCallId())){
-							// 閲婃斁ssrc
-							MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlay.getMediaServerId());
-							if (mediaServerItem != null) {
-								mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransactionForPlay.getSsrc());
-							}
-							streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlay.getStream());
-						}
-					}
-					SsrcTransaction ssrcTransactionForPlayBack = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, callIdHeader.getCallId(), null);
-					if (ssrcTransactionForPlayBack != null) {
+			}
+			// 鍙兘鏄澶囦富鍔ㄥ仠姝�
+			Device device = storager.queryVideoDeviceByChannelId(platformGbId);
+			if (device != null) {
+				storager.stopPlay(device.getDeviceId(), channelId);
+				StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);
+				if (streamInfo != null) {
+					redisCatchStorage.stopPlay(streamInfo);
+					mediaServerService.closeRTPServer(streamInfo.getMediaServerId(), streamInfo.getStream());
+				}
+				SsrcTransaction ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "play", null);
+				if (ssrcTransactionForPlay != null){
+					SIPDialog dialogForPlay = (SIPDialog) SerializeUtils.deSerialize(ssrcTransactionForPlay.getDialog());
+					if (dialogForPlay.getCallId().getCallId().equals(callIdHeader.getCallId())){
 						// 閲婃斁ssrc
-						MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlayBack.getMediaServerId());
+						MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlay.getMediaServerId());
 						if (mediaServerItem != null) {
-							mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransactionForPlayBack.getSsrc());
+							mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransactionForPlay.getSsrc());
 						}
-						streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlayBack.getStream());
+						streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlay.getStream());
 					}
 				}
+				SsrcTransaction ssrcTransactionForPlayBack = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, callIdHeader.getCallId(), null);
+				if (ssrcTransactionForPlayBack != null) {
+					// 閲婃斁ssrc
+					MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlayBack.getMediaServerId());
+					if (mediaServerItem != null) {
+						mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransactionForPlayBack.getSsrc());
+					}
+					streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlayBack.getStream());
+				}
 			}
 		} catch (SipException e) {
 			e.printStackTrace();
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 b855bf7..a843159 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
@@ -14,7 +14,6 @@
 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
-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.transmit.event.request.ISIPRequestProcessor;
 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
@@ -32,7 +31,8 @@
 import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
 import com.genersoft.iot.vmp.service.impl.RedisGbPlayMsgListener;
-import com.genersoft.iot.vmp.service.impl.RedisPushStreamResponseListener;
+import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener;
+import com.genersoft.iot.vmp.service.redisMsg.RedisPushStreamResponseListener;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
 import com.genersoft.iot.vmp.utils.DateUtil;
@@ -43,6 +43,8 @@
 import gov.nist.javax.sdp.fields.TimeField;
 import gov.nist.javax.sip.message.SIPRequest;
 import gov.nist.javax.sip.stack.SIPDialog;
+import gov.nist.javax.sip.message.SIPRequest;
+import gov.nist.javax.sip.message.SIPResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.InitializingBean;
@@ -160,17 +162,19 @@
             String channelId = SipUtils.getChannelIdFromRequest(request);
             String requesterId = SipUtils.getUserIdFromFromHeader(request);
             CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
+            ServerTransaction serverTransaction = getServerTransaction(evt);
             if (requesterId == null || channelId == null) {
                 logger.info("鏃犳硶浠嶧romHeader鐨凙ddress涓幏鍙栧埌骞冲彴id锛岃繑鍥�400");
                 // 鍙傛暟涓嶅叏锛� 鍙�400锛岃姹傞敊璇�
-                responseAck(evt, Response.BAD_REQUEST);
+                responseAck(serverTransaction, Response.BAD_REQUEST);
                 return;
             }
+
 
             // 鏌ヨ璇锋眰鏄惁鏉ヨ嚜涓婄骇骞冲彴\璁惧
             ParentPlatform platform = storager.queryParentPlatByServerGBId(requesterId);
             if (platform == null) {
-                inviteFromDeviceHandle(evt, requesterId, channelId);
+                inviteFromDeviceHandle(serverTransaction, requesterId);
             } else {
                 // 鏌ヨ骞冲彴涓嬫槸鍚︽湁璇ラ�氶亾
                 DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
@@ -182,12 +186,13 @@
                 StreamProxyItem proxyByAppAndStream =null;
                 // 涓嶆槸閫氶亾鍙兘鏄洿鎾祦
                 if (channel != null && gbStream == null) {
-                    if (channel.getStatus() == 0) {
-                        logger.info("閫氶亾绂荤嚎锛岃繑鍥�400");
-                        responseAck(evt, Response.BAD_REQUEST, "channel [" + channel.getChannelId() + "] offline");
-                        return;
-                    }
-                    responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 閫氶亾瀛樺湪锛屽彂181锛屽懠鍙浆鎺ヤ腑
+//                    if (channel.getStatus() == 0) {
+//                        logger.info("閫氶亾绂荤嚎锛岃繑鍥�400");
+//                        responseAck(serverTransaction, Response.BAD_REQUEST, "channel [" + channel.getChannelId() + "] offline");
+//                        return;
+//                    }
+                    // 閫氶亾瀛樺湪锛屽彂100锛孴RYING
+                    responseAck(serverTransaction, Response.TRYING);
                 } else if (channel == null && gbStream != null) {
 
                     String mediaServerId = gbStream.getMediaServerId();
@@ -195,13 +200,13 @@
                     if (mediaServerItem == null) {
                         if ("proxy".equals(gbStream.getStreamType())) {
                             logger.info("[ app={}, stream={} ]鎵句笉鍒皕lm {}锛岃繑鍥�410", gbStream.getApp(), gbStream.getStream(), mediaServerId);
-                            responseAck(evt, Response.GONE);
+                            responseAck(serverTransaction, Response.GONE);
                             return;
                         } else {
                             streamPushItem = streamPushService.getPush(gbStream.getApp(), gbStream.getStream());
                             if (streamPushItem == null || streamPushItem.getServerId().equals(userSetting.getServerId())) {
                                 logger.info("[ app={}, stream={} ]鎵句笉鍒皕lm {}锛岃繑鍥�410", gbStream.getApp(), gbStream.getStream(), mediaServerId);
-                                responseAck(evt, Response.GONE);
+                                responseAck(serverTransaction, Response.GONE);
                                 return;
                             }
                         }
@@ -210,25 +215,25 @@
                             streamPushItem = streamPushService.getPush(gbStream.getApp(), gbStream.getStream());
                             if (streamPushItem == null) {
                                 logger.info("[ app={}, stream={} ]鎵句笉鍒皕lm {}锛岃繑鍥�410", gbStream.getApp(), gbStream.getStream(), mediaServerId);
-                                responseAck(evt, Response.GONE);
+                                responseAck(serverTransaction, Response.GONE);
                                 return;
                             }
                         }else if("proxy".equals(gbStream.getStreamType())){
                             proxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(gbStream.getApp(), gbStream.getStream());
                             if (proxyByAppAndStream == null) {
                                 logger.info("[ app={}, stream={} ]鎵句笉鍒皕lm {}锛岃繑鍥�410", gbStream.getApp(), gbStream.getStream(), mediaServerId);
-                                responseAck(evt, Response.GONE);
+                                responseAck(serverTransaction, Response.GONE);
                                 return;
                             }
                         }
                     }
-                    responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 閫氶亾瀛樺湪锛屽彂181锛屽懠鍙浆鎺ヤ腑
+                    responseAck(serverTransaction, Response.CALL_IS_BEING_FORWARDED); // 閫氶亾瀛樺湪锛屽彂181锛屽懠鍙浆鎺ヤ腑
                 } else if (catalog != null) {
-                    responseAck(evt, Response.BAD_REQUEST, "catalog channel can not play"); // 鐩綍涓嶆敮鎸佺偣鎾�
+                    responseAck(serverTransaction, Response.BAD_REQUEST, "catalog channel can not play"); // 鐩綍涓嶆敮鎸佺偣鎾�
                     return;
                 } else {
                     logger.info("閫氶亾涓嶅瓨鍦紝杩斿洖404");
-                    responseAck(evt, Response.NOT_FOUND); // 閫氶亾涓嶅瓨鍦紝鍙�404锛岃祫婧愪笉瀛樺湪
+                    responseAck(serverTransaction, Response.NOT_FOUND); // 閫氶亾涓嶅瓨鍦紝鍙�404锛岃祫婧愪笉瀛樺湪
                     return;
                 }
                 // 瑙f瀽sdp娑堟伅, 浣跨敤jainsip 鑷甫鐨剆dp瑙f瀽鏂瑰紡
@@ -241,7 +246,7 @@
                 String ssrc;
                 SessionDescription sdp;
                 if (ssrcIndex >= 0) {
-                    //ssrc瑙勫畾闀垮害涓�10瀛楄妭锛屼笉鍙栦綑涓嬮暱搴︿互閬垮厤鍚庣画杩樻湁鈥渇=鈥濆瓧娈�
+                    //ssrc瑙勫畾闀垮害涓�10涓瓧鑺傦紝涓嶅彇浣欎笅闀垮害浠ラ伩鍏嶅悗缁繕鏈夆�渇=鈥濆瓧娈�
                     ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
                     String substring = contentString.substring(0, contentString.indexOf("y="));
                     sdp = SdpFactory.getInstance().createSessionDescription(substring);
@@ -288,9 +293,6 @@
                                 mediaTransmissionTCP = true;
                                 if ("active".equalsIgnoreCase(setup)) {
                                     tcpActive = true;
-                                    // 涓嶆敮鎸乼cp涓诲姩
-                                    responseAck(evt, Response.NOT_IMPLEMENTED, "tcp active not support"); // 鐩綍涓嶆敮鎸佺偣鎾�
-                                    return;
                                 } else if ("passive".equalsIgnoreCase(setup)) {
                                     tcpActive = false;
                                 }
@@ -302,7 +304,7 @@
                 if (port == -1) {
                     logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415");
                     // 鍥炲涓嶆敮鎸佺殑鏍煎紡
-                    responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
+                    responseAck(serverTransaction, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
                     return;
                 }
                 String username = sdp.getOrigin().getUsername();
@@ -315,24 +317,25 @@
                     device = storager.queryVideoDeviceByPlatformIdAndChannelId(requesterId, channelId);
                     if (device == null) {
                         logger.warn("鐐规挱骞冲彴{}鐨勯�氶亾{}鏃舵湭鎵惧埌璁惧淇℃伅", requesterId, channel);
-                        responseAck(evt, Response.SERVER_INTERNAL_ERROR);
+                        responseAck(serverTransaction, Response.SERVER_INTERNAL_ERROR);
                         return;
                     }
                     mediaServerItem = playService.getNewMediaServerItem(device);
                     if (mediaServerItem == null) {
                         logger.warn("鏈壘鍒板彲鐢ㄧ殑zlm");
-                        responseAck(evt, Response.BUSY_HERE);
+                        responseAck(serverTransaction, Response.BUSY_HERE);
                         return;
                     }
                     SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
                             device.getDeviceId(), channelId,
                             mediaTransmissionTCP);
+
                     if (tcpActive != null) {
                         sendRtpItem.setTcpActive(tcpActive);
                     }
                     if (sendRtpItem == null) {
                         logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
-                        responseAck(evt, Response.BUSY_HERE);
+                        responseAck(serverTransaction, Response.BUSY_HERE);
                         return;
                     }
                     sendRtpItem.setCallId(callIdHeader.getCallId());
@@ -374,7 +377,7 @@
                                 // 鍥炲bye
                                 cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());
                             }, 60 * 1000);
-                            responseSdpAck(evt, content.toString(), platform);
+                            responseSdpAck(serverTransaction, content.toString(), platform);
 
                         } catch (SipException e) {
                             e.printStackTrace();
@@ -389,8 +392,8 @@
                         Response response = null;
                         try {
                             response = getMessageFactory().createResponse(event.statusCode, evt.getRequest());
-                            ServerTransaction serverTransaction = getServerTransaction(evt);
                             serverTransaction.sendResponse(response);
+                            System.out.println("鏈煡閿欒銆傜洿鎺ヨ浆鍙戣澶囩偣鎾殑閿欒");
                             if (serverTransaction.getDialog() != null) {
                                 serverTransaction.getDialog().delete();
                             }
@@ -414,7 +417,7 @@
                                         }
                                         redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
                                         try {
-                                            responseAck(evt, Response.REQUEST_TIMEOUT);
+                                            responseAck(serverTransaction, Response.REQUEST_TIMEOUT);
                                         } catch (SipException e) {
                                             e.printStackTrace();
                                         } catch (InvalidArgumentException e) {
@@ -452,6 +455,7 @@
                             SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false);
                             logger.info(JSONObject.toJSONString(ssrcInfo));
                             sendRtpItem.setStreamId(ssrcInfo.getStream());
+
                             // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
                             redisCatchStorage.updateSendRTPSever(sendRtpItem);
                             playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg) -> {
@@ -472,26 +476,26 @@
                     if("push".equals(gbStream.getStreamType())) {
                         if (streamPushItem != null && streamPushItem.isPushIng()) {
                             // 鎺ㄦ祦鐘舵��
-                            pushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+                            pushStream(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
                                     mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
                         } else {
                             // 鏈帹娴� 鎷夎捣
-                            notifyStreamOnline(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+                            notifyStreamOnline(evt, serverTransaction,gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
                                     mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
                         }
                     }else if ("proxy".equals(gbStream.getStreamType())){
                         if(null != proxyByAppAndStream &&proxyByAppAndStream.isStatus()){
-                            pushProxyStream(evt, gbStream,  platform, callIdHeader, mediaServerItem, port, tcpActive,
+                            pushProxyStream(evt, serverTransaction, gbStream,  platform, callIdHeader, mediaServerItem, port, tcpActive,
                                     mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
                         }else{
                             //寮�鍚唬鐞嗘媺娴�
                             boolean start1 = streamProxyService.start(gbStream.getApp(), gbStream.getStream());
                             if(start1) {
-                                pushProxyStream(evt, gbStream,  platform, callIdHeader, mediaServerItem, port, tcpActive,
+                                pushProxyStream(evt, serverTransaction, gbStream,  platform, callIdHeader, mediaServerItem, port, tcpActive,
                                         mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
                             }else{
                                 //澶辫触鍚庨�氱煡
-                                notifyStreamOnline(evt, gbStream, null, platform, callIdHeader, mediaServerItem, port, tcpActive,
+                                notifyStreamOnline(evt, serverTransaction,gbStream, null, platform, callIdHeader, mediaServerItem, port, tcpActive,
                                         mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
                             }
                         }
@@ -514,7 +518,7 @@
     /**
      * 瀹夋帓鎺ㄦ祦
      */
-    private void pushProxyStream(RequestEvent evt, GbStream gbStream, ParentPlatform platform,
+    private void pushProxyStream(RequestEvent evt, ServerTransaction serverTransaction, GbStream gbStream, ParentPlatform platform,
                             CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
                             int port, Boolean tcpActive, boolean mediaTransmissionTCP,
                             String channelId, String addressStr, String ssrc, String requesterId) throws InvalidArgumentException, ParseException, SipException {
@@ -527,7 +531,7 @@
 
                 if (sendRtpItem == null) {
                     logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
-                    responseAck(evt, Response.BUSY_HERE);
+                    responseAck(serverTransaction, Response.BUSY_HERE);
                     return;
                 }
                 if (tcpActive != null) {
@@ -537,17 +541,19 @@
                 // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
                 sendRtpItem.setStatus(1);
                 sendRtpItem.setCallId(callIdHeader.getCallId());
-                byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());
-                sendRtpItem.setDialog(dialogByteArray);
-                byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());
-                sendRtpItem.setTransaction(transactionByteArray);
+                SIPRequest request = (SIPRequest) evt.getRequest();
+                sendRtpItem.setFromTag(request.getFromTag());
+
+                SIPResponse response = sendStreamAck(mediaServerItem, serverTransaction, sendRtpItem, platform, evt);
+                if (response != null) {
+                    sendRtpItem.setToTag(response.getToTag());
+                }
                 redisCatchStorage.updateSendRTPSever(sendRtpItem);
-                sendStreamAck(mediaServerItem, sendRtpItem, platform, evt);
 
         }
 
     }
-    private void pushStream(RequestEvent evt, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
+    private void pushStream(RequestEvent evt, ServerTransaction serverTransaction, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
                             CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
                             int port, Boolean tcpActive, boolean mediaTransmissionTCP,
                             String channelId, String addressStr, String ssrc, String requesterId) throws InvalidArgumentException, ParseException, SipException {
@@ -562,7 +568,7 @@
 
                 if (sendRtpItem == null) {
                     logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
-                    responseAck(evt, Response.BUSY_HERE);
+                    responseAck(serverTransaction, Response.BUSY_HERE);
                     return;
                 }
                 if (tcpActive != null) {
@@ -572,39 +578,43 @@
                 // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
                 sendRtpItem.setStatus(1);
                 sendRtpItem.setCallId(callIdHeader.getCallId());
-                byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());
-                sendRtpItem.setDialog(dialogByteArray);
-                byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());
-                sendRtpItem.setTransaction(transactionByteArray);
+
+                SIPRequest request = (SIPRequest) evt.getRequest();
+                sendRtpItem.setFromTag(request.getFromTag());
+                SIPResponse response = sendStreamAck(mediaServerItem, serverTransaction, sendRtpItem, platform, evt);
+                if (response != null) {
+                    sendRtpItem.setToTag(response.getToTag());
+                }
+
                 redisCatchStorage.updateSendRTPSever(sendRtpItem);
-                sendStreamAck(mediaServerItem, sendRtpItem, platform, evt);
+
             } else {
                 // 涓嶅湪绾� 鎷夎捣
-                notifyStreamOnline(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+                notifyStreamOnline(evt, serverTransaction,gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
                         mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
             }
 
         } else {
             // 鍏朵粬骞冲彴鍐呭
-            otherWvpPushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+            otherWvpPushStream(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
                     mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
         }
     }
     /**
      * 閫氱煡娴佷笂绾�
      */
-    private void notifyStreamOnline(RequestEvent evt, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
+    private void notifyStreamOnline(RequestEvent evt, ServerTransaction serverTransaction, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
                                     CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
                                     int port, Boolean tcpActive, boolean mediaTransmissionTCP,
                                     String channelId, String addressStr, String ssrc, String requesterId) throws InvalidArgumentException, ParseException, SipException {
         if ("proxy".equals(gbStream.getStreamType())) {
             // TODO 鎺у埗鍚敤浠ヤ娇璁惧涓婄嚎
             logger.info("[ app={}, stream={} ]閫氶亾鏈帹娴侊紝鍚敤娴佸悗寮�濮嬫帹娴�", gbStream.getApp(), gbStream.getStream());
-            responseAck(evt, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline");
+            responseAck(serverTransaction, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline");
         } else if ("push".equals(gbStream.getStreamType())) {
             if (!platform.isStartOfflinePush()) {
                 // 骞冲彴璁剧疆涓叧闂簡鎷夎捣绂荤嚎鐨勬帹娴佸垯鐩存帴鍥炲
-                responseAck(evt, Response.TEMPORARILY_UNAVAILABLE, "channel stream not pushing");
+                responseAck(serverTransaction, Response.TEMPORARILY_UNAVAILABLE, "channel stream not pushing");
                 return;
             }
             // 鍙戦�乺edis娑堟伅浠ヤ娇璁惧涓婄嚎
@@ -619,7 +629,7 @@
                 logger.info("[ app={}, stream={} ] 绛夊緟璁惧寮�濮嬫帹娴佽秴鏃�", gbStream.getApp(), gbStream.getStream());
                 try {
                     mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream());
-                    responseAck(evt, Response.REQUEST_TIMEOUT); // 瓒呮椂
+                    responseAck(serverTransaction, Response.REQUEST_TIMEOUT); // 瓒呮椂
                 } catch (SipException e) {
                     e.printStackTrace();
                 } catch (InvalidArgumentException e) {
@@ -642,7 +652,7 @@
                     if (sendRtpItem == null) {
                         logger.warn("涓婄骇鐐规椂鍒涘缓sendRTPItem澶辫触锛屽彲鑳芥槸鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
                         try {
-                            responseAck(evt, Response.BUSY_HERE);
+                            responseAck(serverTransaction, Response.BUSY_HERE);
                         } catch (SipException e) {
                             e.printStackTrace();
                         } catch (InvalidArgumentException e) {
@@ -659,15 +669,17 @@
                     // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
                     sendRtpItem.setStatus(1);
                     sendRtpItem.setCallId(callIdHeader.getCallId());
-                    byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());
-                    sendRtpItem.setDialog(dialogByteArray);
-                    byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());
-                    sendRtpItem.setTransaction(transactionByteArray);
+
+                    SIPRequest request = (SIPRequest) evt.getRequest();
+                    sendRtpItem.setFromTag(request.getFromTag());
+                    SIPResponse response = sendStreamAck(mediaServerItem, serverTransaction, sendRtpItem, platform, evt);
+                    if (response != null) {
+                        sendRtpItem.setToTag(response.getToTag());
+                    }
                     redisCatchStorage.updateSendRTPSever(sendRtpItem);
-                    sendStreamAck(mediaServerItem, sendRtpItem, platform, evt);
                 } else {
                     // 鍏朵粬骞冲彴鍐呭
-                    otherWvpPushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+                    otherWvpPushStream(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
                             mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
                 }
             });
@@ -678,7 +690,7 @@
                     dynamicTask.stop(callIdHeader.getCallId());
                     mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream());
                     try {
-                        responseAck(evt, Response.TEMPORARILY_UNAVAILABLE, response.getMsg());
+                        responseAck(serverTransaction, Response.TEMPORARILY_UNAVAILABLE, response.getMsg());
                     } catch (SipException e) {
                         throw new RuntimeException(e);
                     } catch (InvalidArgumentException e) {
@@ -694,7 +706,7 @@
     /**
      * 鏉ヨ嚜鍏朵粬wvp鐨勬帹娴�
      */
-    private void otherWvpPushStream(RequestEvent evt, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
+    private void otherWvpPushStream(RequestEvent evt, ServerTransaction serverTransaction, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
                                     CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
                                     int port, Boolean tcpActive, boolean mediaTransmissionTCP,
                                     String channelId, String addressStr, String ssrc, String requesterId) {
@@ -707,7 +719,7 @@
                     if (sendRtpItem == null || responseSendItemMsg.getMediaServerItem() == null) {
                         logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
                         try {
-                            responseAck(evt, Response.BUSY_HERE);
+                            responseAck(serverTransaction, Response.BUSY_HERE);
                         } catch (SipException e) {
                             e.printStackTrace();
                         } catch (InvalidArgumentException e) {
@@ -725,12 +737,14 @@
                     // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
                     sendRtpItem.setStatus(1);
                     sendRtpItem.setCallId(callIdHeader.getCallId());
-                    byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());
-                    sendRtpItem.setDialog(dialogByteArray);
-                    byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());
-                    sendRtpItem.setTransaction(transactionByteArray);
+
+                    SIPRequest request = (SIPRequest) evt.getRequest();
+                    sendRtpItem.setFromTag(request.getFromTag());
+                    SIPResponse response = sendStreamAck(responseSendItemMsg.getMediaServerItem(), serverTransaction,sendRtpItem, platform, evt);
+                    if (response != null) {
+                        sendRtpItem.setToTag(response.getToTag());
+                    }
                     redisCatchStorage.updateSendRTPSever(sendRtpItem);
-                    sendStreamAck(responseSendItemMsg.getMediaServerItem(), sendRtpItem, platform, evt);
                 }, (wvpResult) -> {
                     try {
                         // 閿欒
@@ -740,12 +754,12 @@
                             StreamPushItem currentStreamPushItem = streamPushService.getPush(streamPushItem.getApp(), streamPushItem.getStream());
                             if (currentStreamPushItem.isPushIng()) {
                                 // 鍦ㄧ嚎鐘舵��
-                                pushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+                                pushStream(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
                                         mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
 
                             } else {
                                 // 涓嶅湪绾� 鎷夎捣
-                                notifyStreamOnline(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+                                notifyStreamOnline(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
                                         mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
                             }
                         }
@@ -759,7 +773,7 @@
 
 
                     try {
-                        responseAck(evt, Response.BUSY_HERE);
+                        responseAck(serverTransaction, Response.BUSY_HERE);
                     } catch (SipException e) {
                         e.printStackTrace();
                     } catch (InvalidArgumentException e) {
@@ -771,7 +785,7 @@
                 });
     }
 
-    public void sendStreamAck(MediaServerItem mediaServerItem, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt) {
+    public SIPResponse sendStreamAck(MediaServerItem mediaServerItem, ServerTransaction serverTransaction, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt) {
 
         StringBuffer content = new StringBuffer(200);
         content.append("v=0\r\n");
@@ -794,7 +808,7 @@
         content.append("f=\r\n");
 
         try {
-            responseSdpAck(evt, content.toString(), platform);
+            return responseSdpAck(serverTransaction, content.toString(), platform);
         } catch (SipException e) {
             e.printStackTrace();
         } catch (InvalidArgumentException e) {
@@ -802,24 +816,25 @@
         } catch (ParseException e) {
             e.printStackTrace();
         }
+        return null;
     }
 
-    public void inviteFromDeviceHandle(RequestEvent evt, String requesterId, String channelId) throws InvalidArgumentException, ParseException, SipException, SdpException {
+    public void inviteFromDeviceHandle(ServerTransaction serverTransaction, String requesterId, String channelId) throws InvalidArgumentException, ParseException, SipException, SdpException {
 
         // 闈炰笂绾у钩鍙拌姹傦紝鏌ヨ鏄惁璁惧璇锋眰锛堥�氬父涓烘帴鏀惰闊冲箍鎾殑璁惧锛�
         Device device = redisCatchStorage.getDevice(requesterId);
         AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(requesterId, channelId);
         if (audioBroadcastCatch == null) {
             logger.warn("鏉ヨ嚜璁惧鐨処nvite璇锋眰闈炶闊冲箍鎾紝宸插拷鐣ワ紝requesterId锛� {}/{}", requesterId, channelId);
-            responseAck(evt, Response.FORBIDDEN);
+            responseAck(serverTransaction, Response.FORBIDDEN);
             return;
         }
-        Request request = evt.getRequest();
+        Request request = serverTransaction.getRequest();
         if (device != null) {
             logger.info("鏀跺埌璁惧" + requesterId + "鐨勮闊冲箍鎾璉nvite璇锋眰");
-            responseAck(evt, Response.TRYING);
+            responseAck(serverTransaction, Response.TRYING);
 
-            String contentString = new String(request.getRawContent());
+            String contentString = new String(serverTransaction.getRequest().getRawContent());
             // jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎绉婚櫎浠ヨВ鏋愩��
             String substring = contentString;
             String ssrc = "0000000404";
@@ -867,7 +882,7 @@
             if (port == -1) {
                 logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415");
                 // 鍥炲涓嶆敮鎸佺殑鏍煎紡
-                responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
+                responseAck(serverTransaction, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
                 return;
             }
             String addressStr = sdp.getOrigin().getAddress();
@@ -876,7 +891,7 @@
             MediaServerItem mediaServerItem = playService.getNewMediaServerItem(device);
             if (mediaServerItem == null) {
                 logger.warn("鏈壘鍒板彲鐢ㄧ殑zlm");
-                responseAck(evt, Response.BUSY_HERE);
+                responseAck(serverTransaction, Response.BUSY_HERE);
                 return;
             }
             SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
@@ -884,7 +899,7 @@
                     mediaTransmissionTCP);
             if (sendRtpItem == null) {
                 logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
-                responseAck(evt, Response.BUSY_HERE);
+                responseAck(serverTransaction, Response.BUSY_HERE);
                 return;
             }
             sendRtpItem.setTcp(mediaTransmissionTCP);
@@ -998,19 +1013,13 @@
                                 parentPlatform.setServerPort(device.getPort());
                                 parentPlatform.setServerGBId(device.getDeviceId());
 
-                                responseSdpAck(evt, content.toString(), parentPlatform);
+                                responseSdpAck(serverTransaction, content.toString(), parentPlatform);
                                 Dialog dialog = evt.getDialog();
                                 audioBroadcastCatch.setDialog((SIPDialog) dialog);
                                 audioBroadcastCatch.setRequest((SIPRequest) request);
                                 audioBroadcastManager.update(audioBroadcastCatch);
-                            } catch (SipException e) {
-                                throw new RuntimeException(e);
-                            } catch (InvalidArgumentException e) {
-                                throw new RuntimeException(e);
-                            } catch (ParseException e) {
-                                throw new RuntimeException(e);
-                            } catch (SdpParseException e) {
-                                throw new RuntimeException(e);
+                            } catch (SipException | InvalidArgumentException | ParseException | SdpParseException e) {
+                                logger.error("[鍛戒护鍙戦�佸け璐 璇煶瀵硅: {}", e.getMessage());
                             }
                         });
 //            }
@@ -1030,7 +1039,7 @@
             resultHolder.invokeAllResult(requestMessage);
         } else {
             logger.warn("鏉ヨ嚜鏃犳晥璁惧/骞冲彴鐨勮姹�");
-            responseAck(evt, Response.BAD_REQUEST);
+            responseAck(serverTransaction, Response.BAD_REQUEST);
         }
     }
 }
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 9438471..84bf0b8 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
@@ -34,6 +34,7 @@
 
 import javax.sip.InvalidArgumentException;
 import javax.sip.RequestEvent;
+import javax.sip.ServerTransaction;
 import javax.sip.SipException;
 import javax.sip.header.FromHeader;
 import javax.sip.message.Response;
@@ -78,7 +79,7 @@
 
 	private boolean taskQueueHandlerRun = false;
 
-	private final ConcurrentLinkedQueue<HandlerCatchData> taskQueue = new ConcurrentLinkedQueue<>();
+	private ConcurrentLinkedQueue<HandlerCatchData> taskQueue = new ConcurrentLinkedQueue<>();
 
 	@Qualifier("taskExecutor")
 	@Autowired
@@ -94,7 +95,8 @@
 	public void process(RequestEvent evt) {
 		try {
 			taskQueue.offer(new HandlerCatchData(evt, null, null));
-			responseAck(evt, Response.OK);
+			ServerTransaction serverTransaction = getServerTransaction(evt);
+			responseAck(serverTransaction, Response.OK);
 			if (!taskQueueHandlerRun) {
 				taskQueueHandlerRun = true;
 				taskExecutor.execute(()-> {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java
index 8c04368..2ec4023 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java
@@ -17,6 +17,12 @@
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
 import gov.nist.javax.sip.SipProviderImpl;
+import gov.nist.javax.sip.message.SIPRequest;
+import gov.nist.javax.sip.message.SIPResponse;
+import gov.nist.javax.sip.stack.SIPClientTransaction;
+import gov.nist.javax.sip.stack.SIPDialog;
+import gov.nist.javax.sip.stack.SIPServerTransaction;
+import gov.nist.javax.sip.stack.SIPServerTransactionImpl;
 import org.dom4j.DocumentException;
 import org.dom4j.Element;
 import org.slf4j.Logger;
@@ -49,22 +55,6 @@
 	@Autowired
 	private IVideoManagerStorage storager;
 
-	@Lazy
-	@Autowired
-	@Qualifier(value="tcpSipProvider")
-	private SipProviderImpl tcpSipProvider;
-
-	@Lazy
-	@Autowired
-	@Qualifier(value="udpSipProvider")
-	private SipProviderImpl udpSipProvider;
-
-	@Autowired
-	private DynamicTask dynamicTask;
-
-	@Autowired
-	private UserSetting userSetting;
-
 	@Autowired
 	private SubscribeHolder subscribeHolder;
 
@@ -81,6 +71,7 @@
 	 */
 	@Override
 	public void process(RequestEvent evt) {
+		ServerTransaction serverTransaction = getServerTransaction(evt);
 		Request request = evt.getRequest();
 		try {
 			Element rootElement = getRootElement(evt);
@@ -90,12 +81,12 @@
 			}
 			String cmd = XmlUtil.getText(rootElement, "CmdType");
 			if (CmdType.MOBILE_POSITION.equals(cmd)) {
-				processNotifyMobilePosition(evt, rootElement);
+				processNotifyMobilePosition(serverTransaction, rootElement);
 //			} else if (CmdType.ALARM.equals(cmd)) {
 //				logger.info("鎺ユ敹鍒癆larm璁㈤槄");
-//				processNotifyAlarm(evt, rootElement);
+//				processNotifyAlarm(serverTransaction, rootElement);
 			} else if (CmdType.CATALOG.equals(cmd)) {
-				processNotifyCatalogList(evt, rootElement);
+				processNotifyCatalogList(serverTransaction, rootElement);
 			} else {
 				logger.info("鎺ユ敹鍒版秷鎭細" + cmd);
 
@@ -108,7 +99,6 @@
 				ServerTransaction transaction = getServerTransaction(evt);
 				if (transaction != null) {
 					transaction.sendResponse(response);
-					transaction.getDialog().delete();
 					transaction.terminate();
 				} else {
 					logger.info("processRequest serverTransactionId is null.");
@@ -123,24 +113,20 @@
 	/**
 	 * 澶勭悊绉诲姩浣嶇疆璁㈤槄娑堟伅
 	 */
-	private void processNotifyMobilePosition(RequestEvent evt, Element rootElement) throws SipException {
-		String platformId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
+	private void processNotifyMobilePosition(ServerTransaction serverTransaction, Element rootElement) throws SipException {
+		if (serverTransaction == null) {
+			return;
+		}
+		String platformId = SipUtils.getUserIdFromFromHeader(serverTransaction.getRequest());
 		String deviceId = XmlUtil.getText(rootElement, "DeviceID");
 		ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);
-		SubscribeInfo subscribeInfo = new SubscribeInfo(evt, platformId);
+		SubscribeInfo subscribeInfo = new SubscribeInfo(serverTransaction, platformId);
 		if (platform == null) {
 			return;
 		}
-		if (evt.getServerTransaction() == null) {
-			ServerTransaction serverTransaction = "TCP".equalsIgnoreCase(platform.getTransport()) ? tcpSipProvider.getNewServerTransaction(evt.getRequest())
-					: udpSipProvider.getNewServerTransaction(evt.getRequest());
-			subscribeInfo.setTransaction(serverTransaction);
-			Dialog dialog = serverTransaction.getDialog();
-			dialog.terminateOnBye(false);
-			subscribeInfo.setDialog(dialog);
-		}
+
 		String sn = XmlUtil.getText(rootElement, "SN");
-		logger.info("[鍥炲 绉诲姩浣嶇疆璁㈤槄]: {}", platformId);
+		logger.info("[鍥炲涓婄骇鐨勭Щ鍔ㄤ綅缃闃呰姹俔: {}", platformId);
 		StringBuilder resultXml = new StringBuilder(200);
 		resultXml.append("<?xml version=\"1.0\" ?>\r\n")
 				.append("<Response>\r\n")
@@ -158,17 +144,19 @@
 			}else {
 				subscribeInfo.setGpsInterval(Integer.parseInt(interval));
 			}
-
 			subscribeInfo.setSn(sn);
-			subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo);
-
-		}else if (subscribeInfo.getExpires() == 0) {
-			subscribeHolder.removeMobilePositionSubscribe(platformId);
 		}
 
 		try {
 			ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId);
-			responseXmlAck(evt, resultXml.toString(), parentPlatform);
+			SIPResponse response = responseXmlAck(serverTransaction, resultXml.toString(), parentPlatform, subscribeInfo.getExpires());
+			if (subscribeInfo.getExpires() == 0) {
+				subscribeHolder.removeMobilePositionSubscribe(platformId);
+			}else {
+				subscribeInfo.setResponse(response);
+				subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo);
+			}
+
 		} catch (SipException | InvalidArgumentException | ParseException e) {
 			e.printStackTrace();
 		}
@@ -178,25 +166,20 @@
 
 	}
 
-	private void processNotifyCatalogList(RequestEvent evt, Element rootElement) throws SipException {
-
-		String platformId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
+	private void processNotifyCatalogList(ServerTransaction serverTransaction, Element rootElement) throws SipException {
+		if (serverTransaction == null) {
+			return;
+		}
+		String platformId = SipUtils.getUserIdFromFromHeader(serverTransaction.getRequest());
 		String deviceId = XmlUtil.getText(rootElement, "DeviceID");
 		ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);
 		if (platform == null){
 			return;
 		}
-		SubscribeInfo subscribeInfo = new SubscribeInfo(evt, platformId);
-		if (evt.getServerTransaction() == null) {
-			ServerTransaction serverTransaction = "TCP".equalsIgnoreCase(platform.getTransport()) ? tcpSipProvider.getNewServerTransaction(evt.getRequest())
-					: udpSipProvider.getNewServerTransaction(evt.getRequest());
-			subscribeInfo.setTransaction(serverTransaction);
-			Dialog dialog = serverTransaction.getDialog();
-			dialog.terminateOnBye(false);
-			subscribeInfo.setDialog(dialog);
-		}
+		SubscribeInfo subscribeInfo = new SubscribeInfo(serverTransaction, platformId);
+
 		String sn = XmlUtil.getText(rootElement, "SN");
-		logger.info("[鍥炲 鐩綍璁㈤槄]: {}/{}", platformId, deviceId);
+		logger.info("[鍥炲涓婄骇鐨勭洰褰曡闃呰姹俔: {}/{}", platformId, deviceId);
 		StringBuilder resultXml = new StringBuilder(200);
 		resultXml.append("<?xml version=\"1.0\" ?>\r\n")
 				.append("<Response>\r\n")
@@ -213,7 +196,13 @@
 		}
 		try {
 			ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId);
-			responseXmlAck(evt, resultXml.toString(), parentPlatform);
+			SIPResponse response = responseXmlAck(serverTransaction, resultXml.toString(), parentPlatform, subscribeInfo.getExpires());
+			if (subscribeInfo.getExpires() == 0) {
+				subscribeHolder.removeCatalogSubscribe(platformId);
+			}else {
+				subscribeInfo.setResponse(response);
+				subscribeHolder.putCatalogSubscribe(platformId, subscribeInfo);
+			}
 		} catch (SipException | InvalidArgumentException | ParseException e) {
 			e.printStackTrace();
 		}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/info/InfoRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/info/InfoRequestProcessor.java
index 98a2ec2..0b6ced0 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/info/InfoRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/info/InfoRequestProcessor.java
@@ -19,6 +19,7 @@
 import org.springframework.stereotype.Component;
 import javax.sip.InvalidArgumentException;
 import javax.sip.RequestEvent;
+import javax.sip.ServerTransaction;
 import javax.sip.SipException;
 import javax.sip.header.*;
 import javax.sip.message.Response;
@@ -65,9 +66,12 @@
         CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
         // 鍏堜粠浼氳瘽鍐呮煡鎵�
         SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransaction(null, null, callIdHeader.getCallId(), null);
-        if (ssrcTransaction != null) { // 鍏煎娴峰悍 濯掍綋閫氱煡 娑堟伅from瀛楁涓嶆槸璁惧ID鐨勯棶棰�
+
+        // 鍏煎娴峰悍 濯掍綋閫氱煡 娑堟伅from瀛楁涓嶆槸璁惧ID鐨勯棶棰�
+        if (ssrcTransaction != null) {
             deviceId = ssrcTransaction.getDeviceId();
         }
+        ServerTransaction serverTransaction = getServerTransaction(evt);
         // 鏌ヨ璁惧鏄惁瀛樺湪
         Device device = redisCatchStorage.getDevice(deviceId);
         // 鏌ヨ涓婄骇骞冲彴鏄惁瀛樺湪
@@ -86,7 +90,7 @@
             }
             if (device == null && parentPlatform == null) {
                 // 涓嶅瓨鍦ㄥ垯鍥炲404
-                responseAck(evt, Response.NOT_FOUND, "device "+ deviceId +" not found");
+                responseAck(serverTransaction, Response.NOT_FOUND, "device "+ deviceId +" not found");
                 logger.warn("[璁惧鏈壘鍒� ]锛� {}", deviceId);
                 if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){
                     SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new DeviceNotFoundEvent(evt.getDialog()));
@@ -101,14 +105,14 @@
                     String streamId = sendRtpItem.getStreamId();
                     StreamInfo streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null);
                     if (null == streamInfo) {
-                        responseAck(evt, Response.NOT_FOUND, "stream " + streamId + " not found");
+                        responseAck(serverTransaction, Response.NOT_FOUND, "stream " + streamId + " not found");
                         return;
                     }
                     Device device1 = storager.queryVideoDevice(streamInfo.getDeviceID());
                     cmder.playbackControlCmd(device1,streamInfo,new String(evt.getRequest().getRawContent()),eventResult -> {
                         // 澶辫触鐨勫洖澶�
                         try {
-                            responseAck(evt, eventResult.statusCode, eventResult.msg);
+                            responseAck(serverTransaction, eventResult.statusCode, eventResult.msg);
                         } catch (SipException e) {
                             e.printStackTrace();
                         } catch (InvalidArgumentException e) {
@@ -119,7 +123,7 @@
                     }, eventResult -> {
                         // 鎴愬姛鐨勫洖澶�
                         try {
-                            responseAck(evt, eventResult.statusCode);
+                            responseAck(serverTransaction, eventResult.statusCode);
                         } catch (SipException e) {
                             e.printStackTrace();
                         } catch (InvalidArgumentException e) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java
index 9e0f8dc..bd4ca65 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java
@@ -23,6 +23,7 @@
 
 import javax.sip.InvalidArgumentException;
 import javax.sip.RequestEvent;
+import javax.sip.ServerTransaction;
 import javax.sip.SipException;
 import javax.sip.address.SipURI;
 import javax.sip.header.CSeqHeader;
@@ -79,6 +80,9 @@
         if (ssrcTransaction != null) {
             deviceId = ssrcTransaction.getDeviceId();
         }
+
+        ServerTransaction serverTransaction = getServerTransaction(evt);
+
         // 鏌ヨ璁惧鏄惁瀛樺湪
         Device device = redisCatchStorage.getDevice(deviceId);
         // 鏌ヨ涓婄骇骞冲彴鏄惁瀛樺湪
@@ -98,7 +102,7 @@
             }
             if (device == null && parentPlatform == null) {
                 // 涓嶅瓨鍦ㄥ垯鍥炲404
-                responseAck(evt, Response.NOT_FOUND, "device "+ deviceId +" not found");
+                responseAck(serverTransaction, Response.NOT_FOUND, "device "+ deviceId +" not found");
                 logger.warn("[璁惧鏈壘鍒� ]锛� {}", deviceId);
                 if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){
                     SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new DeviceNotFoundEvent(evt.getDialog()));
@@ -110,13 +114,13 @@
                     rootElement = getRootElement(evt);
                     if (rootElement == null) {
                         logger.error("澶勭悊MESSAGE璇锋眰  鏈幏鍙栧埌娑堟伅浣搟}", evt.getRequest());
-                        responseAck(evt, Response.BAD_REQUEST, "content is null");
+                        responseAck(serverTransaction, Response.BAD_REQUEST, "content is null");
                         return;
                     }
                 } catch (DocumentException e) {
                     logger.warn("瑙f瀽XML娑堟伅鍐呭寮傚父", e);
                     // 涓嶅瓨鍦ㄥ垯鍥炲404
-                    responseAck(evt, Response.BAD_REQUEST, e.getMessage());
+                    responseAck(serverTransaction, Response.BAD_REQUEST, e.getMessage());
                 }
                 String name = rootElement.getName();
                 IMessageHandler messageHandler = messageHandlerMap.get(name);
@@ -129,7 +133,7 @@
                 }else {
                     // 涓嶆敮鎸佺殑message
                     // 涓嶅瓨鍦ㄥ垯鍥炲415
-                    responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE, "Unsupported message type, must Control/Notify/Query/Response");
+                    responseAck(serverTransaction, Response.UNSUPPORTED_MEDIA_TYPE, "Unsupported message type, must Control/Notify/Query/Response");
                 }
             }
         } catch (SipException e) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/control/cmd/DeviceControlQueryMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/control/cmd/DeviceControlQueryMessageHandler.java
index 9589bdf..094e656 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/control/cmd/DeviceControlQueryMessageHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/control/cmd/DeviceControlQueryMessageHandler.java
@@ -61,6 +61,8 @@
     @Override
     public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
 
+        ServerTransaction serverTransaction = getServerTransaction(evt);
+
         // 姝ゅ鏄笂绾у彂鍑虹殑DeviceControl鎸囦护
         String targetGBId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
         String channelId = getText(rootElement, "DeviceID");
@@ -107,7 +109,7 @@
             Device deviceForPlatform = storager.queryVideoDeviceByPlatformIdAndChannelId(parentPlatform.getServerGBId(), channelId);
             if (deviceForPlatform == null) {
                 try {
-                    responseAck(evt, Response.NOT_FOUND);
+                    responseAck(serverTransaction, Response.NOT_FOUND);
                     return;
                 } catch (SipException e) {
                     e.printStackTrace();
@@ -120,7 +122,7 @@
             cmder.fronEndCmd(deviceForPlatform, channelId, cmdString, eventResult -> {
                 // 澶辫触鐨勫洖澶�
                 try {
-                    responseAck(evt, eventResult.statusCode, eventResult.msg);
+                    responseAck(serverTransaction, eventResult.statusCode, eventResult.msg);
                 } catch (SipException e) {
                     e.printStackTrace();
                 } catch (InvalidArgumentException e) {
@@ -131,7 +133,7 @@
             }, eventResult -> {
                 // 鎴愬姛鐨勫洖澶�
                 try {
-                    responseAck(evt, eventResult.statusCode);
+                    responseAck(serverTransaction, eventResult.statusCode);
                 } catch (SipException e) {
                     e.printStackTrace();
                 } catch (InvalidArgumentException e) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java
index 98fd7a7..ec75015 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java
@@ -21,6 +21,8 @@
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Component;
 import org.springframework.util.ObjectUtils;
 import org.springframework.util.StringUtils;
@@ -31,6 +33,7 @@
 import javax.sip.message.Response;
 
 import java.text.ParseException;
+import java.util.concurrent.ConcurrentLinkedQueue;
 
 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.*;
 
@@ -67,6 +70,15 @@
     @Autowired
     private IDeviceChannelService deviceChannelService;
 
+    private boolean taskQueueHandlerRun = false;
+
+    private ConcurrentLinkedQueue<SipMsgInfo> taskQueue = new ConcurrentLinkedQueue<>();
+
+    @Qualifier("taskExecutor")
+    @Autowired
+    private ThreadPoolTaskExecutor taskExecutor;
+
+
     @Override
     public void afterPropertiesSet() throws Exception {
         notifyMessageHandler.addHandler(cmdType, this);
@@ -75,114 +87,128 @@
     @Override
     public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
         logger.info("[鏀跺埌鎶ヨ閫氱煡]璁惧锛歿}", device.getDeviceId());
-        // 鍥炲200 OK
-        try {
-            responseAck(evt, Response.OK);
-        } catch (SipException | InvalidArgumentException | ParseException e) {
-            logger.error("[鏀跺埌鎶ヨ閫氱煡], 鍥炲200OK澶辫触", e);
-        }
 
-        Element deviceIdElement = rootElement.element("DeviceID");
-        String channelId = deviceIdElement.getText().toString();
+        taskQueue.offer(new SipMsgInfo(evt, device, rootElement));
+        if (!taskQueueHandlerRun) {
+            taskQueueHandlerRun = true;
+            taskExecutor.execute(() -> {
+                logger.info("[澶勭悊鎶ヨ閫氱煡]寰呭鐞嗘暟閲忥細{}", taskQueue.size() );
+                while (!taskQueue.isEmpty()) {
+                    SipMsgInfo sipMsgInfo = taskQueue.poll();
+                    // 鍥炲200 OK
+                    try {
+                        responseAck(getServerTransaction(sipMsgInfo.getEvt()), Response.OK);
+                    } catch (SipException | InvalidArgumentException | ParseException e) {
+                        logger.error("[澶勭悊鎶ヨ閫氱煡], 鍥炲200OK澶辫触", e);
+                    }
 
-        DeviceAlarm deviceAlarm = new DeviceAlarm();
-        deviceAlarm.setCreateTime(DateUtil.getNow());
-        deviceAlarm.setDeviceId(device.getDeviceId());
-        deviceAlarm.setChannelId(channelId);
-        deviceAlarm.setAlarmPriority(getText(rootElement, "AlarmPriority"));
-        deviceAlarm.setAlarmMethod(getText(rootElement, "AlarmMethod"));
-        String alarmTime = XmlUtil.getText(rootElement, "AlarmTime");
-        if (alarmTime == null) {
-            return;
-        }
-        deviceAlarm.setAlarmTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(alarmTime));
-        String alarmDescription = getText(rootElement, "AlarmDescription");
-        if (alarmDescription == null) {
-            deviceAlarm.setAlarmDescription("");
-        } else {
-            deviceAlarm.setAlarmDescription(alarmDescription);
-        }
-        String longitude = getText(rootElement, "Longitude");
-        if (longitude != null && NumericUtil.isDouble(longitude)) {
-            deviceAlarm.setLongitude(Double.parseDouble(longitude));
-        } else {
-            deviceAlarm.setLongitude(0.00);
-        }
-        String latitude = getText(rootElement, "Latitude");
-        if (latitude != null && NumericUtil.isDouble(latitude)) {
-            deviceAlarm.setLatitude(Double.parseDouble(latitude));
-        } else {
-            deviceAlarm.setLatitude(0.00);
-        }
+                    Element deviceIdElement = sipMsgInfo.getRootElement().element("DeviceID");
+                    String channelId = deviceIdElement.getText().toString();
 
-        if (!ObjectUtils.isEmpty(deviceAlarm.getAlarmMethod())) {
-            if ( deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.GPS.getVal() + "")) {
-                MobilePosition mobilePosition = new MobilePosition();
-                mobilePosition.setCreateTime(DateUtil.getNow());
-                mobilePosition.setDeviceId(deviceAlarm.getDeviceId());
-                mobilePosition.setTime(deviceAlarm.getAlarmTime());
-                mobilePosition.setLongitude(deviceAlarm.getLongitude());
-                mobilePosition.setLatitude(deviceAlarm.getLatitude());
-                mobilePosition.setReportSource("GPS Alarm");
+                    DeviceAlarm deviceAlarm = new DeviceAlarm();
+                    deviceAlarm.setCreateTime(DateUtil.getNow());
+                    deviceAlarm.setDeviceId(sipMsgInfo.getDevice().getDeviceId());
+                    deviceAlarm.setChannelId(channelId);
+                    deviceAlarm.setAlarmPriority(getText(sipMsgInfo.getRootElement(), "AlarmPriority"));
+                    deviceAlarm.setAlarmMethod(getText(sipMsgInfo.getRootElement(), "AlarmMethod"));
+                    String alarmTime = XmlUtil.getText(sipMsgInfo.getRootElement(), "AlarmTime");
+                    if (alarmTime == null) {
+                        continue;
+                    }
+                    deviceAlarm.setAlarmTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(alarmTime));
+                    String alarmDescription = getText(sipMsgInfo.getRootElement(), "AlarmDescription");
+                    if (alarmDescription == null) {
+                        deviceAlarm.setAlarmDescription("");
+                    } else {
+                        deviceAlarm.setAlarmDescription(alarmDescription);
+                    }
+                    String longitude = getText(sipMsgInfo.getRootElement(), "Longitude");
+                    if (longitude != null && NumericUtil.isDouble(longitude)) {
+                        deviceAlarm.setLongitude(Double.parseDouble(longitude));
+                    } else {
+                        deviceAlarm.setLongitude(0.00);
+                    }
+                    String latitude = getText(sipMsgInfo.getRootElement(), "Latitude");
+                    if (latitude != null && NumericUtil.isDouble(latitude)) {
+                        deviceAlarm.setLatitude(Double.parseDouble(latitude));
+                    } else {
+                        deviceAlarm.setLatitude(0.00);
+                    }
 
-                // 鏇存柊device channel 鐨勭粡绾害
-                DeviceChannel deviceChannel = new DeviceChannel();
-                deviceChannel.setDeviceId(device.getDeviceId());
-                deviceChannel.setChannelId(channelId);
-                deviceChannel.setLongitude(mobilePosition.getLongitude());
-                deviceChannel.setLatitude(mobilePosition.getLatitude());
-                deviceChannel.setGpsTime(mobilePosition.getTime());
+                    if (!ObjectUtils.isEmpty(deviceAlarm.getAlarmMethod())) {
+                        if ( deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.GPS.getVal() + "")) {
+                            MobilePosition mobilePosition = new MobilePosition();
+                            mobilePosition.setCreateTime(DateUtil.getNow());
+                            mobilePosition.setDeviceId(deviceAlarm.getDeviceId());
+                            mobilePosition.setTime(deviceAlarm.getAlarmTime());
+                            mobilePosition.setLongitude(deviceAlarm.getLongitude());
+                            mobilePosition.setLatitude(deviceAlarm.getLatitude());
+                            mobilePosition.setReportSource("GPS Alarm");
 
-                deviceChannel = deviceChannelService.updateGps(deviceChannel, device);
+                            // 鏇存柊device channel 鐨勭粡绾害
+                            DeviceChannel deviceChannel = new DeviceChannel();
+                            deviceChannel.setDeviceId(sipMsgInfo.getDevice().getDeviceId());
+                            deviceChannel.setChannelId(channelId);
+                            deviceChannel.setLongitude(mobilePosition.getLongitude());
+                            deviceChannel.setLatitude(mobilePosition.getLatitude());
+                            deviceChannel.setGpsTime(mobilePosition.getTime());
 
-                mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84());
-                mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84());
-                mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02());
-                mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02());
+                            deviceChannel = deviceChannelService.updateGps(deviceChannel, sipMsgInfo.getDevice());
 
-                if (userSetting.getSavePositionHistory()) {
-                    storager.insertMobilePosition(mobilePosition);
+                            mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84());
+                            mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84());
+                            mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02());
+                            mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02());
+
+                            if (userSetting.getSavePositionHistory()) {
+                                storager.insertMobilePosition(mobilePosition);
+                            }
+                            storager.updateChannelPosition(deviceChannel);
+
+                            // 鍙戦�乺edis娑堟伅銆� 閫氱煡浣嶇疆淇℃伅鐨勫彉鍖�
+                            JSONObject jsonObject = new JSONObject();
+                            jsonObject.put("time", mobilePosition.getTime());
+                            jsonObject.put("serial", deviceChannel.getDeviceId());
+                            jsonObject.put("code", deviceChannel.getChannelId());
+                            jsonObject.put("longitude", mobilePosition.getLongitude());
+                            jsonObject.put("latitude", mobilePosition.getLatitude());
+                            jsonObject.put("altitude", mobilePosition.getAltitude());
+                            jsonObject.put("direction", mobilePosition.getDirection());
+                            jsonObject.put("speed", mobilePosition.getSpeed());
+                            redisCatchStorage.sendMobilePositionMsg(jsonObject);
+                        }
+                    }
+                    if (!ObjectUtils.isEmpty(deviceAlarm.getDeviceId())) {
+                        if (deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.Video.getVal() + "")) {
+                            deviceAlarm.setAlarmType(getText(sipMsgInfo.getRootElement().element("Info"), "AlarmType"));
+                        }
+                    }
+                    logger.info("[鏀跺埌鎶ヨ閫氱煡]鍐呭锛歿}", JSONObject.toJSON(deviceAlarm));
+                    if ("7".equals(deviceAlarm.getAlarmMethod()) ) {
+                        // 鍙戦�佺粰骞冲彴鐨勬姤璀︿俊鎭�� 鍙戦�乺edis閫氱煡
+                        AlarmChannelMessage alarmChannelMessage = new AlarmChannelMessage();
+                        alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod()));
+                        alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription());
+                        alarmChannelMessage.setGbId(channelId);
+                        redisCatchStorage.sendAlarmMsg(alarmChannelMessage);
+                        continue;
+                    }
+
+                    logger.debug("瀛樺偍鎶ヨ淇℃伅銆佹姤璀﹀垎绫�");
+                    // 瀛樺偍鎶ヨ淇℃伅銆佹姤璀﹀垎绫�
+                    if (sipConfig.isAlarm()) {
+                        deviceAlarmService.add(deviceAlarm);
+                    }
+
+                    if (redisCatchStorage.deviceIsOnline(sipMsgInfo.getDevice().getDeviceId())) {
+                        publisher.deviceAlarmEventPublish(deviceAlarm);
+                    }
                 }
-                storager.updateChannelPosition(deviceChannel);
-
-                // 鍙戦�乺edis娑堟伅銆� 閫氱煡浣嶇疆淇℃伅鐨勫彉鍖�
-                JSONObject jsonObject = new JSONObject();
-                jsonObject.put("time", mobilePosition.getTime());
-                jsonObject.put("serial", deviceChannel.getDeviceId());
-                jsonObject.put("code", deviceChannel.getChannelId());
-                jsonObject.put("longitude", mobilePosition.getLongitude());
-                jsonObject.put("latitude", mobilePosition.getLatitude());
-                jsonObject.put("altitude", mobilePosition.getAltitude());
-                jsonObject.put("direction", mobilePosition.getDirection());
-                jsonObject.put("speed", mobilePosition.getSpeed());
-                redisCatchStorage.sendMobilePositionMsg(jsonObject);
-            }
-        }
-        if (!ObjectUtils.isEmpty(deviceAlarm.getDeviceId())) {
-            if (deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.Video.getVal() + "")) {
-                deviceAlarm.setAlarmType(getText(rootElement.element("Info"), "AlarmType"));
-            }
+                taskQueueHandlerRun = false;
+            });
         }
 
-        if ("7".equals(deviceAlarm.getAlarmMethod()) ) {
-            // 鍙戦�佺粰骞冲彴鐨勬姤璀︿俊鎭�� 鍙戦�乺edis閫氱煡
-            AlarmChannelMessage alarmChannelMessage = new AlarmChannelMessage();
-            alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod()));
-            alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription());
-            alarmChannelMessage.setGbId(channelId);
-            redisCatchStorage.sendAlarmMsg(alarmChannelMessage);
-            return;
-        }
 
-        logger.debug("瀛樺偍鎶ヨ淇℃伅銆佹姤璀﹀垎绫�");
-        // 瀛樺偍鎶ヨ淇℃伅銆佹姤璀﹀垎绫�
-        if (sipConfig.isAlarm()) {
-            deviceAlarmService.add(deviceAlarm);
-        }
-
-        if (redisCatchStorage.deviceIsOnline(device.getDeviceId())) {
-            publisher.deviceAlarmEventPublish(deviceAlarm);
-        }
     }
 
     @Override
@@ -190,7 +216,7 @@
         logger.info("鏀跺埌鏉ヨ嚜骞冲彴[{}]鐨勬姤璀﹂�氱煡", parentPlatform.getServerGBId());
         // 鍥炲200 OK
         try {
-            responseAck(evt, Response.OK);
+            responseAck(getServerTransaction(evt), Response.OK);
         } catch (SipException e) {
             throw new RuntimeException(e);
         } catch (InvalidArgumentException e) {
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 3029746..63dc7d8 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
@@ -69,7 +69,7 @@
             }
             device.setKeepaliveTime(DateUtil.getNow());
             // 鍥炲200 OK
-            responseAck(evt, Response.OK);
+            responseAck(getServerTransaction(evt), Response.OK);
             if (device.getOnline() == 1) {
                 deviceService.updateDevice(device);
             }else {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java
index 5e724e7..332fc67 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java
@@ -66,7 +66,7 @@
 
         // 鍥炲200 OK
         try {
-            responseAck(evt, Response.OK);
+            responseAck(getServerTransaction(evt), Response.OK);
         } catch (SipException e) {
             e.printStackTrace();
         } catch (InvalidArgumentException e) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java
index 255fc00..652cd83 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java
@@ -17,6 +17,8 @@
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Component;
 import org.springframework.util.ObjectUtils;
 import org.springframework.util.StringUtils;
@@ -26,6 +28,7 @@
 import javax.sip.SipException;
 import javax.sip.message.Response;
 import java.text.ParseException;
+import java.util.concurrent.ConcurrentLinkedQueue;
 
 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
 
@@ -53,6 +56,14 @@
     @Autowired
     private IDeviceChannelService deviceChannelService;
 
+    private boolean taskQueueHandlerRun = false;
+
+    private ConcurrentLinkedQueue<SipMsgInfo> taskQueue = new ConcurrentLinkedQueue<>();
+
+    @Qualifier("taskExecutor")
+    @Autowired
+    private ThreadPoolTaskExecutor taskExecutor;
+
     @Override
     public void afterPropertiesSet() throws Exception {
         notifyMessageHandler.addHandler(cmdType, this);
@@ -61,78 +72,91 @@
     @Override
     public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
 
-        try {
-            rootElement = getRootElement(evt, device.getCharset());
-            if (rootElement == null) {
-                logger.warn("[ 绉诲姩璁惧浣嶇疆鏁版嵁閫氱煡 ] content cannot be null, {}", evt.getRequest());
-                responseAck(evt, Response.BAD_REQUEST);
-                return;
-            }
-            MobilePosition mobilePosition = new MobilePosition();
-            mobilePosition.setCreateTime(DateUtil.getNow());
-            if (!ObjectUtils.isEmpty(device.getName())) {
-                mobilePosition.setDeviceName(device.getName());
-            }
-            mobilePosition.setDeviceId(device.getDeviceId());
-            mobilePosition.setChannelId(getText(rootElement, "DeviceID"));
-            mobilePosition.setTime(getText(rootElement, "Time"));
-            mobilePosition.setLongitude(Double.parseDouble(getText(rootElement, "Longitude")));
-            mobilePosition.setLatitude(Double.parseDouble(getText(rootElement, "Latitude")));
-            if (NumericUtil.isDouble(getText(rootElement, "Speed"))) {
-                mobilePosition.setSpeed(Double.parseDouble(getText(rootElement, "Speed")));
-            } else {
-                mobilePosition.setSpeed(0.0);
-            }
-            if (NumericUtil.isDouble(getText(rootElement, "Direction"))) {
-                mobilePosition.setDirection(Double.parseDouble(getText(rootElement, "Direction")));
-            } else {
-                mobilePosition.setDirection(0.0);
-            }
-            if (NumericUtil.isDouble(getText(rootElement, "Altitude"))) {
-                mobilePosition.setAltitude(Double.parseDouble(getText(rootElement, "Altitude")));
-            } else {
-                mobilePosition.setAltitude(0.0);
-            }
-            mobilePosition.setReportSource("Mobile Position");
+        taskQueue.offer(new SipMsgInfo(evt, device, rootElement));
+        if (!taskQueueHandlerRun) {
+            taskQueueHandlerRun = true;
+            taskExecutor.execute(() -> {
+                while (!taskQueue.isEmpty()) {
+                    SipMsgInfo sipMsgInfo = taskQueue.poll();
+                    try {
+                        Element rootElementAfterCharset = getRootElement(sipMsgInfo.getEvt(), sipMsgInfo.getDevice().getCharset());
+                        if (rootElementAfterCharset == null) {
+                            logger.warn("[ 绉诲姩璁惧浣嶇疆鏁版嵁閫氱煡 ] content cannot be null, {}", sipMsgInfo.getEvt().getRequest());
+                            responseAck(getServerTransaction(sipMsgInfo.getEvt()), Response.BAD_REQUEST);
+                            continue;
+                        }
+                        MobilePosition mobilePosition = new MobilePosition();
+                        mobilePosition.setCreateTime(DateUtil.getNow());
+                        if (!ObjectUtils.isEmpty(sipMsgInfo.getDevice().getName())) {
+                            mobilePosition.setDeviceName(sipMsgInfo.getDevice().getName());
+                        }
+                        mobilePosition.setDeviceId(sipMsgInfo.getDevice().getDeviceId());
+                        mobilePosition.setChannelId(getText(rootElementAfterCharset, "DeviceID"));
+                        mobilePosition.setTime(getText(rootElementAfterCharset, "Time"));
+                        mobilePosition.setLongitude(Double.parseDouble(getText(rootElementAfterCharset, "Longitude")));
+                        mobilePosition.setLatitude(Double.parseDouble(getText(rootElementAfterCharset, "Latitude")));
+                        if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Speed"))) {
+                            mobilePosition.setSpeed(Double.parseDouble(getText(rootElementAfterCharset, "Speed")));
+                        } else {
+                            mobilePosition.setSpeed(0.0);
+                        }
+                        if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Direction"))) {
+                            mobilePosition.setDirection(Double.parseDouble(getText(rootElementAfterCharset, "Direction")));
+                        } else {
+                            mobilePosition.setDirection(0.0);
+                        }
+                        if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Altitude"))) {
+                            mobilePosition.setAltitude(Double.parseDouble(getText(rootElementAfterCharset, "Altitude")));
+                        } else {
+                            mobilePosition.setAltitude(0.0);
+                        }
+                        mobilePosition.setReportSource("Mobile Position");
 
 
-            // 鏇存柊device channel 鐨勭粡绾害
-            DeviceChannel deviceChannel = new DeviceChannel();
-            deviceChannel.setDeviceId(device.getDeviceId());
-            deviceChannel.setChannelId(mobilePosition.getChannelId());
-            deviceChannel.setLongitude(mobilePosition.getLongitude());
-            deviceChannel.setLatitude(mobilePosition.getLatitude());
-            deviceChannel.setGpsTime(mobilePosition.getTime());
+                        // 鏇存柊device channel 鐨勭粡绾害
+                        DeviceChannel deviceChannel = new DeviceChannel();
+                        deviceChannel.setDeviceId(sipMsgInfo.getDevice().getDeviceId());
+                        deviceChannel.setChannelId(mobilePosition.getChannelId());
+                        deviceChannel.setLongitude(mobilePosition.getLongitude());
+                        deviceChannel.setLatitude(mobilePosition.getLatitude());
+                        deviceChannel.setGpsTime(mobilePosition.getTime());
 
-            deviceChannel = deviceChannelService.updateGps(deviceChannel, device);
+                        deviceChannel = deviceChannelService.updateGps(deviceChannel, sipMsgInfo.getDevice());
 
-            mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84());
-            mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84());
-            mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02());
-            mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02());
+                        mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84());
+                        mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84());
+                        mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02());
+                        mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02());
 
-            if (userSetting.getSavePositionHistory()) {
-                storager.insertMobilePosition(mobilePosition);
-            }
-            storager.updateChannelPosition(deviceChannel);
-            //鍥炲 200 OK
-            responseAck(evt, Response.OK);
+                        if (userSetting.getSavePositionHistory()) {
+                            storager.insertMobilePosition(mobilePosition);
+                        }
+                        storager.updateChannelPosition(deviceChannel);
+                        //鍥炲 200 OK
+                        responseAck(getServerTransaction(sipMsgInfo.getEvt()), Response.OK);
 
-            // 鍙戦�乺edis娑堟伅銆� 閫氱煡浣嶇疆淇℃伅鐨勫彉鍖�
-            JSONObject jsonObject = new JSONObject();
-            jsonObject.put("time", mobilePosition.getTime());
-            jsonObject.put("serial", deviceChannel.getDeviceId());
-            jsonObject.put("code", deviceChannel.getChannelId());
-            jsonObject.put("longitude", mobilePosition.getLongitude());
-            jsonObject.put("latitude", mobilePosition.getLatitude());
-            jsonObject.put("altitude", mobilePosition.getAltitude());
-            jsonObject.put("direction", mobilePosition.getDirection());
-            jsonObject.put("speed", mobilePosition.getSpeed());
-            redisCatchStorage.sendMobilePositionMsg(jsonObject);
+                        // 鍙戦�乺edis娑堟伅銆� 閫氱煡浣嶇疆淇℃伅鐨勫彉鍖�
+                        JSONObject jsonObject = new JSONObject();
+                        jsonObject.put("time", mobilePosition.getTime());
+                        jsonObject.put("serial", deviceChannel.getDeviceId());
+                        jsonObject.put("code", deviceChannel.getChannelId());
+                        jsonObject.put("longitude", mobilePosition.getLongitude());
+                        jsonObject.put("latitude", mobilePosition.getLatitude());
+                        jsonObject.put("altitude", mobilePosition.getAltitude());
+                        jsonObject.put("direction", mobilePosition.getDirection());
+                        jsonObject.put("speed", mobilePosition.getSpeed());
+                        redisCatchStorage.sendMobilePositionMsg(jsonObject);
 
-        } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
-            e.printStackTrace();
+                    } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
+                        e.printStackTrace();
+                    }
+
+                }
+                taskQueueHandlerRun = false;
+            });
         }
+
+
     }
 
     @Override
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/AlarmQueryMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/AlarmQueryMessageHandler.java
index 8c884d5..e35da0e 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/AlarmQueryMessageHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/AlarmQueryMessageHandler.java
@@ -58,7 +58,7 @@
 
         logger.info("涓嶆敮鎸乤larm鏌ヨ");
         try {
-            responseAck(evt, Response.NOT_FOUND, "not support alarm query");
+            responseAck(getServerTransaction(evt), Response.NOT_FOUND, "not support alarm query");
         } catch (SipException e) {
             e.printStackTrace();
         } catch (InvalidArgumentException e) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/CatalogQueryMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/CatalogQueryMessageHandler.java
index d2db8f0..cd98094 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/CatalogQueryMessageHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/CatalogQueryMessageHandler.java
@@ -66,7 +66,7 @@
         FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
         try {
             // 鍥炲200 OK
-            responseAck(evt, Response.OK);
+            responseAck(getServerTransaction(evt), Response.OK);
             Element snElement = rootElement.element("SN");
             String sn = snElement.getText();
             // 鍑嗗鍥炲閫氶亾淇℃伅
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceInfoQueryMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceInfoQueryMessageHandler.java
index 19183e0..27d9200 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceInfoQueryMessageHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceInfoQueryMessageHandler.java
@@ -48,7 +48,7 @@
         FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
         try {
             // 鍥炲200 OK
-            responseAck(evt, Response.OK);
+            responseAck(getServerTransaction(evt), Response.OK);
         } catch (SipException e) {
             e.printStackTrace();
         } catch (InvalidArgumentException e) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceStatusQueryMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceStatusQueryMessageHandler.java
index 64df786..05d2714 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceStatusQueryMessageHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceStatusQueryMessageHandler.java
@@ -61,7 +61,7 @@
         FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
         // 鍥炲200 OK
         try {
-            responseAck(evt, Response.OK);
+            responseAck(getServerTransaction(evt), Response.OK);
         } catch (SipException e) {
             e.printStackTrace();
         } catch (InvalidArgumentException 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 4b6c902..49e04e9 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
@@ -21,6 +21,7 @@
 
 import javax.sip.InvalidArgumentException;
 import javax.sip.RequestEvent;
+import javax.sip.ServerTransaction;
 import javax.sip.SipException;
 import javax.sip.header.FromHeader;
 import javax.sip.message.Response;
@@ -68,7 +69,7 @@
     public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
 
         FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
-
+        ServerTransaction serverTransaction = getServerTransaction(evt);
         Element snElement = rootElement.element("SN");
         int sn = Integer.parseInt(snElement.getText());
         Element deviceIDElement = rootElement.element("DeviceID");
@@ -108,7 +109,7 @@
                     DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(endTime), sn, secrecy, type, (eventResult -> {
                         // 鍥炲200 OK
                         try {
-                            responseAck(evt, Response.OK);
+                            responseAck(serverTransaction, Response.OK);
                         } catch (SipException e) {
                             e.printStackTrace();
                         } catch (InvalidArgumentException e) {
@@ -119,7 +120,7 @@
                     }),(eventResult -> {
                         // 鏌ヨ澶辫触
                         try {
-                            responseAck(evt, eventResult.statusCode, eventResult.msg);
+                            responseAck(serverTransaction, eventResult.statusCode, eventResult.msg);
                         } catch (SipException e) {
                             e.printStackTrace();
                         } catch (InvalidArgumentException e) {
@@ -132,7 +133,7 @@
         }else if (channelSources.get(1).getCount() > 0) { // 鐩存挱娴�
             // TODO
             try {
-                responseAck(evt, Response.NOT_IMPLEMENTED); // 鍥炲鏈疄鐜�
+                responseAck(serverTransaction, Response.NOT_IMPLEMENTED); // 鍥炲鏈疄鐜�
             } catch (SipException e) {
                 e.printStackTrace();
             } catch (InvalidArgumentException e) {
@@ -142,7 +143,7 @@
             }
         }else { // 閿欒鐨勮姹�
             try {
-                responseAck(evt, Response.BAD_REQUEST);
+                responseAck(serverTransaction, Response.BAD_REQUEST);
             } catch (SipException e) {
                 e.printStackTrace();
             } catch (InvalidArgumentException e) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java
index e684be3..0aa152c 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java
@@ -21,6 +21,7 @@
 
 import javax.sip.InvalidArgumentException;
 import javax.sip.RequestEvent;
+import javax.sip.ServerTransaction;
 import javax.sip.SipException;
 import javax.sip.message.Response;
 import java.text.ParseException;
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 be01fd7..3cff19d 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
@@ -27,6 +27,7 @@
 
 import javax.sip.InvalidArgumentException;
 import javax.sip.RequestEvent;
+import javax.sip.ServerTransaction;
 import javax.sip.SipException;
 import javax.sip.message.Response;
 import java.text.ParseException;
@@ -87,7 +88,8 @@
         taskQueue.offer(new HandlerCatchData(evt, device, element));
         // 鍥炲200 OK
         try {
-            responseAck(evt, Response.OK);
+            ServerTransaction serverTransaction = getServerTransaction(evt);
+            responseAck(serverTransaction, Response.OK);
             if (!taskQueueHandlerRun) {
                 taskQueueHandlerRun = true;
                 taskExecutor.execute(()-> {
@@ -103,7 +105,7 @@
                             Element sumNumElement = rootElement.element("SumNum");
                             Element snElement = rootElement.element("SN");
                             if (snElement == null || sumNumElement == null || deviceListElement == null) {
-                                responseAck(take.getEvt(), Response.BAD_REQUEST, "xml error");
+                                responseAck(serverTransaction, Response.BAD_REQUEST, "xml error");
                                 continue;
                             }
                             int sumNum = Integer.parseInt(sumNumElement.getText());
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/ConfigDownloadResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/ConfigDownloadResponseMessageHandler.java
index d1a2893..200677a 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/ConfigDownloadResponseMessageHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/ConfigDownloadResponseMessageHandler.java
@@ -52,7 +52,7 @@
         String key = DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + device.getDeviceId() + channelId;
         try {
             // 鍥炲200 OK
-            responseAck(evt, Response.OK);
+            responseAck(getServerTransaction(evt), Response.OK);
             // 姝ゅ鏄鏈钩鍙板彂鍑篋eviceControl鎸囦护鐨勫簲绛�
             JSONObject json = new JSONObject();
             XmlUtil.node2Json(element, json);
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceControlResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceControlResponseMessageHandler.java
index 0c9b835..cd6d1b8 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceControlResponseMessageHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceControlResponseMessageHandler.java
@@ -46,7 +46,7 @@
     public void handForDevice(RequestEvent evt, Device device, Element element) {
         // 姝ゅ鏄鏈钩鍙板彂鍑篋eviceControl鎸囦护鐨勫簲绛�
         try {
-            responseAck(evt, Response.OK);
+            responseAck(getServerTransaction(evt), Response.OK);
             JSONObject json = new JSONObject();
             String channelId = getText(element, "DeviceID");
             XmlUtil.node2Json(element, json);
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 98e5ac0..a0109ed 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
@@ -25,6 +25,7 @@
 
 import javax.sip.InvalidArgumentException;
 import javax.sip.RequestEvent;
+import javax.sip.ServerTransaction;
 import javax.sip.SipException;
 import javax.sip.message.Response;
 import java.text.ParseException;
@@ -74,11 +75,12 @@
             logger.warn("[鎺ユ敹鍒癉eviceInfo搴旂瓟娑堟伅,浣嗘槸璁惧宸茬粡绂荤嚎]锛�" + (device != null ? device.getDeviceId():"" ));
             return;
         }
+        ServerTransaction serverTransaction = getServerTransaction(evt);
         try {
             rootElement = getRootElement(evt, device.getCharset());
             if (rootElement == null) {
                 logger.warn("[ 鎺ユ敹鍒癉eviceInfo搴旂瓟娑堟伅 ] content cannot be null, {}", evt.getRequest());
-                responseAck(evt, Response.BAD_REQUEST);
+                responseAck(serverTransaction, Response.BAD_REQUEST);
                 return;
             }
             Element deviceIdElement = rootElement.element("DeviceID");
@@ -99,7 +101,7 @@
             msg.setData(device);
             deferredResultHolder.invokeAllResult(msg);
             // 鍥炲200 OK
-            responseAck(evt, Response.OK);
+            responseAck(serverTransaction, Response.OK);
         } 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 5854261..b324b5d 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
@@ -59,7 +59,7 @@
         }
         // 鍥炲200 OK
         try {
-            responseAck(evt, Response.OK);
+            responseAck(getServerTransaction(evt), Response.OK);
         } catch (SipException e) {
             e.printStackTrace();
         } catch (InvalidArgumentException e) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java
index 42666db..158f5b7 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java
@@ -25,6 +25,7 @@
 
 import javax.sip.InvalidArgumentException;
 import javax.sip.RequestEvent;
+import javax.sip.ServerTransaction;
 import javax.sip.SipException;
 import javax.sip.message.Response;
 import java.text.ParseException;
@@ -64,11 +65,13 @@
     @Override
     public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
 
+        ServerTransaction serverTransaction = getServerTransaction(evt);
+
         try {
             rootElement = getRootElement(evt, device.getCharset());
             if (rootElement == null) {
                 logger.warn("[ 绉诲姩璁惧浣嶇疆鏁版嵁鏌ヨ鍥炲 ] content cannot be null, {}", evt.getRequest());
-                responseAck(evt, Response.BAD_REQUEST);
+                responseAck(serverTransaction, Response.BAD_REQUEST);
                 return;
             }
             MobilePosition mobilePosition = new MobilePosition();
@@ -130,7 +133,7 @@
             jsonObject.put("speed", mobilePosition.getSpeed());
             redisCatchStorage.sendMobilePositionMsg(jsonObject);
             //鍥炲 200 OK
-            responseAck(evt, Response.OK);
+            responseAck(serverTransaction, Response.OK);
         } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
             e.printStackTrace();
         }
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 abc9440..1febeae 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
@@ -17,6 +17,7 @@
 
 import javax.sip.InvalidArgumentException;
 import javax.sip.RequestEvent;
+import javax.sip.ServerTransaction;
 import javax.sip.SipException;
 import javax.sip.message.Response;
 import java.text.ParseException;
@@ -51,10 +52,13 @@
     public void handForDevice(RequestEvent evt, Device device, Element element) {
         Element rootElement = null;
         try {
+
+            ServerTransaction serverTransaction = getServerTransaction(evt);
+
             rootElement = getRootElement(evt, device.getCharset());
             if (rootElement == null) {
                 logger.warn("[ 璁惧棰勭疆浣嶆煡璇㈠簲绛� ] content cannot be null, {}", evt.getRequest());
-                responseAck(evt, Response.BAD_REQUEST);
+                responseAck(serverTransaction, Response.BAD_REQUEST);
                 return;
             }
             Element presetListNumElement = rootElement.element("PresetList");
@@ -63,7 +67,7 @@
             String deviceId = getText(rootElement, "DeviceID");
             String key = DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + deviceId;
             if (snElement == null ||  presetListNumElement == null) {
-                responseAck(evt, Response.BAD_REQUEST, "xml error");
+                responseAck(serverTransaction, Response.BAD_REQUEST, "xml error");
                 return;
             }
             int sumNum = Integer.parseInt(presetListNumElement.attributeValue("Num"));
@@ -93,7 +97,7 @@
             requestMessage.setKey(key);
             requestMessage.setData(presetQuerySipReqList);
             deferredResultHolder.invokeAllResult(requestMessage);
-            responseAck(evt, Response.OK);
+            responseAck(serverTransaction, Response.OK);
         } 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/RecordInfoResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java
index d96b622..e9ee32d 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
@@ -72,7 +72,7 @@
 
         // 鍥炲200 OK
         try {
-            responseAck(evt, Response.OK);
+            responseAck(getServerTransaction(evt), Response.OK);
             taskQueue.offer(new HandlerCatchData(evt, device, rootElement));
             if (!taskQueueHandlerRun) {
                 taskQueueHandlerRun = true;
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java
index a2bc6e1..9b09029 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java
@@ -7,6 +7,8 @@
 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
 import com.genersoft.iot.vmp.utils.GitUtil;
 import gov.nist.javax.sip.ResponseEventExt;
+import gov.nist.javax.sip.message.SIPResponse;
+import gov.nist.javax.sip.stack.SIPClientTransaction;
 import gov.nist.javax.sip.stack.SIPDialog;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -78,7 +80,7 @@
 			// 涓嬪彂ack
 			if (statusCode == Response.OK) {
 				ResponseEventExt event = (ResponseEventExt)evt;
-				SIPDialog dialog = (SIPDialog)evt.getDialog();
+				SIPDialog dialog = new SIPDialog((SIPClientTransaction) event.getClientTransaction(), (SIPResponse) event.getResponse());
 				CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
 				Request reqAck = dialog.createAck(cseq.getSeqNumber());
 				SipURI requestURI = (SipURI) reqAck.getRequestURI();
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
index b789974..cbecf0f 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -103,7 +103,7 @@
 	@PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8")
 	public JSONObject onServerKeepalive(@RequestBody JSONObject json){
 
-		logger.info("[ ZLM HOOK ] on_server_keepalive API璋冪敤锛屽弬鏁帮細" + json.toString());
+		logger.info("[ ZLM HOOK ]on_server_keepalive API璋冪敤锛屽弬鏁帮細" + json.toString());
 		String mediaServerId = json.getString("mediaServerId");
 		List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive);
 		if (subscribes != null  && subscribes.size() > 0) {
@@ -417,10 +417,11 @@
 		String schema = item.getSchema();
 		List<MediaItem.MediaTrack> tracks = item.getTracks();
 		boolean regist = item.isRegist();
-		if (item.getOriginType() == OriginType.RTMP_PUSH.ordinal()
-				|| item.getOriginType() == OriginType.RTSP_PUSH.ordinal()
-				|| item.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
-			if (regist) {
+		if (regist) {
+			if (item.getOriginType() == OriginType.RTMP_PUSH.ordinal()
+					|| item.getOriginType() == OriginType.RTSP_PUSH.ordinal()
+					|| item.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
+
 				StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream);
 				if (streamAuthorityInfo == null) {
 					streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(item);
@@ -429,9 +430,9 @@
 					streamAuthorityInfo.setOriginTypeStr(item.getOriginTypeStr());
 				}
 				redisCatchStorage.updateStreamAuthorityInfo(app, stream, streamAuthorityInfo);
-			}else {
-				redisCatchStorage.removeStreamAuthorityInfo(app, stream);
 			}
+		}else {
+			redisCatchStorage.removeStreamAuthorityInfo(app, stream);
 		}
 
 		if ("rtsp".equals(schema)){
@@ -451,15 +452,12 @@
 				if (streamInfo!=null){
 					redisCatchStorage.stopPlay(streamInfo);
 					storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
-					// 濡傛灉姝e湪缁欎笂绾ф帹閫侊紝鍒欏彂閫乥ye
-
 				}else{
 					streamInfo = redisCatchStorage.queryPlayback(null, null, stream, null);
 					if (streamInfo != null) {
 						redisCatchStorage.stopPlayback(streamInfo.getDeviceID(), streamInfo.getChannelId(),
 								streamInfo.getStream(), null);
 					}
-					// 濡傛灉姝e湪缁欎笂绾ф帹閫侊紝鍒欏彂閫乥ye
 				}
 			}else {
 				if (!"rtp".equals(app)){
@@ -509,6 +507,19 @@
 					}
 				}
 			}
+			if (!regist) {
+				List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(stream);
+				if (sendRtpItems.size() > 0) {
+					for (SendRtpItem sendRtpItem : sendRtpItems) {
+						if (sendRtpItem.getApp().equals(app)) {
+							String platformId = sendRtpItem.getPlatformId();
+							ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);
+
+							commanderFroPlatform.streamByeCmd(platform, sendRtpItem);
+						}
+					}
+				}
+			}
 		}
 
 		JSONObject ret = new JSONObject();
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
index 50a1fa5..b545ccc 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
@@ -17,6 +17,7 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.text.ParseException;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -83,7 +84,11 @@
         }
         if (transform != null) {
             if (getChannelOnlineEventLister(transform.getApp(), transform.getStream()) != null)  {
-                getChannelOnlineEventLister(transform.getApp(), transform.getStream()).run(transform.getApp(), transform.getStream(), transform.getServerId());
+                try {
+                    getChannelOnlineEventLister(transform.getApp(), transform.getStream()).run(transform.getApp(), transform.getStream(), transform.getServerId());
+                } catch (ParseException e) {
+                    throw new RuntimeException(e);
+                }
                 removedChannelOnlineEventLister(transform.getApp(), transform.getStream());
             }
         }
@@ -95,7 +100,11 @@
         // 鏌ョ湅鎺ㄦ祦鐘舵��
         if (zlmrtpServerFactory.isStreamReady(mediaServerItem, app, stream)) {
             if (getChannelOnlineEventLister(app, stream) != null)  {
-                getChannelOnlineEventLister(app, stream).run(app, stream, mediaServerId);
+                try {
+                    getChannelOnlineEventLister(app, stream).run(app, stream, mediaServerId);
+                } catch (ParseException e) {
+                    throw new RuntimeException(e);
+                }
                 removedChannelOnlineEventLister(app, stream);
             }
         }
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
index 6767f61..80ae95e 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
@@ -98,7 +98,18 @@
                 result = rtpInfo.getInteger("local_port");
                 if (result == 0) {
                     // 姝ゆ椂璇存槑rtpServer宸茬粡鍒涘缓浣嗘槸娴佽繕娌℃湁鎺ㄤ笂鏉�
-
+                    // 姝ゆ椂閲嶆柊鎵撳紑rtpServer
+                    Map<String, Object> param = new HashMap<>();
+                    param.put("stream_id", streamId);
+                    JSONObject jsonObject = zlmresTfulUtils.closeRtpServer(mediaServerItem, param);
+                    if (jsonObject != null ) {
+                        System.out.println(jsonObject);
+                        if (jsonObject.getInteger("code") == 0) {
+                            return createRTPServer(mediaServerItem, streamId, ssrc, port);
+                        }else {
+                            logger.warn("[寮�鍚痳tpServer], 閲嶅惎RtpServer閿欒");
+                        }
+                    }
                 }
                 return result;
             }
@@ -326,12 +337,12 @@
         Boolean result = false;
         JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaServerItem, param);
         if (jsonObject == null) {
-            logger.error("鍋滄RTP鎺ㄦ祦澶辫触: 璇锋鏌LM鏈嶅姟");
+            logger.error("[鍋滄RTP鎺ㄦ祦] 澶辫触: 璇锋鏌LM鏈嶅姟");
         } else if (jsonObject.getInteger("code") == 0) {
             result= true;
-            logger.info("鍋滄RTP鎺ㄦ祦鎴愬姛");
+            logger.info("[鍋滄RTP鎺ㄦ祦] 鎴愬姛");
         } else {
-            logger.error("鍋滄RTP鎺ㄦ祦澶辫触: {}, 鍙傛暟锛歿}",jsonObject.getString("msg"),JSONObject.toJSON(param));
+            logger.error("[鍋滄RTP鎺ㄦ祦] 澶辫触: {}, 鍙傛暟锛歿}->\r\n{}",jsonObject.getString("msg"),JSONObject.toJSON(param), jsonObject);
         }
         return result;
     }
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 da4bb76..3dfb167 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
@@ -104,7 +104,7 @@
         }, 60 * 1000 );
     }
 
-    @Async
+    @Async("taskExecutor")
     public void connectZlmServer(MediaServerItem mediaServerItem){
         String connectZlmServerTaskKey = "connect-zlm-" + mediaServerItem.getId();
         ZLMServerConfig zlmServerConfigFirst = getMediaServerConfig(mediaServerItem);
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java
index 823bdab..19ffdc4 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java
@@ -137,8 +137,6 @@
     @Scheduled(cron="0 0/5 * * * ?")   //姣�5鍒嗛挓鎵ц涓�娆�
     public void execute(){
 
-        logger.info("[hook璁㈤槄] 娓呯悊");
-
         Instant instant = Instant.now().minusMillis(TimeUnit.MINUTES.toMillis(5));
         int total = 0;
         for (HookType hookType : allSubscribes.keySet()) {
@@ -153,6 +151,5 @@
                 }
             }
         }
-        logger.info("[hook璁㈤槄] 娓呯悊缁撴潫锛屽叡娓呯悊{}鏉¤繃鏈熸暟鎹�", total);
     }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ChannelOnlineEvent.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ChannelOnlineEvent.java
index 21e6ca0..714838e 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ChannelOnlineEvent.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ChannelOnlineEvent.java
@@ -1,9 +1,11 @@
 package com.genersoft.iot.vmp.media.zlm.dto;
 
+import java.text.ParseException;
+
 /**
  * @author lin
  */
 public interface ChannelOnlineEvent {
 
-    void run(String app, String stream, String serverId);
+    void run(String app, String stream, String serverId) throws ParseException;
 }
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 223ef13..bad8e56 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
@@ -36,7 +36,7 @@
 	@Autowired
 	private IPlayService playService;
 
-	@Async
+	@Async("taskExecutor")
 	@EventListener
 	public void onApplicationEvent(ZLMOnlineEvent event) {
 		logger.info("[ZLM] 涓婄嚎 ID锛�" + event.getMediaServerId());
@@ -45,7 +45,7 @@
 		playService.zlmServerOnline(event.getMediaServerId());
 	}
 
-	@Async
+	@Async("taskExecutor")
 	@EventListener
 	public void onApplicationEvent(ZLMOfflineEvent event) {
 
diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java
index b5f3c5b..ddc91eb 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java
@@ -1,7 +1,12 @@
 package com.genersoft.iot.vmp.service;
 
+import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
+import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo;
+import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
 import com.github.pagehelper.PageInfo;
+
+import java.util.List;
 
 /**
  * 鍥芥爣骞冲彴鐨勪笟鍔$被
@@ -42,4 +47,10 @@
      * @param parentPlatform
      */
     void login(ParentPlatform parentPlatform);
+
+    /**
+     * 鍚戜笂绾у钩鍙板彂閫佷綅缃闃�
+     * @param platformId 骞冲彴
+     */
+    void sendNotifyMobilePosition(String platformId);
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java
index d024550..22d195e 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java
@@ -73,7 +73,9 @@
             result = platformChannelMapper.addChannels(platformId, channelReducesToAdd);
             // TODO 鍚庣画缁欏钩鍙板鍔犳帶鍒跺紑鍏充互鎺у埗鏄惁鍝嶅簲鐩綍璁㈤槄
             List<DeviceChannel> deviceChannelList = getDeviceChannelListByChannelReduceList(channelReducesToAdd, catalogId, platform);
-            eventPublisher.catalogEventPublish(platformId, deviceChannelList, CatalogEvent.ADD);
+            if (deviceChannelList != null) {
+                eventPublisher.catalogEventPublish(platformId, deviceChannelList, CatalogEvent.ADD);
+            }
         }
 
         return result;
@@ -83,7 +85,7 @@
         List<DeviceChannel> deviceChannelList = new ArrayList<>();
         if (channelReduces.size() > 0){
             PlatformCatalog catalog = catalogManager.select(catalogId);
-            if (catalog == null && !catalogId.equals(platform.getServerGBId())) {
+            if (catalog == null && !catalogId.equals(platform.getDeviceGBId())) {
                 logger.warn("鏈煡璇㈠埌鐩綍{}鐨勪俊鎭�", catalogId);
                 return null;
             }
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
index 6df1483..3c5644b 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
@@ -1,17 +1,17 @@
 package com.genersoft.iot.vmp.service.impl;
 
 import com.genersoft.iot.vmp.conf.DynamicTask;
-import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
-import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
-import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
-import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder;
+import com.genersoft.iot.vmp.conf.UserSetting;
+import com.genersoft.iot.vmp.gb28181.bean.*;
 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
 import com.genersoft.iot.vmp.service.IMediaServerService;
 import com.genersoft.iot.vmp.service.IPlatformService;
+import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
+import com.genersoft.iot.vmp.storager.dao.GbStreamMapper;
 import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
@@ -56,6 +56,12 @@
 
     @Autowired
     private SubscribeHolder subscribeHolder;
+
+    @Autowired
+    private GbStreamMapper gbStreamMapper;
+
+    @Autowired
+    private UserSetting userSetting;
 
 
 
@@ -228,4 +234,34 @@
                     60*1000);
         }, null);
     }
+
+    @Override
+    public void sendNotifyMobilePosition(String platformId) {
+        ParentPlatform platform = platformMapper.getParentPlatByServerGBId(platformId);
+        if (platform == null) {
+            return;
+        }
+        SubscribeInfo subscribe = subscribeHolder.getMobilePositionSubscribe(platform.getServerGBId());
+        if (subscribe != null) {
+
+            // TODO 鏆傛椂鍙鐞嗚棰戞祦鐨勫洖澶�,鍚庣画澧炲姞瀵瑰浗鏍囪澶囩殑鏀寔
+            List<DeviceChannel> gbStreams = gbStreamMapper.queryGbStreamListInPlatform(platform.getServerGBId(), userSetting.isUsePushingAsStatus());
+            if (gbStreams.size() == 0) {
+                return;
+            }
+            for (DeviceChannel deviceChannel : gbStreams) {
+                String gbId = deviceChannel.getChannelId();
+                GPSMsgInfo gpsMsgInfo = redisCatchStorage.getGpsMsgInfo(gbId);
+                // 鏃犳渶鏂颁綅缃笉鍙戦��
+                if (gpsMsgInfo != null) {
+                    // 缁忕含搴﹂兘涓�0涓嶅彂閫�
+                    if (gpsMsgInfo.getLng() == 0 && gpsMsgInfo.getLat() == 0) {
+                        continue;
+                    }
+                    // 鍙戦�丟PS娑堟伅
+                    commanderForPlatform.sendNotifyMobilePosition(platform, gpsMsgInfo, subscribe);
+                }
+            }
+        }
+    }
 }
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 f4a3c68..274eca8 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
@@ -177,6 +177,7 @@
                 }
             });
         });
+
         if (streamInfo != null) {
             String streamId = streamInfo.getStream();
             if (streamId == null) {
@@ -281,7 +282,7 @@
         if (ssrcInfo == null) {
             ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, device.isSsrcCheck(), false);
         }
-        logger.info("[鐐规挱寮�濮媇 deviceId: {}, channelId: {}, SSRC: {}", device.getDeviceId(), channelId, ssrcInfo.getSsrc() );
+        logger.info("[鐐规挱寮�濮媇 deviceId: {}, channelId: {},鏀舵祦绔彛锛� {}, 鏀舵祦妯″紡锛歿}, SSRC: {}, SSRC鏍¢獙锛歿}", device.getDeviceId(), channelId, ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck() );
         // 瓒呮椂澶勭悊
         String timeOutTaskKey = UUID.randomUUID().toString();
         SSRCInfo finalSsrcInfo = ssrcInfo;
@@ -290,12 +291,12 @@
 
             SIPDialog dialog = streamSession.getDialogByStream(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
             if (dialog != null) {
-                logger.info("[鐐规挱瓒呮椂] 鏀舵祦瓒呮椂 deviceId: {}, channelId: {}", device.getDeviceId(), channelId);
+                logger.info("[鐐规挱瓒呮椂] 鏀舵祦瓒呮椂 deviceId: {}, channelId: {}锛岀鍙o細{}, SSRC: {}", device.getDeviceId(), channelId, finalSsrcInfo.getPort(), finalSsrcInfo.getSsrc());
                 timeoutCallback.run(1, "鏀舵祦瓒呮椂");
                 // 鐐规挱瓒呮椂鍥炲BYE 鍚屾椂閲婃斁ssrc浠ュ強姝ゆ鐐规挱鐨勮祫婧�
                 cmder.streamByeCmd(device.getDeviceId(), channelId, finalSsrcInfo.getStream(), null);
             }else {
-                logger.info("[鐐规挱瓒呮椂] 娑堟伅鏈搷搴� deviceId: {}, channelId: {}", device.getDeviceId(), channelId);
+                logger.info("[鐐规挱瓒呮椂] 娑堟伅鏈搷搴� deviceId: {}, channelId: {}锛岀鍙o細{}, SSRC: {}", device.getDeviceId(), channelId, finalSsrcInfo.getPort(), finalSsrcInfo.getSsrc());
                 timeoutCallback.run(0, "鐐规挱瓒呮椂");
                 mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
                 mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
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
deleted file mode 100644
index 1634234..0000000
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package com.genersoft.iot.vmp.service.impl;
-
-import com.alibaba.fastjson.JSON;
-import com.genersoft.iot.vmp.gb28181.bean.*;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
-import com.genersoft.iot.vmp.service.IPlatformChannelService;
-import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
-import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
-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.stereotype.Component;
-import org.springframework.util.ObjectUtils;
-
-import java.util.List;
-
-
-@Component
-public class RedisAlarmMsgListener implements MessageListener {
-
-    private final static Logger logger = LoggerFactory.getLogger(RedisAlarmMsgListener.class);
-
-    @Autowired
-    private ISIPCommander commander;
-
-    @Autowired
-    private ISIPCommanderForPlatform commanderForPlatform;
-
-    @Autowired
-    private IVideoManagerStorage storage;
-
-    @Override
-    public void onMessage(Message message, byte[] bytes) {
-        logger.info("鏀跺埌鏉ヨ嚜REDIS鐨凙LARM閫氱煡锛� {}", new String(message.getBody()));
-        AlarmChannelMessage alarmChannelMessage = JSON.parseObject(message.getBody(), AlarmChannelMessage.class);
-        if (alarmChannelMessage == null) {
-            logger.warn("[REDIS鐨凙LARM閫氱煡]娑堟伅瑙f瀽澶辫触");
-            return;
-        }
-        String gbId = alarmChannelMessage.getGbId();
-
-        DeviceAlarm deviceAlarm = new DeviceAlarm();
-        deviceAlarm.setCreateTime(DateUtil.getNow());
-        deviceAlarm.setChannelId(gbId);
-        deviceAlarm.setAlarmDescription(alarmChannelMessage.getAlarmDescription());
-        deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn());
-        deviceAlarm.setAlarmPriority("1");
-        deviceAlarm.setAlarmTime(DateUtil.getNowForISO8601());
-        deviceAlarm.setAlarmType("1");
-        deviceAlarm.setLongitude(0);
-        deviceAlarm.setLatitude(0);
-
-        if (ObjectUtils.isEmpty(gbId)) {
-            // 鍙戦�佺粰鎵�鏈夌殑涓婄骇
-            List<ParentPlatform> parentPlatforms = storage.queryEnableParentPlatformList(true);
-            if (parentPlatforms.size() > 0) {
-                for (ParentPlatform parentPlatform : parentPlatforms) {
-                    commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm);
-                }
-            }
-        }else {
-            Device device = storage.queryVideoDevice(gbId);
-            ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId);
-            if (device != null && platform == null) {
-                commander.sendAlarmMessage(device, deviceAlarm);
-            }else if (device == null && platform != null){
-                commanderForPlatform.sendAlarmMessage(platform, deviceAlarm);
-            }else {
-                logger.warn("鏃犳硶纭畾" + gbId + "鏄钩鍙拌繕鏄澶�");
-            }
-        }
-    }
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamResponseListener.java b/src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamResponseListener.java
deleted file mode 100644
index 56c9ff3..0000000
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamResponseListener.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.genersoft.iot.vmp.service.impl;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.genersoft.iot.vmp.media.zlm.dto.ChannelOnlineEvent;
-import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
-import com.genersoft.iot.vmp.service.IGbStreamService;
-import com.genersoft.iot.vmp.service.IMediaServerService;
-import com.genersoft.iot.vmp.service.IStreamPushService;
-import com.genersoft.iot.vmp.service.bean.MessageForPushChannelResponse;
-import com.genersoft.iot.vmp.utils.DateUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.data.redis.connection.Message;
-import org.springframework.data.redis.connection.MessageListener;
-import org.springframework.stereotype.Component;
-import org.springframework.util.ObjectUtils;
-
-import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * 鎺ユ敹redis杩斿洖鐨勬帹娴佺粨鏋�
- * @author lin
- */
-@Component
-public class RedisPushStreamResponseListener implements MessageListener {
-
-    private final static Logger logger = LoggerFactory.getLogger(RedisPushStreamResponseListener.class);
-
-    private Map<String, PushStreamResponseEvent> responseEvents = new ConcurrentHashMap<>();
-
-    public interface PushStreamResponseEvent{
-        void run(MessageForPushChannelResponse response);
-    }
-
-    @Override
-    public void onMessage(Message message, byte[] bytes) {
-        //
-        logger.warn("[REDIS娑堟伅-璇锋眰鎺ㄦ祦缁撴灉]锛� {}", new String(message.getBody()));
-        MessageForPushChannelResponse response = JSON.parseObject(new String(message.getBody()), MessageForPushChannelResponse.class);
-        if (response == null || ObjectUtils.isEmpty(response.getApp()) || ObjectUtils.isEmpty(response.getStream())){
-            logger.info("[REDIS娑堟伅-璇锋眰鎺ㄦ祦缁撴灉]锛氬弬鏁颁笉鍏�");
-            return;
-        }
-        // 鏌ョ湅姝e湪绛夊緟鐨刬nvite娑堟伅
-        if (responseEvents.get(response.getApp() + response.getStream()) != null) {
-            responseEvents.get(response.getApp() + response.getStream()).run(response);
-        }
-    }
-
-    public void addEvent(String app, String stream, PushStreamResponseEvent callback) {
-        responseEvents.put(app + stream, callback);
-    }
-
-    public void removeEvent(String app, String stream) {
-        responseEvents.remove(app + stream);
-    }
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamStatusListMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamStatusListMsgListener.java
deleted file mode 100644
index bedbf44..0000000
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamStatusListMsgListener.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.genersoft.iot.vmp.service.impl;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
-import com.genersoft.iot.vmp.service.IGbStreamService;
-import com.genersoft.iot.vmp.service.IMediaServerService;
-import com.genersoft.iot.vmp.service.IStreamPushService;
-import com.genersoft.iot.vmp.utils.DateUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.data.redis.connection.Message;
-import org.springframework.data.redis.connection.MessageListener;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.Resource;
-import java.util.*;
-
-/**
- * @Auther: JiangFeng
- * @Date: 2022/8/16 11:32
- * @Description: 鎺ユ敹redis鍙戦�佺殑鎺ㄦ祦璁惧鍒楄〃鏇存柊閫氱煡
- */
-@Component
-public class RedisPushStreamStatusListMsgListener implements MessageListener {
-
-    private final static Logger logger = LoggerFactory.getLogger(RedisPushStreamStatusListMsgListener.class);
-    @Resource
-    private IMediaServerService mediaServerService;
-
-    @Resource
-    private IStreamPushService streamPushService;
-    @Resource
-    private IGbStreamService gbStreamService;
-
-    @Override
-    public void onMessage(Message message, byte[] bytes) {
-        //
-        logger.warn("[REDIS娑堟伅-鎺ㄦ祦璁惧鍒楄〃鏇存柊]锛� {}", new String(message.getBody()));
-        List<StreamPushItem> streamPushItems = JSON.parseArray(new String(message.getBody()), StreamPushItem.class);
-        //鏌ヨ鍏ㄩ儴鐨刟pp+stream 鐢ㄤ簬鍒ゆ柇鏄坊鍔犺繕鏄慨鏀�
-        List<String> allAppAndStream = streamPushService.getAllAppAndStream();
-
-        /**
-         * 鐢ㄤ簬瀛樺偍鏇村叿APP+Stream杩囨护鍚庣殑鏁版嵁锛屽彲浠ョ洿鎺ュ瓨鍏tream_push琛ㄤ笌gb_stream琛�
-         */
-        List<StreamPushItem> streamPushItemForSave = new ArrayList<>();
-        List<StreamPushItem> streamPushItemForUpdate = new ArrayList<>();
-        for (StreamPushItem streamPushItem : streamPushItems) {
-            String app = streamPushItem.getApp();
-            String stream = streamPushItem.getStream();
-            boolean contains = allAppAndStream.contains(app + stream);
-            //涓嶅瓨鍦ㄥ氨娣诲姞
-            if (!contains) {
-                streamPushItem.setStreamType("push");
-                streamPushItem.setCreateTime(DateUtil.getNow());
-                streamPushItem.setMediaServerId(mediaServerService.getDefaultMediaServer().getId());
-                streamPushItem.setOriginType(2);
-                streamPushItem.setOriginTypeStr("rtsp_push");
-                streamPushItem.setTotalReaderCount("0");
-                streamPushItemForSave.add(streamPushItem);
-            } else {
-                //瀛樺湪灏卞彧淇敼 name鍜実bId
-                streamPushItemForUpdate.add(streamPushItem);
-            }
-        }
-        if (streamPushItemForSave.size() > 0) {
-
-            logger.info("娣诲姞{}鏉�",streamPushItemForSave.size());
-            logger.info(JSONObject.toJSONString(streamPushItemForSave));
-            streamPushService.batchAdd(streamPushItemForSave);
-
-        }
-        if(streamPushItemForUpdate.size()>0){
-            logger.info("淇敼{}鏉�",streamPushItemForUpdate.size());
-            logger.info(JSONObject.toJSONString(streamPushItemForUpdate));
-            gbStreamService.updateGbIdOrName(streamPushItemForUpdate);
-        }
-
-    }
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisStreamMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/impl/RedisStreamMsgListener.java
deleted file mode 100644
index 118a227..0000000
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisStreamMsgListener.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.genersoft.iot.vmp.service.impl;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.genersoft.iot.vmp.conf.UserSetting;
-
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
-import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager;
-import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
-import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
-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.stereotype.Component;
-
-
-/**
- * 鎺ユ敹鍏朵粬wvp鍙戦�佹祦鍙樺寲閫氱煡
- * @author lin
- */
-@Component
-public class RedisStreamMsgListener implements MessageListener {
-
-    private final static Logger logger = LoggerFactory.getLogger(RedisStreamMsgListener.class);
-
-    @Autowired
-    private UserSetting userSetting;
-
-    @Autowired
-    private ZLMMediaListManager zlmMediaListManager;
-
-    @Override
-    public void onMessage(Message message, byte[] bytes) {
-
-        JSONObject steamMsgJson = JSON.parseObject(message.getBody(), JSONObject.class);
-        if (steamMsgJson == null) {
-            logger.warn("[鏀跺埌redis 娴佸彉鍖朷娑堟伅瑙f瀽澶辫触");
-            return;
-        }
-        String serverId = steamMsgJson.getString("serverId");
-
-        if (userSetting.getServerId().equals(serverId)) {
-            // 鑷繁鍙戦�佺殑娑堟伅蹇界暐鍗冲彲
-            return;
-        }
-        logger.info("[鏀跺埌redis 娴佸彉鍖朷锛� {}", new String(message.getBody()));
-        String app = steamMsgJson.getString("app");
-        String stream = steamMsgJson.getString("stream");
-        boolean register = steamMsgJson.getBoolean("register");
-        String mediaServerId = steamMsgJson.getString("mediaServerId");
-        MediaItem mediaItem = new MediaItem();
-        mediaItem.setSeverId(serverId);
-        mediaItem.setApp(app);
-        mediaItem.setStream(stream);
-        mediaItem.setRegist(register);
-        mediaItem.setMediaServerId(mediaServerId);
-        mediaItem.setCreateStamp(System.currentTimeMillis()/1000);
-        mediaItem.setAliveSecond(0L);
-        mediaItem.setTotalReaderCount("0");
-        mediaItem.setOriginType(0);
-        mediaItem.setOriginTypeStr("0");
-        mediaItem.setOriginTypeStr("unknown");
-        if (register) {
-            zlmMediaListManager.addPush(mediaItem);
-        }else {
-            zlmMediaListManager.removeMedia(app, stream);
-        }
-    }
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java
new file mode 100644
index 0000000..8d1b066
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java
@@ -0,0 +1,102 @@
+package com.genersoft.iot.vmp.service.redisMsg;
+
+import com.alibaba.fastjson.JSON;
+import com.genersoft.iot.vmp.gb28181.bean.*;
+import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
+import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
+import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
+import com.genersoft.iot.vmp.utils.DateUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.connection.Message;
+import org.springframework.data.redis.connection.MessageListener;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+
+@Component
+public class RedisAlarmMsgListener implements MessageListener {
+
+    private final static Logger logger = LoggerFactory.getLogger(RedisAlarmMsgListener.class);
+
+    @Autowired
+    private ISIPCommander commander;
+
+    @Autowired
+    private ISIPCommanderForPlatform commanderForPlatform;
+
+    @Autowired
+    private IVideoManagerStorage storage;
+
+    private boolean taskQueueHandlerRun = false;
+
+    private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
+
+    @Qualifier("taskExecutor")
+    @Autowired
+    private ThreadPoolTaskExecutor taskExecutor;
+
+    @Override
+    public void onMessage(@NotNull Message message, byte[] bytes) {
+        logger.info("鏀跺埌鏉ヨ嚜REDIS鐨凙LARM閫氱煡锛� {}", new String(message.getBody()));
+
+        taskQueue.offer(message);
+        if (!taskQueueHandlerRun) {
+            taskQueueHandlerRun = true;
+            logger.info("[绾跨▼姹犱俊鎭痌娲诲姩绾跨▼鏁帮細{}, 鏈�澶х嚎绋嬫暟锛� {}", taskExecutor.getActiveCount(), taskExecutor.getMaxPoolSize());
+            taskExecutor.execute(() -> {
+                while (!taskQueue.isEmpty()) {
+                    Message msg = taskQueue.poll();
+
+                    AlarmChannelMessage alarmChannelMessage = JSON.parseObject(msg.getBody(), AlarmChannelMessage.class);
+                    if (alarmChannelMessage == null) {
+                        logger.warn("[REDIS鐨凙LARM閫氱煡]娑堟伅瑙f瀽澶辫触");
+                        continue;
+                    }
+                    String gbId = alarmChannelMessage.getGbId();
+
+                    DeviceAlarm deviceAlarm = new DeviceAlarm();
+                    deviceAlarm.setCreateTime(DateUtil.getNow());
+                    deviceAlarm.setChannelId(gbId);
+                    deviceAlarm.setAlarmDescription(alarmChannelMessage.getAlarmDescription());
+                    deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn());
+                    deviceAlarm.setAlarmPriority("1");
+                    deviceAlarm.setAlarmTime(DateUtil.getNowForISO8601());
+                    deviceAlarm.setAlarmType("1");
+                    deviceAlarm.setLongitude(0);
+                    deviceAlarm.setLatitude(0);
+
+                    if (ObjectUtils.isEmpty(gbId)) {
+                        // 鍙戦�佺粰鎵�鏈夌殑涓婄骇
+                        List<ParentPlatform> parentPlatforms = storage.queryEnableParentPlatformList(true);
+                        if (parentPlatforms.size() > 0) {
+                            for (ParentPlatform parentPlatform : parentPlatforms) {
+                                commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm);
+                            }
+                        }
+                    }else {
+                        Device device = storage.queryVideoDevice(gbId);
+                        ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId);
+                        if (device != null && platform == null) {
+                            commander.sendAlarmMessage(device, deviceAlarm);
+                        }else if (device == null && platform != null){
+                            commanderForPlatform.sendAlarmMessage(platform, deviceAlarm);
+                        }else {
+                            logger.warn("鏃犳硶纭畾" + gbId + "鏄钩鍙拌繕鏄澶�");
+                        }
+                    }
+                }
+                taskQueueHandlerRun = false;
+            });
+        }
+
+
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java
similarity index 66%
rename from src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java
rename to src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java
index ff82cd7..2d4a82f 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java
@@ -1,4 +1,4 @@
-package com.genersoft.iot.vmp.service.impl;
+package com.genersoft.iot.vmp.service.redisMsg;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
@@ -19,14 +19,18 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.redis.connection.Message;
 import org.springframework.data.redis.connection.MessageListener;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Component;
 
+import java.text.ParseException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
 
 
 /**
@@ -84,9 +88,17 @@
     @Autowired
     private ZlmHttpHookSubscribe subscribe;
 
+    private boolean taskQueueHandlerRun = false;
+
+    private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
+
+    @Qualifier("taskExecutor")
+    @Autowired
+    private ThreadPoolTaskExecutor taskExecutor;
+
 
     public interface PlayMsgCallback{
-        void handler(ResponseSendItemMsg responseSendItemMsg);
+        void handler(ResponseSendItemMsg responseSendItemMsg) throws ParseException;
     }
 
     public interface PlayMsgCallbackForStartSendRtpStream{
@@ -99,90 +111,107 @@
 
     @Override
     public void onMessage(Message message, byte[] bytes) {
-        JSONObject msgJSON = JSON.parseObject(message.getBody(), JSONObject.class);
-        WvpRedisMsg wvpRedisMsg = JSON.toJavaObject(msgJSON, WvpRedisMsg.class);
-        if (!userSetting.getServerId().equals(wvpRedisMsg.getToId())) {
-            return;
-        }
-        if (WvpRedisMsg.isRequest(wvpRedisMsg)) {
-            logger.info("[鏀跺埌REDIS閫氱煡] 璇锋眰锛� {}", new String(message.getBody()));
 
-            switch (wvpRedisMsg.getCmd()){
-                case WvpRedisMsgCmd.GET_SEND_ITEM:
-                    RequestSendItemMsg content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestSendItemMsg.class);
-                    requestSendItemMsgHand(content, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial());
-                    break;
-                case WvpRedisMsgCmd.REQUEST_PUSH_STREAM:
-                    RequestPushStreamMsg param = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestPushStreamMsg.class);;
-                    requestPushStreamMsgHand(param, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial());
-                    break;
-                default:
-                    break;
-            }
-
-        }else {
-            logger.info("[鏀跺埌REDIS閫氱煡] 鍥炲锛� {}", new String(message.getBody()));
-            switch (wvpRedisMsg.getCmd()){
-                case WvpRedisMsgCmd.GET_SEND_ITEM:
-
-                    WVPResult content  = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class);
-
-                    String key = wvpRedisMsg.getSerial();
-                    switch (content.getCode()) {
-                        case 0:
-                            ResponseSendItemMsg responseSendItemMsg =JSON.toJavaObject((JSONObject)content.getData(), ResponseSendItemMsg.class);
-                            PlayMsgCallback playMsgCallback = callbacks.get(key);
-                            if (playMsgCallback != null) {
-                                callbacksForError.remove(key);
-                                playMsgCallback.handler(responseSendItemMsg);
-                            }
-                            break;
-                        case ERROR_CODE_MEDIA_SERVER_NOT_FOUND:
-                        case ERROR_CODE_OFFLINE:
-                        case ERROR_CODE_TIMEOUT:
-                            PlayMsgErrorCallback errorCallback = callbacksForError.get(key);
-                            if (errorCallback != null) {
-                                callbacks.remove(key);
-                                errorCallback.handler(content);
-                            }
-                            break;
-                        default:
-                            break;
+        taskQueue.offer(message);
+        if (!taskQueueHandlerRun) {
+            taskQueueHandlerRun = true;
+            taskExecutor.execute(() -> {
+                while (!taskQueue.isEmpty()) {
+                    Message msg = taskQueue.poll();
+                    JSONObject msgJSON = JSON.parseObject(msg.getBody(), JSONObject.class);
+                    WvpRedisMsg wvpRedisMsg = JSON.toJavaObject(msgJSON, WvpRedisMsg.class);
+                    if (!userSetting.getServerId().equals(wvpRedisMsg.getToId())) {
+                        continue;
                     }
-                    break;
-                case WvpRedisMsgCmd.REQUEST_PUSH_STREAM:
-                    WVPResult wvpResult  = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class);
-                    String serial = wvpRedisMsg.getSerial();
-                    switch (wvpResult.getCode()) {
-                        case 0:
-                            JSONObject jsonObject = (JSONObject)wvpResult.getData();
-                            PlayMsgCallbackForStartSendRtpStream playMsgCallback = callbacksForStartSendRtpStream.get(serial);
-                            if (playMsgCallback != null) {
-                                callbacksForError.remove(serial);
-                                playMsgCallback.handler(jsonObject);
-                            }
-                            break;
-                        case ERROR_CODE_MEDIA_SERVER_NOT_FOUND:
-                        case ERROR_CODE_OFFLINE:
-                        case ERROR_CODE_TIMEOUT:
-                            PlayMsgErrorCallback errorCallback = callbacksForError.get(serial);
-                            if (errorCallback != null) {
-                                callbacks.remove(serial);
-                                errorCallback.handler(wvpResult);
-                            }
-                            break;
-                        default:
-                            break;
+                    if (WvpRedisMsg.isRequest(wvpRedisMsg)) {
+                        logger.info("[鏀跺埌REDIS閫氱煡] 璇锋眰锛� {}", new String(msg.getBody()));
+
+                        switch (wvpRedisMsg.getCmd()){
+                            case WvpRedisMsgCmd.GET_SEND_ITEM:
+                                RequestSendItemMsg content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestSendItemMsg.class);
+                                requestSendItemMsgHand(content, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial());
+                                break;
+                            case WvpRedisMsgCmd.REQUEST_PUSH_STREAM:
+                                RequestPushStreamMsg param = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestPushStreamMsg.class);;
+                                requestPushStreamMsgHand(param, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial());
+                                break;
+                            default:
+                                break;
+                        }
+
+                    }else {
+                        logger.info("[鏀跺埌REDIS閫氱煡] 鍥炲锛� {}", new String(msg.getBody()));
+                        switch (wvpRedisMsg.getCmd()){
+                            case WvpRedisMsgCmd.GET_SEND_ITEM:
+
+                                WVPResult content  = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class);
+
+                                String key = wvpRedisMsg.getSerial();
+                                switch (content.getCode()) {
+                                    case 0:
+                                        ResponseSendItemMsg responseSendItemMsg =JSON.toJavaObject((JSONObject)content.getData(), ResponseSendItemMsg.class);
+                                        PlayMsgCallback playMsgCallback = callbacks.get(key);
+                                        if (playMsgCallback != null) {
+                                            callbacksForError.remove(key);
+                                            try {
+                                                playMsgCallback.handler(responseSendItemMsg);
+                                            } catch (ParseException e) {
+                                                throw new RuntimeException(e);
+                                            }
+                                        }
+                                        break;
+                                    case ERROR_CODE_MEDIA_SERVER_NOT_FOUND:
+                                    case ERROR_CODE_OFFLINE:
+                                    case ERROR_CODE_TIMEOUT:
+                                        PlayMsgErrorCallback errorCallback = callbacksForError.get(key);
+                                        if (errorCallback != null) {
+                                            callbacks.remove(key);
+                                            errorCallback.handler(content);
+                                        }
+                                        break;
+                                    default:
+                                        break;
+                                }
+                                break;
+                            case WvpRedisMsgCmd.REQUEST_PUSH_STREAM:
+                                WVPResult wvpResult  = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class);
+                                String serial = wvpRedisMsg.getSerial();
+                                switch (wvpResult.getCode()) {
+                                    case 0:
+                                        JSONObject jsonObject = (JSONObject)wvpResult.getData();
+                                        PlayMsgCallbackForStartSendRtpStream playMsgCallback = callbacksForStartSendRtpStream.get(serial);
+                                        if (playMsgCallback != null) {
+                                            callbacksForError.remove(serial);
+                                            playMsgCallback.handler(jsonObject);
+                                        }
+                                        break;
+                                    case ERROR_CODE_MEDIA_SERVER_NOT_FOUND:
+                                    case ERROR_CODE_OFFLINE:
+                                    case ERROR_CODE_TIMEOUT:
+                                        PlayMsgErrorCallback errorCallback = callbacksForError.get(serial);
+                                        if (errorCallback != null) {
+                                            callbacks.remove(serial);
+                                            errorCallback.handler(wvpResult);
+                                        }
+                                        break;
+                                    default:
+                                        break;
+                                }
+                                break;
+                            default:
+                                break;
+                        }
                     }
-                    break;
-                default:
-                    break;
-            }
+                }
+                taskQueueHandlerRun = false;
+            });
         }
 
 
 
 
+
+
     }
 
     /**
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisGpsMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGpsMsgListener.java
similarity index 92%
rename from src/main/java/com/genersoft/iot/vmp/service/impl/RedisGpsMsgListener.java
rename to src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGpsMsgListener.java
index 4e94d68..b5d02a5 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisGpsMsgListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGpsMsgListener.java
@@ -1,7 +1,6 @@
-package com.genersoft.iot.vmp.service.impl;
+package com.genersoft.iot.vmp.service.redisMsg;
 
 import com.alibaba.fastjson.JSON;
-import com.genersoft.iot.vmp.gb28181.bean.HandlerCatchData;
 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
@@ -36,7 +35,7 @@
     @Autowired
     private IVideoManagerStorage storager;
 
-    private final ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
+    private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
 
     @Qualifier("taskExecutor")
     @Autowired
diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamResponseListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamResponseListener.java
new file mode 100644
index 0000000..4fff32d
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamResponseListener.java
@@ -0,0 +1,75 @@
+package com.genersoft.iot.vmp.service.redisMsg;
+
+import com.alibaba.fastjson.JSON;
+import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
+import com.genersoft.iot.vmp.service.bean.MessageForPushChannelResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.connection.Message;
+import org.springframework.data.redis.connection.MessageListener;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/**
+ * 鎺ユ敹redis杩斿洖鐨勬帹娴佺粨鏋�
+ * @author lin
+ */
+@Component
+public class RedisPushStreamResponseListener implements MessageListener {
+
+    private final static Logger logger = LoggerFactory.getLogger(RedisPushStreamResponseListener.class);
+
+    private boolean taskQueueHandlerRun = false;
+
+    private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
+
+    @Qualifier("taskExecutor")
+    @Autowired
+    private ThreadPoolTaskExecutor taskExecutor;
+
+
+    private Map<String, PushStreamResponseEvent> responseEvents = new ConcurrentHashMap<>();
+
+    public interface PushStreamResponseEvent{
+        void run(MessageForPushChannelResponse response);
+    }
+
+    @Override
+    public void onMessage(Message message, byte[] bytes) {
+        logger.warn("[REDIS娑堟伅-璇锋眰鎺ㄦ祦缁撴灉]锛� {}", new String(message.getBody()));
+        taskQueue.offer(message);
+        if (!taskQueueHandlerRun) {
+            taskQueueHandlerRun = true;
+            taskExecutor.execute(() -> {
+                while (!taskQueue.isEmpty()) {
+                    Message msg = taskQueue.poll();
+                    MessageForPushChannelResponse response = JSON.parseObject(new String(msg.getBody()), MessageForPushChannelResponse.class);
+                    if (response == null || ObjectUtils.isEmpty(response.getApp()) || ObjectUtils.isEmpty(response.getStream())){
+                        logger.info("[REDIS娑堟伅-璇锋眰鎺ㄦ祦缁撴灉]锛氬弬鏁颁笉鍏�");
+                        continue;
+                    }
+                    // 鏌ョ湅姝e湪绛夊緟鐨刬nvite娑堟伅
+                    if (responseEvents.get(response.getApp() + response.getStream()) != null) {
+                        responseEvents.get(response.getApp() + response.getStream()).run(response);
+                    }
+                }
+                taskQueueHandlerRun = false;
+            });
+        }
+    }
+
+    public void addEvent(String app, String stream, PushStreamResponseEvent callback) {
+        responseEvents.put(app + stream, callback);
+    }
+
+    public void removeEvent(String app, String stream) {
+        responseEvents.remove(app + stream);
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java
new file mode 100644
index 0000000..b69a587
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java
@@ -0,0 +1,103 @@
+package com.genersoft.iot.vmp.service.redisMsg;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
+import com.genersoft.iot.vmp.service.IGbStreamService;
+import com.genersoft.iot.vmp.service.IMediaServerService;
+import com.genersoft.iot.vmp.service.IStreamPushService;
+import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
+import com.genersoft.iot.vmp.utils.DateUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.connection.Message;
+import org.springframework.data.redis.connection.MessageListener;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/**
+ * @Auther: JiangFeng
+ * @Date: 2022/8/16 11:32
+ * @Description: 鎺ユ敹redis鍙戦�佺殑鎺ㄦ祦璁惧鍒楄〃鏇存柊閫氱煡
+ */
+@Component
+public class RedisPushStreamStatusListMsgListener implements MessageListener {
+
+    private final static Logger logger = LoggerFactory.getLogger(RedisPushStreamStatusListMsgListener.class);
+    @Resource
+    private IMediaServerService mediaServerService;
+
+    @Resource
+    private IStreamPushService streamPushService;
+    @Resource
+    private IGbStreamService gbStreamService;
+
+    private boolean taskQueueHandlerRun = false;
+
+    private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
+
+    @Qualifier("taskExecutor")
+    @Autowired
+    private ThreadPoolTaskExecutor taskExecutor;
+
+    @Override
+    public void onMessage(Message message, byte[] bytes) {
+        logger.info("[REDIS娑堟伅-鎺ㄦ祦璁惧鍒楄〃鏇存柊]锛� {}", new String(message.getBody()));
+
+        taskQueue.offer(message);
+        if (!taskQueueHandlerRun) {
+            taskQueueHandlerRun = true;
+            taskExecutor.execute(() -> {
+                while (!taskQueue.isEmpty()) {
+                    Message msg = taskQueue.poll();
+                    List<StreamPushItem> streamPushItems = JSON.parseArray(new String(msg.getBody()), StreamPushItem.class);
+                    //鏌ヨ鍏ㄩ儴鐨刟pp+stream 鐢ㄤ簬鍒ゆ柇鏄坊鍔犺繕鏄慨鏀�
+                    List<String> allAppAndStream = streamPushService.getAllAppAndStream();
+
+                    /**
+                     * 鐢ㄤ簬瀛樺偍鏇村叿APP+Stream杩囨护鍚庣殑鏁版嵁锛屽彲浠ョ洿鎺ュ瓨鍏tream_push琛ㄤ笌gb_stream琛�
+                     */
+                    List<StreamPushItem> streamPushItemForSave = new ArrayList<>();
+                    List<StreamPushItem> streamPushItemForUpdate = new ArrayList<>();
+                    for (StreamPushItem streamPushItem : streamPushItems) {
+                        String app = streamPushItem.getApp();
+                        String stream = streamPushItem.getStream();
+                        boolean contains = allAppAndStream.contains(app + stream);
+                        //涓嶅瓨鍦ㄥ氨娣诲姞
+                        if (!contains) {
+                            streamPushItem.setStreamType("push");
+                            streamPushItem.setCreateTime(DateUtil.getNow());
+                            streamPushItem.setMediaServerId(mediaServerService.getDefaultMediaServer().getId());
+                            streamPushItem.setOriginType(2);
+                            streamPushItem.setOriginTypeStr("rtsp_push");
+                            streamPushItem.setTotalReaderCount("0");
+                            streamPushItemForSave.add(streamPushItem);
+                        } else {
+                            //瀛樺湪灏卞彧淇敼 name鍜実bId
+                            streamPushItemForUpdate.add(streamPushItem);
+                        }
+                    }
+                    if (streamPushItemForSave.size() > 0) {
+
+                        logger.info("娣诲姞{}鏉�",streamPushItemForSave.size());
+                        logger.info(JSONObject.toJSONString(streamPushItemForSave));
+                        streamPushService.batchAdd(streamPushItemForSave);
+
+                    }
+                    if(streamPushItemForUpdate.size()>0){
+                        logger.info("淇敼{}鏉�",streamPushItemForUpdate.size());
+                        logger.info(JSONObject.toJSONString(streamPushItemForUpdate));
+                        gbStreamService.updateGbIdOrName(streamPushItemForUpdate);
+                    }
+                }
+                taskQueueHandlerRun = false;
+            });
+        }
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamStatusMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusMsgListener.java
similarity index 79%
rename from src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamStatusMsgListener.java
rename to src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusMsgListener.java
index 50e894a..2faf3b8 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamStatusMsgListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusMsgListener.java
@@ -1,24 +1,11 @@
-package com.genersoft.iot.vmp.service.impl;
+package com.genersoft.iot.vmp.service.redisMsg;
 
 import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
 import com.genersoft.iot.vmp.common.VideoManagerConstants;
 import com.genersoft.iot.vmp.conf.DynamicTask;
-import com.genersoft.iot.vmp.conf.UserSetting;
-import com.genersoft.iot.vmp.gb28181.bean.GbStream;
-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.ISIPCommander;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
-import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager;
-import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
-import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
 import com.genersoft.iot.vmp.service.IStreamPushService;
-import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
 import com.genersoft.iot.vmp.service.bean.PushStreamStatusChangeFromRedisDto;
-import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
-import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -30,8 +17,6 @@
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Component;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.concurrent.ConcurrentLinkedQueue;
 
 
@@ -57,7 +42,7 @@
 
 
 
-    private final ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
+    private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
 
     @Qualifier("taskExecutor")
     @Autowired
@@ -65,7 +50,6 @@
 
     @Override
     public void onMessage(Message message, byte[] bytes) {
-        // TODO 澧炲姞闃熷垪
         logger.warn("[REDIS娑堟伅-鎺ㄦ祦璁惧鐘舵�佸彉鍖朷锛� {}", new String(message.getBody()));
         taskQueue.offer(message);
 
@@ -77,7 +61,7 @@
                     PushStreamStatusChangeFromRedisDto statusChangeFromPushStream = JSON.parseObject(msg.getBody(), PushStreamStatusChangeFromRedisDto.class);
                     if (statusChangeFromPushStream == null) {
                         logger.warn("[REDIS娑堟伅]鎺ㄦ祦璁惧鐘舵�佸彉鍖栨秷鎭В鏋愬け璐�");
-                        return;
+                        continue;
                     }
                     // 鍙栨秷瀹氭椂浠诲姟
                     dynamicTask.stop(VideoManagerConstants.VM_MSG_GET_ALL_ONLINE_REQUESTED);
diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java
new file mode 100644
index 0000000..415787e
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java
@@ -0,0 +1,91 @@
+package com.genersoft.iot.vmp.service.redisMsg;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.conf.UserSetting;
+
+import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.connection.Message;
+import org.springframework.data.redis.connection.MessageListener;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+
+/**
+ * 鎺ユ敹鍏朵粬wvp鍙戦�佹祦鍙樺寲閫氱煡
+ * @author lin
+ */
+@Component
+public class RedisStreamMsgListener implements MessageListener {
+
+    private final static Logger logger = LoggerFactory.getLogger(RedisStreamMsgListener.class);
+
+    @Autowired
+    private UserSetting userSetting;
+
+    @Autowired
+    private ZLMMediaListManager zlmMediaListManager;
+
+    private boolean taskQueueHandlerRun = false;
+
+    private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
+
+    @Qualifier("taskExecutor")
+    @Autowired
+    private ThreadPoolTaskExecutor taskExecutor;
+
+    @Override
+    public void onMessage(Message message, byte[] bytes) {
+
+        taskQueue.offer(message);
+        if (!taskQueueHandlerRun) {
+            taskQueueHandlerRun = true;
+            taskExecutor.execute(() -> {
+                while (!taskQueue.isEmpty()) {
+                    Message msg = taskQueue.poll();
+                    JSONObject steamMsgJson = JSON.parseObject(msg.getBody(), JSONObject.class);
+                    if (steamMsgJson == null) {
+                        logger.warn("[鏀跺埌redis 娴佸彉鍖朷娑堟伅瑙f瀽澶辫触");
+                        continue;
+                    }
+                    String serverId = steamMsgJson.getString("serverId");
+
+                    if (userSetting.getServerId().equals(serverId)) {
+                        // 鑷繁鍙戦�佺殑娑堟伅蹇界暐鍗冲彲
+                        continue;
+                    }
+                    logger.info("[鏀跺埌redis 娴佸彉鍖朷锛� {}", new String(message.getBody()));
+                    String app = steamMsgJson.getString("app");
+                    String stream = steamMsgJson.getString("stream");
+                    boolean register = steamMsgJson.getBoolean("register");
+                    String mediaServerId = steamMsgJson.getString("mediaServerId");
+                    MediaItem mediaItem = new MediaItem();
+                    mediaItem.setSeverId(serverId);
+                    mediaItem.setApp(app);
+                    mediaItem.setStream(stream);
+                    mediaItem.setRegist(register);
+                    mediaItem.setMediaServerId(mediaServerId);
+                    mediaItem.setCreateStamp(System.currentTimeMillis()/1000);
+                    mediaItem.setAliveSecond(0L);
+                    mediaItem.setTotalReaderCount("0");
+                    mediaItem.setOriginType(0);
+                    mediaItem.setOriginTypeStr("0");
+                    mediaItem.setOriginTypeStr("unknown");
+                    if (register) {
+                        zlmMediaListManager.addPush(mediaItem);
+                    }else {
+                        zlmMediaListManager.removeMedia(app, stream);
+                    }
+                }
+                taskQueueHandlerRun = false;
+            });
+        }
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
index 5e74d99..8a5d455 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
@@ -75,18 +75,23 @@
             "WHERE gs.gbId = '${gbId}' AND pgs.platformId = '${platformId}'")
     GbStream queryStreamInPlatform(String platformId, String gbId);
 
-    @Select("select gt.gbId as channelId, gt.name, 'wvp-pro' as manufacture,  st.status, gt.longitude, gt.latitude, pc.id as parentId," +
+    @Select("<script> "+
+            "select gt.gbId as channelId, gt.name, 'wvp-pro' as manufacture,  st.status, gt.longitude, gt.latitude, pc.id as parentId," +
             "       '1' as registerWay, pc.civilCode, 'live' as model, 'wvp-pro' as owner, '0' as parental,'0' as secrecy" +
             " from gb_stream gt " +
             " left join (" +
-            "    select sp.status, sp.app, sp.stream from stream_push sp" +
+            "    select " +
+            " <if test='usPushingAsStatus != true'> sp.status as status, </if>" +
+            " <if test='usPushingAsStatus == true'> sp.pushIng as status, </if>" +
+            "sp.app, sp.stream from stream_push sp" +
             "    union all" +
             "    select spxy.status, spxy.app, spxy.stream from stream_proxy spxy" +
             " ) st on st.app = gt.app and st.stream = gt.stream" +
             " left join platform_gb_stream pgs on  gt.gbStreamId = pgs.gbStreamId" +
             " left join platform_catalog pc on pgs.catalogId = pc.id and pgs.platformId = pc.platformId" +
-            " where pgs.platformId=#{platformId}")
-    List<DeviceChannel> queryGbStreamListInPlatform(String platformId);
+            " where pgs.platformId=#{platformId}" +
+            "</script>")
+    List<DeviceChannel> queryGbStreamListInPlatform(String platformId, boolean usPushingAsStatus);
 
 
     @Select("SELECT gs.* FROM gb_stream gs LEFT JOIN platform_gb_stream pgs " +
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 9d30fef..258b956 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
@@ -710,14 +710,14 @@
     @Override
     public void sendMobilePositionMsg(JSONObject jsonObject) {
         String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_MOBILE_POSITION;
-        logger.info("[redis鍙戦�侀�氱煡]绉诲姩浣嶇疆 {}: {}", key, jsonObject.toString());
+        logger.info("[redis鍙戦�侀�氱煡] 绉诲姩浣嶇疆 {}: {}", key, jsonObject.toString());
         RedisUtil.convertAndSend(key, jsonObject);
     }
 
     @Override
     public void sendStreamPushRequestedMsg(MessageForPushChannel msg) {
         String key = VideoManagerConstants.VM_MSG_STREAM_PUSH_REQUESTED;
-        logger.info("[redis鍙戦�侀�氱煡]鎺ㄦ祦琚姹� {}: {}/{}", key, msg.getApp(), msg.getStream());
+        logger.info("[redis鍙戦�侀�氱煡] 鎺ㄦ祦琚姹� {}: {}/{}", key, msg.getApp(), msg.getStream());
         RedisUtil.convertAndSend(key, (JSONObject)JSON.toJSON(msg));
     }
 
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 702b5be..f8a74fe 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
@@ -2,6 +2,7 @@
 
 import com.genersoft.iot.vmp.common.StreamInfo;
 import com.genersoft.iot.vmp.conf.SipConfig;
+import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.gb28181.bean.*;
 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
@@ -82,6 +83,9 @@
 
 	@Autowired
     private GbStreamMapper gbStreamMapper;
+
+	@Autowired
+    private UserSetting userSetting;
 
 	@Autowired
     private PlatformCatalogMapper catalogMapper;
@@ -614,7 +618,7 @@
 	 */
 	@Override
 	public List<DeviceChannel> queryGbStreamListInPlatform(String platformId) {
-		return gbStreamMapper.queryGbStreamListInPlatform(platformId);
+		return gbStreamMapper.queryGbStreamListInPlatform(platformId, userSetting.isUsePushingAsStatus());
 	}
 
 	/**
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
index 9c7d203..eb79fc7 100644
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
@@ -413,24 +413,20 @@
 	@GetMapping("/{deviceId}/subscribe_info")
 	@Operation(summary = "鑾峰彇璁惧鐨勮闃呯姸鎬�")
 	@Parameter(name = "deviceId", description = "璁惧鍥芥爣缂栧彿", required = true)
-	public WVPResult<Map<String, String>> getSubscribeInfo(@PathVariable String deviceId) {
+	public WVPResult<Map<String, Integer>> getSubscribeInfo(@PathVariable String deviceId) {
 		Set<String> allKeys = dynamicTask.getAllKeys();
-		Map<String, String> dialogStateMap = new HashMap<>();
+		Map<String, Integer> dialogStateMap = new HashMap<>();
 		for (String key : allKeys) {
 			if (key.startsWith(deviceId)) {
 				ISubscribeTask subscribeTask = (ISubscribeTask)dynamicTask.get(key);
-				DialogState dialogState = subscribeTask.getDialogState();
-				if (dialogState == null) {
-					continue;
-				}
 				if (subscribeTask instanceof CatalogSubscribeTask) {
-					dialogStateMap.put("catalog", dialogState.toString());
+					dialogStateMap.put("catalog", 1);
 				}else if (subscribeTask instanceof MobilePositionSubscribeTask) {
-					dialogStateMap.put("mobilePosition", dialogState.toString());
+					dialogStateMap.put("mobilePosition", 1);
 				}
 			}
 		}
-		WVPResult<Map<String, String>> wvpResult = new WVPResult<>();
+		WVPResult<Map<String, Integer>> wvpResult = new WVPResult<>();
 		wvpResult.setCode(0);
 		wvpResult.setData(dialogStateMap);
 		return wvpResult;
diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml
index 3569de2..ed025b9 100644
--- a/src/main/resources/all-application.yml
+++ b/src/main/resources/all-application.yml
@@ -188,6 +188,8 @@
     record-sip: true
     # 鏄惁灏嗘棩蹇楀瓨鍌ㄨ繘鏁版嵁搴�
     logInDatebase: true
+    # 浣跨敤鎺ㄦ祦鐘舵�佷綔涓烘帹娴侀�氶亾鐘舵��
+    use-pushing-as-status: true
 
 # 鍏抽棴鍦ㄧ嚎鏂囨。锛堢敓浜х幆澧冨缓璁叧闂級
 springdoc:
diff --git a/web_src/src/components/dialog/devicePlayer.vue b/web_src/src/components/dialog/devicePlayer.vue
index fac02fd..ee5fd7b 100644
--- a/web_src/src/components/dialog/devicePlayer.vue
+++ b/web_src/src/components/dialog/devicePlayer.vue
@@ -411,6 +411,9 @@
             console.log(this.videoUrl)
         },
         openDialog: function (tab, deviceId, channelId, param) {
+            if (this.showVideoDialog) {
+              return;
+            }
             this.tabActiveName = tab;
             this.channelId = channelId;
             this.deviceId = deviceId;
diff --git a/web_src/src/components/dialog/recordDownload.vue b/web_src/src/components/dialog/recordDownload.vue
index b718a8b..b0b8fea 100644
--- a/web_src/src/components/dialog/recordDownload.vue
+++ b/web_src/src/components/dialog/recordDownload.vue
@@ -84,12 +84,13 @@
             method: 'get',
             url: `/api/gb_record/download/progress/${this.deviceId}/${this.channelId}/${this.stream}`
           }).then((res)=> {
+            console.log(res)
               if (res.data.code === 0) {
                 this.streamInfo = res.data.data;
                 if (parseFloat(res.data.progress) == 1) {
                   this.percentage = 100;
                 }else {
-                  this.percentage = (res.data.progress*100).toFixed(1);
+                  this.percentage = (parseFloat(res.data.data.progress)*100).toFixed(1);
                 }
                 if (callback)callback();
               }
@@ -175,6 +176,10 @@
           }).then((res) => {
             console.log(res)
             if (res.data.code === 0) {
+              if (res.data.data.length === 0){
+                this.percentage = 0
+                return
+              }
                 this.percentage = parseFloat(res.data.data.percentage)*100
                  if (res.data.data[0].percentage === '1') {
                    this.getProgressForFileRun = false;

--
Gitblit v1.8.0