From f2279859b367fda6108a5ea22c572d38d89d338d Mon Sep 17 00:00:00 2001
From: panlinlin <648540858@qq.com>
Date: 星期六, 26 十二月 2020 16:44:27 +0800
Subject: [PATCH] 增加对水星IPC的兼容 增加对SIP错误的订阅,刷新通道或点播或回放出现sip错误时及时返回给页面 优化UI,增加按钮loading

---
 src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java                          |   13 +++
 src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java                            |   37 +++++++++
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java                |   65 ++++++++++-----
 web_src/src/components/videoList.vue                                                           |   36 ++++++--
 src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java                  |    7 +
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java                    |    7 +
 src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java                                      |   19 ++++
 src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java                     |    2 
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java                         |    2 
 src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java                      |   23 +++++
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java                  |    8 +
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java |    2 
 src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java                               |    1 
 13 files changed, 176 insertions(+), 46 deletions(-)

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 f1ed477..92ba204 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
@@ -8,8 +8,10 @@
 import java.util.concurrent.TimeUnit;
 
 import javax.sip.*;
+import javax.sip.header.CallIdHeader;
 import javax.sip.message.Response;
 
+import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,6 +35,9 @@
 
 	@Autowired
 	private SIPProcessorFactory processorFactory;
+
+	@Autowired
+	private SipSubscribe sipSubscribe;
 
 	private SipStack sipStack;
 
@@ -139,11 +144,19 @@
 			// 澧炲姞鍏跺畠鏃犻渶鍥炲鐨勫搷搴旓紝濡�101銆�180绛�
 		} else {
 			logger.warn("鎺ユ敹鍒板け璐ョ殑response鍝嶅簲锛乻tatus锛�" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/);
+			if (evt.getResponse() != null && sipSubscribe.getSize() > 0 ) {
+				CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME);
+				if (callIdHeader != null) {
+					SipSubscribe.Event subscribe = sipSubscribe.getSubscribe(callIdHeader.getCallId());
+					if (subscribe != null) {
+						subscribe.response(evt);
+					}
+				}
+			}
 		}
-		// trying涓嶄細鍥炲
-		// if (status == Response.TRYING) {
 
-		// }
+
+
 	}
 
 	/**
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java
index 6e4588d..6fe63cc 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java
@@ -21,6 +21,6 @@
 		// TODO 鍚庣画澶勭悊锛屽彧鏈夌涓�娆℃敞鍐屾椂璋冪敤鏌ヨ璁惧淇℃伅锛屽闇�鏇存柊璋冪敤鏇存柊API鎺ュ彛
 		cmder.deviceInfoQuery(device);
 		
-		cmder.catalogQuery(device);
+		cmder.catalogQuery(device, null);
 	}
 }
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
new file mode 100644
index 0000000..1f78df4
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
@@ -0,0 +1,37 @@
+package com.genersoft.iot.vmp.gb28181.event;
+
+import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import javax.sip.ResponseEvent;
+import javax.sip.message.Request;
+import java.util.EventObject;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Component
+public class SipSubscribe {
+
+    private final static Logger logger = LoggerFactory.getLogger(SipSubscribe.class);
+
+    private Map<String, SipSubscribe.Event> allSubscribes = new ConcurrentHashMap<>();
+
+    public interface Event {
+        void response(ResponseEvent event);
+    }
+
+    public void addSubscribe(String key, SipSubscribe.Event event) {
+        allSubscribes.put(key, event);
+    }
+
+    public SipSubscribe.Event getSubscribe(String key) {
+        return allSubscribes.get(key);
+    }
+
+    public int getSize(){
+        return allSubscribes.size();
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
index 73fb474..d37259a 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
@@ -4,10 +4,13 @@
 import javax.sip.ResponseEvent;
 import javax.sip.SipProvider;
 import javax.sip.header.CSeqHeader;
+import javax.sip.header.CallIdHeader;
+import javax.sip.header.Header;
 import javax.sip.message.Request;
 import javax.sip.message.Response;
 
 import com.alibaba.fastjson.JSON;
+import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -83,7 +86,8 @@
 	
 	@Autowired
 	private OtherResponseProcessor otherResponseProcessor;
-	
+
+
 	// 娉細杩欓噷浣跨敤娉ㄨВ浼氬鑷村惊鐜緷璧栨敞鍏ワ紝鏆傜敤springBean
 	private SipProvider tcpSipProvider;
 		
@@ -94,6 +98,7 @@
 		Request request = evt.getRequest();
 		String method = request.getMethod();
 //		logger.info("鎺ユ敹鍒版秷鎭細"+request.getMethod());
+//		sipSubscribe.getSubscribe(evt.getServerTransaction().getBranchId()).response(evt);
 		if (Request.INVITE.equals(method)) {
 			InviteRequestProcessor processor = new InviteRequestProcessor();
 			processor.setRequestEvent(evt);
@@ -145,6 +150,7 @@
 	}
 	
 	public ISIPResponseProcessor createResponseProcessor(ResponseEvent evt) {
+
 		Response response = evt.getResponse();
 		CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
 		String method = cseqHeader.getMethod();
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 46e5945..732b2cd 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
@@ -2,6 +2,7 @@
 
 import com.genersoft.iot.vmp.common.StreamInfo;
 import com.genersoft.iot.vmp.gb28181.bean.Device;
+import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
 
 /**    
@@ -83,7 +84,7 @@
 	 * @param device  瑙嗛璁惧
 	 * @param channelId  棰勮閫氶亾
 	 */
-	void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event);
+	void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
 	
 	/**
 	 * 璇锋眰鍥炴斁瑙嗛娴�
@@ -93,7 +94,7 @@
 	 * @param startTime 寮�濮嬫椂闂�,鏍煎紡瑕佹眰锛歽yyy-MM-dd HH:mm:ss
 	 * @param endTime 缁撴潫鏃堕棿,鏍煎紡瑕佹眰锛歽yyy-MM-dd HH:mm:ss
 	 */
-	void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event);
+	void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
 	
 	/**
 	 * 瑙嗛娴佸仠姝�
@@ -175,7 +176,7 @@
 	 * 
 	 * @param device 瑙嗛璁惧
 	 */
-	boolean catalogQuery(Device device);
+	boolean catalogQuery(Device device, SipSubscribe.Event errorEvent);
 	
 	/**
 	 * 鏌ヨ褰曞儚淇℃伅
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 7d91d7b..61ed270 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
@@ -4,22 +4,22 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import javax.sip.ClientTransaction;
-import javax.sip.Dialog;
-import javax.sip.InvalidArgumentException;
-import javax.sip.SipException;
-import javax.sip.SipProvider;
-import javax.sip.TransactionDoesNotExistException;
+import javax.sip.*;
 import javax.sip.address.SipURI;
+import javax.sip.header.CallIdHeader;
+import javax.sip.header.Header;
 import javax.sip.header.ViaHeader;
 import javax.sip.message.Request;
 
 import com.alibaba.fastjson.JSONObject;
 import com.genersoft.iot.vmp.conf.MediaServerConfig;
 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
+import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
+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.beans.factory.annotation.Value;
@@ -39,6 +39,8 @@
  */
 @Component
 public class SIPCommander implements ISIPCommander {
+
+	private final Logger logger = LoggerFactory.getLogger(SIPCommander.class);
 	
 	@Autowired
 	private SipConfig sipConfig;
@@ -68,6 +70,9 @@
 
 	@Autowired
 	private ZLMHttpHookSubscribe subscribe;
+
+	@Autowired
+	private SipSubscribe sipSubscribe;
 
 
 
@@ -221,7 +226,7 @@
 			
 			Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag");
 			
-			transmitRequest(device, request);
+			transmitRequest(device, request, null);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
 			e.printStackTrace();
@@ -256,22 +261,23 @@
 			ptzXml.append("</Control>\r\n");
 			
 			Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag");
-			
-			transmitRequest(device, request);
+			transmitRequest(device, request, null);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
 			e.printStackTrace();
 		} 
 		return false;
 	}
+
 	/**
-	 * 璇锋眰棰勮瑙嗛娴�
-	 *
+	 * 	璇锋眰棰勮瑙嗛娴�
 	 * @param device  瑙嗛璁惧
 	 * @param channelId  棰勮閫氶亾
+	 * @param event hook璁㈤槄
+	 * @param errorEvent sip閿欒璁㈤槄
 	 */
 	@Override
-	public void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event) {
+	public void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) {
 		try {
 
 			String ssrc = streamSession.createPlaySsrc();
@@ -300,7 +306,8 @@
 			//
 			StringBuffer content = new StringBuffer(200);
 			content.append("v=0\r\n");
-			content.append("o="+channelId+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");
+//			content.append("o="+channelId+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");
+			content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");
 			content.append("s=Play\r\n");
 			content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n");
 			content.append("t=0 0\r\n");
@@ -332,7 +339,7 @@
 
 			Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "live", null, ssrc);
 
-			ClientTransaction transaction = transmitRequest(device, request);
+			ClientTransaction transaction = transmitRequest(device, request, errorEvent);
 			streamSession.put(streamId, transaction);
 			DeviceChannel deviceChannel = storager.queryChannel(device.getDeviceId(), channelId);
 			if (deviceChannel != null) {
@@ -357,7 +364,8 @@
 	 * @param endTime 缁撴潫鏃堕棿,鏍煎紡瑕佹眰锛歽yyy-MM-dd HH:mm:ss
 	 */ 
 	@Override
-	public void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event) {
+	public void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event
+			, SipSubscribe.Event errorEvent) {
 		try {
 			MediaServerConfig mediaInfo = storager.getMediaInfo();
 			String ssrc = streamSession.createPlayBackSsrc();
@@ -413,8 +421,8 @@
 	        content.append("y="+ssrc+"\r\n");//ssrc
 	        
 	        Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "playback", null);
-	
-	        ClientTransaction transaction = transmitRequest(device, request);
+
+	        ClientTransaction transaction = transmitRequest(device, request, errorEvent);
 	        streamSession.put(streamId, transaction);
 
 		} catch ( SipException | ParseException | InvalidArgumentException e) {
@@ -575,7 +583,8 @@
 			catalogXml.append("</Query>\r\n");
 			
 			Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaDeviceInfoBranch", "FromDeviceInfoTag", "ToDeviceInfoTag");
-			transmitRequest(device, request);
+
+			transmitRequest(device, request, null);
 			
 		} catch (SipException | ParseException | InvalidArgumentException e) {
 			e.printStackTrace();
@@ -590,7 +599,7 @@
 	 * @param device 瑙嗛璁惧
 	 */ 
 	@Override
-	public boolean catalogQuery(Device device) {
+	public boolean catalogQuery(Device device, SipSubscribe.Event errorEvent) {
 		// 娓呯┖閫氶亾
 		storager.cleanChannelsForDevice(device.getDeviceId());
 		try {
@@ -602,8 +611,9 @@
 			catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
 			catalogXml.append("</Query>\r\n");
 			
-			Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaCatalogBranch", "FromCatalogTag", "ToCatalogTag");
-			transmitRequest(device, request);
+			Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaCatalogBranch", "FromCatalogTag", null);
+
+			transmitRequest(device, request, errorEvent);
 		} catch (SipException | ParseException | InvalidArgumentException e) {
 			e.printStackTrace();
 			return false;
@@ -636,7 +646,9 @@
 			recordInfoXml.append("</Query>\r\n");
 			
 			Request request = headerProvider.createMessageRequest(device, recordInfoXml.toString(), "ViaRecordInfoBranch", "FromRecordInfoTag", "ToRecordInfoTag");
-			transmitRequest(device, request);
+
+
+			transmitRequest(device, request, null);
 		} catch (SipException | ParseException | InvalidArgumentException e) {
 			e.printStackTrace();
 			return false;
@@ -688,13 +700,20 @@
 		return false;
 	}
 	
-	private ClientTransaction transmitRequest(Device device, Request request) throws SipException {
+	private ClientTransaction transmitRequest(Device device, Request request, SipSubscribe.Event errorEvent) throws SipException {
 		ClientTransaction clientTransaction = null;
 		if("TCP".equals(device.getTransport())) {
 			clientTransaction = tcpSipProvider.getNewClientTransaction(request);
 		} else if("UDP".equals(device.getTransport())) {
 			clientTransaction = udpSipProvider.getNewClientTransaction(request);
 		}
+
+		// 娣诲姞璁㈤槄
+		if (errorEvent != null) {
+			CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME);
+			sipSubscribe.addSubscribe(callIdHeader.getCallId(), errorEvent);
+		}
+
 		clientTransaction.sendRequest();
 		return clientTransaction;
 	}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
index 3c90e8e..ba4b2cb 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -294,7 +294,7 @@
 				device.setStreamMode("UDP");
 			}
 			storager.updateDevice(device);
-			cmder.catalogQuery(device);
+			cmder.catalogQuery(device, null);
 			// 鍥炲200 OK
 			responseAck(evt);
 			if (offLineDetector.isOnline(deviceId)) {
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 7249d98..1116ae5 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
@@ -323,7 +323,7 @@
 						cmder.playStreamCmd(device, channelId, (JSONObject response) -> {
 							logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString());
 							playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString());
-						});
+						}, null);
 					}
 
 				}
diff --git a/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java b/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java
index 3fe7dcc..ccbe94d 100644
--- a/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java
+++ b/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java
@@ -34,6 +34,7 @@
      * 鑾峰彇瀵硅薄 杩欓噷閲嶅啓浜哹ean鏂规硶锛岃捣涓昏浣滅敤
      */
     public static Object getBean(String beanId) throws BeansException {
+        if (applicationContext == null) return null;
         return applicationContext.getBean(beanId);
     }
 
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java
index 34a02ee..65e294a 100644
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java
@@ -4,6 +4,7 @@
 
 import com.genersoft.iot.vmp.common.PageResult;
 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
+import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -18,6 +19,8 @@
 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
+
+import javax.sip.message.Response;
 
 @CrossOrigin
 @RestController
@@ -86,11 +89,25 @@
 		
 		if (logger.isDebugEnabled()) {
 		}
-			logger.debug("璁惧淇℃伅鍚屾API璋冪敤锛宒eviceId锛�" + deviceId);
+			logger.debug("璁惧閫氶亾淇℃伅鍚屾API璋冪敤锛宒eviceId锛�" + deviceId);
 
 		Device device = storager.queryVideoDevice(deviceId);
-        cmder.catalogQuery(device);
-        DeferredResult<ResponseEntity<Device>> result = new DeferredResult<ResponseEntity<Device>>();
+        cmder.catalogQuery(device, event -> {
+			Response response = event.getResponse();
+			RequestMessage msg = new RequestMessage();
+			msg.setId(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId);
+			msg.setData(String.format("鍚屾閫氶亾澶辫触锛岄敊璇爜锛� %s, %s", response.getStatusCode(), response.getReasonPhrase()));
+			resultHolder.invokeResult(msg);
+		});
+        DeferredResult<ResponseEntity<Device>> result = new DeferredResult<ResponseEntity<Device>>(2*1000L);
+		result.onTimeout(()->{
+			logger.warn(String.format("璁惧閫氶亾淇℃伅鍚屾瓒呮椂"));
+			// 閲婃斁rtpserver
+			RequestMessage msg = new RequestMessage();
+			msg.setId(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId);
+			msg.setData("Timeout");
+			resultHolder.invokeResult(msg);
+		});
         resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result);
         return result;
 	}
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
index ce907e8..eba40bb 100644
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
@@ -28,6 +28,7 @@
 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
 import org.springframework.web.context.request.async.DeferredResult;
 
+import javax.sip.message.Response;
 import java.text.DecimalFormat;
 import java.util.UUID;
 
@@ -72,6 +73,12 @@
 			cmder.playStreamCmd(device, channelId, (JSONObject response) -> {
 				logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString());
 				playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString());
+			}, event -> {
+				RequestMessage msg = new RequestMessage();
+				msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
+				Response response = event.getResponse();
+				msg.setData(String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", response.getStatusCode(), response.getReasonPhrase()));
+				resultHolder.invokeResult(msg);
 			});
 		} else {
 			String streamId = streamInfo.getStreamId();
@@ -86,6 +93,12 @@
 				cmder.playStreamCmd(device, channelId, (JSONObject response) -> {
 					logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString());
 					playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString());
+				}, event -> {
+					RequestMessage msg = new RequestMessage();
+					msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
+					Response response = event.getResponse();
+					msg.setData(String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", response.getStatusCode(), response.getReasonPhrase()));
+					resultHolder.invokeResult(msg);
 				});
 			}
 		}
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java
index 5fbaabf..c9dc92c 100644
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java
@@ -27,6 +27,7 @@
 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
 import org.springframework.web.context.request.async.DeferredResult;
 
+import javax.sip.message.Response;
 import java.util.UUID;
 
 @CrossOrigin
@@ -78,6 +79,12 @@
 		cmder.playbackStreamCmd(device, channelId, startTime, endTime, (JSONObject response) -> {
 			logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString());
 			playService.onPublishHandlerForPlayBack(response, deviceId, channelId, uuid.toString());
+		}, event -> {
+			Response response = event.getResponse();
+			RequestMessage msg = new RequestMessage();
+			msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
+			msg.setData(String.format("鍥炴斁澶辫触锛� 閿欒鐮侊細 %s, %s", response.getStatusCode(), response.getReasonPhrase()));
+			resultHolder.invokeResult(msg);
 		});
 
 		return result;
diff --git a/web_src/src/components/videoList.vue b/web_src/src/components/videoList.vue
index ad2f701..50767cc 100644
--- a/web_src/src/components/videoList.vue
+++ b/web_src/src/components/videoList.vue
@@ -8,7 +8,7 @@
 				<div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;">
 					<span style="font-size: 1rem; font-weight: bold;">璁惧鍒楄〃</span>
 					<div style="position: absolute; right: 1rem; top: 0.3rem;">
-						<el-button icon="el-icon-refresh-right" circle size="mini" @click="getDeviceList()"></el-button>
+						<el-button icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading" @click="getDeviceList()"></el-button>
 					</div>
 				</div>
 				<devicePlayer ref="devicePlayer"></devicePlayer>
@@ -51,7 +51,7 @@
 
 					<el-table-column label="鎿嶄綔" width="240" align="center" fixed="right">
 						<template slot-scope="scope">
-							<el-button size="mini" icon="el-icon-refresh"  @click="refDevice(scope.row)">鍒锋柊閫氶亾</el-button>
+							<el-button size="mini" :ref="scope.row.deviceId + 'refbtn' " icon="el-icon-refresh"  @click="refDevice(scope.row)">鍒锋柊閫氶亾</el-button>
 							<el-button size="mini" icon="el-icon-s-open"  type="primary" @click="showChannelList(scope.row)">鏌ョ湅閫氶亾</el-button>
 						</template>
 					</el-table-column>
@@ -90,7 +90,8 @@
 				winHeight: window.innerHeight - 200,
 				currentPage:1,
 				count:15,
-				total:0
+				total:0,
+				getDeviceListLoading: false
 			};
 		},
 		computed: {
@@ -130,7 +131,7 @@
 			},
 			getDeviceList: function() {
 				let that = this;
-
+				this.getDeviceListLoading = true;
 				this.$axios.get(`/api/devices`,{
 					params: {
 						page: that.currentPage - 1,
@@ -141,9 +142,11 @@
 					console.log(res);
 					that.total = res.data.total;
 					that.deviceList = res.data.data;
+					that.getDeviceListLoading = false;
 				})
 				.catch(function (error) {
 					console.log(error);
+					that.getDeviceListLoading = false;
 				});
 
 			},
@@ -158,17 +161,30 @@
 			refDevice: function(itemData) {
 				///api/devices/{deviceId}/sync
 				console.log("鍒锋柊瀵瑰簲璁惧:" + itemData.deviceId);
+				var that = this;
+				that.$refs[itemData.deviceId + 'refbtn' ].loading = true;
 				this.$axios({
 					method: 'post',
 					url: '/api/devices/' + itemData.deviceId + '/sync'
 				}).then(function(res) {
-					// console.log("鍒锋柊璁惧缁撴灉锛�"+JSON.stringify(res));
+					console.log("鍒锋柊璁惧缁撴灉锛�"+JSON.stringify(res));
+					if (!res.data.deviceId) {
+						that.$message({
+							showClose: true,
+							message: res.data,
+							type: 'error'
+						});
+					}else{
+						that.$message({
+							showClose: true,
+							message: '璇锋眰鎴愬姛',
+							type: 'success'
+						});
+					}
+					that.$refs[itemData.deviceId + 'refbtn' ].loading = false;
 				}).catch(function(e) {
-					that.$message({
-						showClose: true,
-						message: '璇锋眰鎴愬姛',
-						type: 'success'
-					});
+					console.error(e)
+					that.$refs[itemData.deviceId + 'refbtn' ].loading = false;
 				});;
 			},
 			//閫氱煡璁惧涓婁紶濯掍綋娴�

--
Gitblit v1.8.0