Browse Source

对需要向设备发起请求的http请求,使用缓存,等待设备请求返回的时候一次性释放所有请求

pull/212/head
648540858 3 years ago
parent
commit
3b21f385cd
  1. 11
      src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java
  2. 6
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/CheckForAllRecordsThread.java
  3. 66
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
  4. 26
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java
  5. 189
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
  6. 41
      src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
  7. 11
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java
  8. 24
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceConfig.java
  9. 74
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceControl.java
  10. 52
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
  11. 50
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
  12. 24
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java
  13. 15
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java
  14. 30
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/ptz/PtzController.java
  15. 12
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/record/GBRecordController.java
  16. 14
      src/main/java/com/genersoft/iot/vmp/vmanager/onvif/ONVIFController.java
  17. 1
      web_src/src/components/MediaServerManger.vue

11
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java

@ -13,7 +13,9 @@ import java.util.List;
public class RecordInfo { public class RecordInfo {
private String deviceId; private String deviceId;
private String channelId;
private String name; private String name;
private int sumNum; private int sumNum;
@ -52,4 +54,11 @@ public class RecordInfo {
this.recordList = recordList; this.recordList = recordList;
} }
public String getChannelId() {
return channelId;
}
public void setChannelId(String channelId) {
this.channelId = channelId;
}
} }

6
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/CheckForAllRecordsThread.java

@ -54,11 +54,9 @@ public class CheckForAllRecordsThread extends Thread {
// 自然顺序排序, 元素进行升序排列 // 自然顺序排序, 元素进行升序排列
this.recordInfo.getRecordList().sort(Comparator.naturalOrder()); this.recordInfo.getRecordList().sort(Comparator.naturalOrder());
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
String deviceId = recordInfo.getDeviceId(); msg.setKey(DeferredResultHolder.CALLBACK_CMD_RECORDINFO + recordInfo.getDeviceId() + recordInfo.getChannelId());
msg.setDeviceId(deviceId);
msg.setType(DeferredResultHolder.CALLBACK_CMD_RECORDINFO);
msg.setData(recordInfo); msg.setData(recordInfo);
deferredResultHolder.invokeResult(msg); deferredResultHolder.invokeAllResult(msg);
logger.info("处理完成,返回结果"); logger.info("处理完成,返回结果");
MessageRequestProcessor.threadNameList.remove(cacheKey); MessageRequestProcessor.threadNameList.remove(cacheKey);
} }

66
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java

@ -1,6 +1,8 @@
package com.genersoft.iot.vmp.gb28181.transmit.callback; package com.genersoft.iot.vmp.gb28181.transmit.callback;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
@ -45,22 +47,72 @@ public class DeferredResultHolder {
public static final String CALLBACK_CMD_BROADCAST = "CALLBACK_BROADCAST"; public static final String CALLBACK_CMD_BROADCAST = "CALLBACK_BROADCAST";
private Map<String, DeferredResult> map = new ConcurrentHashMap<String, DeferredResult>(); private Map<String, Map<String, DeferredResult>> map = new ConcurrentHashMap<>();
public void put(String key, DeferredResult result) { public void put(String key, String id, DeferredResult result) {
map.put(key, result); Map<String, DeferredResult> deferredResultMap = map.get(key);
if (deferredResultMap == null) {
deferredResultMap = new ConcurrentHashMap<>();
map.put(key, deferredResultMap);
}
deferredResultMap.put(id, result);
} }
public DeferredResult get(String key) { public DeferredResult get(String key, String id) {
return map.get(key); Map<String, DeferredResult> deferredResultMap = map.get(key);
if (deferredResultMap == null) return null;
return deferredResultMap.get(id);
} }
public boolean exist(String key, String id){
if (key == null) return false;
Map<String, DeferredResult> deferredResultMap = map.get(key);
if (id == null) {
return deferredResultMap != null;
}else {
return deferredResultMap != null && deferredResultMap.get(id) != null;
}
}
/**
* 释放单个请求
* @param msg
*/
public void invokeResult(RequestMessage msg) { public void invokeResult(RequestMessage msg) {
DeferredResult result = map.get(msg.getId()); Map<String, DeferredResult> deferredResultMap = map.get(msg.getKey());
if (deferredResultMap == null) {
return;
}
DeferredResult result = deferredResultMap.get(msg.getId());
if (result == null) { if (result == null) {
return; return;
} }
result.setResult(new ResponseEntity<>(msg.getData(),HttpStatus.OK)); result.setResult(new ResponseEntity<>(msg.getData(),HttpStatus.OK));
deferredResultMap.remove(msg.getId());
if (deferredResultMap.size() == 0) {
map.remove(msg.getKey());
}
}
/**
* 释放所有的请求
* @param msg
*/
public void invokeAllResult(RequestMessage msg) {
Map<String, DeferredResult> deferredResultMap = map.get(msg.getKey());
if (deferredResultMap == null) {
return;
}
Set<String> ids = deferredResultMap.keySet();
for (String id : ids) {
DeferredResult result = deferredResultMap.get(id);
if (result == null) {
return;
}
result.setResult(new ResponseEntity<>(msg.getData(),HttpStatus.OK));
}
map.remove(msg.getKey());
} }
} }

26
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java

@ -9,12 +9,10 @@ public class RequestMessage {
private String id; private String id;
private String deviceId; private String key;
private String type;
private Object data; private Object data;
public String getId() { public String getId() {
return id; return id;
} }
@ -23,22 +21,12 @@ public class RequestMessage {
this.id = id; this.id = id;
} }
public String getDeviceId() { public void setKey(String key) {
return deviceId; this.key = key;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
this.id = type + deviceId;
}
public String getType() {
return type;
} }
public void setType(String type) { public String getKey() {
this.type = type; return key;
this.id = type + deviceId;
} }
public Object getData() { public Object getData() {

189
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java

@ -173,12 +173,12 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
if (device == null) { if (device == null) {
logger.warn("处理MobilePosition移动位置消息时未找到设备信息"); logger.warn("处理MobilePosition移动位置消息时未找到设备信息");
response404Ack(evt);
return; return;
} }
Element rootElement = getRootElement(evt, device.getCharset()); Element rootElement = getRootElement(evt, device.getCharset());
MobilePosition mobilePosition = new MobilePosition(); MobilePosition mobilePosition = new MobilePosition();
Element deviceIdElement = rootElement.element("DeviceID");
if (!StringUtils.isEmpty(device.getName())) { if (!StringUtils.isEmpty(device.getName())) {
mobilePosition.setDeviceName(device.getName()); mobilePosition.setDeviceName(device.getName());
} }
@ -227,11 +227,17 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
*/ */
private void processMessageDeviceStatus(RequestEvent evt) { private void processMessageDeviceStatus(RequestEvent evt) {
try { try {
String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
Device device = storager.queryVideoDevice(deviceId);
if (device == null) {
logger.warn("处理DeviceStatus设备状态Message时未找到设备信息");
response404Ack(evt);
return;
}
Element rootElement = getRootElement(evt); Element rootElement = getRootElement(evt);
String name = rootElement.getName(); String name = rootElement.getName();
Element deviceIdElement = rootElement.element("DeviceID"); Element deviceIdElement = rootElement.element("DeviceID");
String deviceId = deviceIdElement.getText(); String channelId = deviceIdElement.getText();
Device device = storager.queryVideoDevice(deviceId);
if (name.equalsIgnoreCase("Query")) { // 区分是Response——查询响应,还是Query——查询请求 if (name.equalsIgnoreCase("Query")) { // 区分是Response——查询响应,还是Query——查询请求
logger.info("接收到DeviceStatus查询消息"); logger.info("接收到DeviceStatus查询消息");
FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
@ -258,10 +264,9 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
logger.debug(json.toJSONString()); logger.debug(json.toJSONString());
} }
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setDeviceId(deviceId); msg.setKey(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId + channelId);
msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS);
msg.setData(json); msg.setData(json);
deferredResultHolder.invokeResult(msg); deferredResultHolder.invokeAllResult(msg);
if (offLineDetector.isOnline(deviceId)) { if (offLineDetector.isOnline(deviceId)) {
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE); publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
@ -282,8 +287,15 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
*/ */
private void processMessageDeviceControl(RequestEvent evt) { private void processMessageDeviceControl(RequestEvent evt) {
try { try {
String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
Device device = storager.queryVideoDevice(deviceId);
if (device == null) {
logger.warn("处理DeviceControl设备状态Message未找到设备信息");
response404Ack(evt);
return;
}
Element rootElement = getRootElement(evt); Element rootElement = getRootElement(evt);
String deviceId = XmlUtil.getText(rootElement, "DeviceID"); String channelId = XmlUtil.getText(rootElement, "DeviceID");
//String result = XmlUtil.getText(rootElement, "Result"); //String result = XmlUtil.getText(rootElement, "Result");
// 回复200 OK // 回复200 OK
responseAck(evt); responseAck(evt);
@ -295,10 +307,10 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
logger.debug(json.toJSONString()); logger.debug(json.toJSONString());
} }
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setDeviceId(deviceId); String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + channelId;
msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL); msg.setKey(key);
msg.setData(json); msg.setData(json);
deferredResultHolder.invokeResult(msg); deferredResultHolder.invokeAllResult(msg);
} else { } else {
// 此处是上级发出的DeviceControl指令 // 此处是上级发出的DeviceControl指令
String platformId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); String platformId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
@ -344,8 +356,8 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
// 云台/前端控制命令 // 云台/前端控制命令
if (!StringUtils.isEmpty(XmlUtil.getText(rootElement,"PTZCmd")) && !deviceId.equals(targetGBId)) { if (!StringUtils.isEmpty(XmlUtil.getText(rootElement,"PTZCmd")) && !deviceId.equals(targetGBId)) {
String cmdString = XmlUtil.getText(rootElement,"PTZCmd"); String cmdString = XmlUtil.getText(rootElement,"PTZCmd");
Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, deviceId); Device deviceForPlatform = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, deviceId);
cmder.fronEndCmd(device, deviceId, cmdString); cmder.fronEndCmd(deviceForPlatform, deviceId, cmdString);
} }
} }
} catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
@ -360,8 +372,16 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
*/ */
private void processMessageDeviceConfig(RequestEvent evt) { private void processMessageDeviceConfig(RequestEvent evt) {
try { try {
String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
// 查询设备是否存在
Device device = storager.queryVideoDevice(deviceId);
if (device == null) {
logger.warn("处理DeviceConfig设备状态Message消息时未找到设备信息");
response404Ack(evt);
return;
}
Element rootElement = getRootElement(evt); Element rootElement = getRootElement(evt);
String deviceId = XmlUtil.getText(rootElement, "DeviceID"); String channelId = XmlUtil.getText(rootElement, "DeviceID");
// 回复200 OK // 回复200 OK
responseAck(evt); responseAck(evt);
if (rootElement.getName().equals("Response")) { if (rootElement.getName().equals("Response")) {
@ -371,11 +391,11 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug(json.toJSONString()); logger.debug(json.toJSONString());
} }
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + deviceId + channelId;
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setDeviceId(deviceId); msg.setKey(key);
msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG);
msg.setData(json); msg.setData(json);
deferredResultHolder.invokeResult(msg); deferredResultHolder.invokeAllResult(msg);
} else { } else {
// 此处是上级发出的DeviceConfig指令 // 此处是上级发出的DeviceConfig指令
} }
@ -391,8 +411,17 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
*/ */
private void processMessageConfigDownload(RequestEvent evt) { private void processMessageConfigDownload(RequestEvent evt) {
try { try {
String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
// 查询设备是否存在
Device device = storager.queryVideoDevice(deviceId);
if (device == null) {
logger.warn("处理ConfigDownload设备状态Message时未找到设备信息");
response404Ack(evt);
return;
}
Element rootElement = getRootElement(evt); Element rootElement = getRootElement(evt);
String deviceId = XmlUtil.getText(rootElement, "DeviceID"); String channelId = XmlUtil.getText(rootElement, "DeviceID");
String key = DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + deviceId + channelId;
// 回复200 OK // 回复200 OK
responseAck(evt); responseAck(evt);
if (rootElement.getName().equals("Response")) { if (rootElement.getName().equals("Response")) {
@ -403,10 +432,9 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
logger.debug(json.toJSONString()); logger.debug(json.toJSONString());
} }
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setDeviceId(deviceId); msg.setKey(key);
msg.setType(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD);
msg.setData(json); msg.setData(json);
deferredResultHolder.invokeResult(msg); deferredResultHolder.invokeAllResult(msg);
} else { } else {
// 此处是上级发出的DeviceConfig指令 // 此处是上级发出的DeviceConfig指令
} }
@ -422,8 +450,17 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
*/ */
private void processMessagePresetQuery(RequestEvent evt) { private void processMessagePresetQuery(RequestEvent evt) {
try { try {
String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
// 查询设备是否存在
Device device = storager.queryVideoDevice(deviceId);
if (device == null) {
logger.warn("处理PresetQuery预置位列表Message时未找到设备信息");
response404Ack(evt);
return;
}
Element rootElement = getRootElement(evt); Element rootElement = getRootElement(evt);
String deviceId = XmlUtil.getText(rootElement, "DeviceID"); String channelId = XmlUtil.getText(rootElement, "DeviceID");
String key = DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + deviceId + channelId;
// 回复200 OK // 回复200 OK
responseAck(evt); responseAck(evt);
if (rootElement.getName().equals("Response")) {// !StringUtils.isEmpty(result)) { if (rootElement.getName().equals("Response")) {// !StringUtils.isEmpty(result)) {
@ -434,10 +471,9 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
logger.debug(json.toJSONString()); logger.debug(json.toJSONString());
} }
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setDeviceId(deviceId); msg.setKey(key);
msg.setType(DeferredResultHolder.CALLBACK_CMD_PRESETQUERY);
msg.setData(json); msg.setData(json);
deferredResultHolder.invokeResult(msg); deferredResultHolder.invokeAllResult(msg);
} else { } else {
// 此处是上级发出的DeviceControl指令 // 此处是上级发出的DeviceControl指令
} }
@ -453,11 +489,19 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
*/ */
private void processMessageDeviceInfo(RequestEvent evt) { private void processMessageDeviceInfo(RequestEvent evt) {
try { try {
String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
// 查询设备是否存在
Device device = storager.queryVideoDevice(deviceId);
if (device == null) {
logger.warn("处理DeviceInfo设备信息Message时未找到设备信息");
response404Ack(evt);
return;
}
Element rootElement = getRootElement(evt); Element rootElement = getRootElement(evt);
String requestName = rootElement.getName(); String requestName = rootElement.getName();
Element deviceIdElement = rootElement.element("DeviceID"); Element deviceIdElement = rootElement.element("DeviceID");
String deviceId = deviceIdElement.getTextTrim(); String channelId = deviceIdElement.getTextTrim();
Device device = storager.queryVideoDevice(deviceId); String key = DeferredResultHolder.CALLBACK_CMD_DEVICEINFO + deviceId + channelId;
if (device != null ) { if (device != null ) {
rootElement = getRootElement(evt, device.getCharset()); rootElement = getRootElement(evt, device.getCharset());
} }
@ -492,10 +536,9 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
storager.updateDevice(device); storager.updateDevice(device);
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setDeviceId(deviceId); msg.setKey(key);
msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICEINFO);
msg.setData(device); msg.setData(device);
deferredResultHolder.invokeResult(msg); deferredResultHolder.invokeAllResult(msg);
// 回复200 OK // 回复200 OK
responseAck(evt); responseAck(evt);
if (offLineDetector.isOnline(deviceId)) { if (offLineDetector.isOnline(deviceId)) {
@ -514,12 +557,22 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
*/ */
private void processMessageCatalogList(RequestEvent evt) { private void processMessageCatalogList(RequestEvent evt) {
try { try {
String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
// 查询设备是否存在
Device device = storager.queryVideoDevice(deviceId);
if (device == null) {
logger.warn("处理DeviceInfo设备信息Message时未找到设备信息");
response404Ack(evt);
return;
}
Element rootElement = getRootElement(evt); Element rootElement = getRootElement(evt);
String name = rootElement.getName(); String name = rootElement.getName();
Element deviceIdElement = rootElement.element("DeviceID"); Element deviceIdElement = rootElement.element("DeviceID");
String deviceId = deviceIdElement.getText(); String channelId = deviceIdElement.getText();
Element deviceListElement = rootElement.element("DeviceList"); Element deviceListElement = rootElement.element("DeviceList");
String key = DeferredResultHolder.CALLBACK_CMD_CATALOG + deviceId;
FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
AddressImpl address = (AddressImpl) fromHeader.getAddress(); AddressImpl address = (AddressImpl) fromHeader.getAddress();
SipUri uri = (SipUri) address.getURI(); SipUri uri = (SipUri) address.getURI();
@ -581,10 +634,6 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
} else { } else {
Device device = storager.queryVideoDevice(deviceId);
if (device == null) {
return;
}
deviceListElement = getRootElement(evt, device.getCharset()).element("DeviceList"); deviceListElement = getRootElement(evt, device.getCharset()).element("DeviceList");
Iterator<Element> deviceListIterator = deviceListElement.elementIterator(); Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
if (deviceListIterator != null) { if (deviceListIterator != null) {
@ -674,10 +723,9 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
} }
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setDeviceId(deviceId); msg.setKey(key);
msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG);
msg.setData(device); msg.setData(device);
deferredResultHolder.invokeResult(msg); deferredResultHolder.invokeAllResult(msg);
// 回复200 OK // 回复200 OK
responseAck(evt); responseAck(evt);
if (offLineDetector.isOnline(deviceId)) { if (offLineDetector.isOnline(deviceId)) {
@ -701,11 +749,13 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
if (device == null) { if (device == null) {
logger.warn("处理alarm设备报警信息未找到设备信息"); logger.warn("处理alarm设备报警信息未找到设备信息");
response404Ack(evt);
return; return;
} }
Element rootElement = getRootElement(evt, device.getCharset()); Element rootElement = getRootElement(evt, device.getCharset());
Element deviceIdElement = rootElement.element("DeviceID"); Element deviceIdElement = rootElement.element("DeviceID");
String channelId = deviceIdElement.getText().toString(); String channelId = deviceIdElement.getText().toString();
String key = DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId + channelId;
// 回复200 OK // 回复200 OK
responseAck(evt); responseAck(evt);
@ -770,10 +820,9 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
logger.debug(json.toJSONString()); logger.debug(json.toJSONString());
} }
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setDeviceId(deviceId); msg.setKey(key);
msg.setType(DeferredResultHolder.CALLBACK_CMD_ALARM);
msg.setData(json); msg.setData(json);
deferredResultHolder.invokeResult(msg); deferredResultHolder.invokeAllResult(msg);
} }
} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
e.printStackTrace(); e.printStackTrace();
@ -787,10 +836,14 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
*/ */
private void processMessageKeepAlive(RequestEvent evt) { private void processMessageKeepAlive(RequestEvent evt) {
try { try {
Element rootElement = getRootElement(evt);
String deviceId = XmlUtil.getText(rootElement, "DeviceID"); String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
// 查询设备是否存在
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
Element rootElement = getRootElement(evt);
String channelId = XmlUtil.getText(rootElement, "DeviceID");
// 检查设备是否存在并在线, 不在线则设置为在线 // 检查设备是否存在并在线, 不在线则设置为在线
if (device != null ) { if (device != null ) {
// 回复200 OK // 回复200 OK
@ -831,18 +884,29 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
*/ */
private void processMessageRecordInfo(RequestEvent evt) { private void processMessageRecordInfo(RequestEvent evt) {
try { try {
String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
// 查询设备是否存在
Device device = storager.queryVideoDevice(deviceId);
if (device == null) {
logger.warn("处理DeviceInfo设备信息Message时未找到设备信息");
response404Ack(evt);
return;
}
// 回复200 OK // 回复200 OK
responseAck(evt); responseAck(evt);
String uuid = UUID.randomUUID().toString().replace("-", ""); String uuid = UUID.randomUUID().toString().replace("-", "");
RecordInfo recordInfo = new RecordInfo(); RecordInfo recordInfo = new RecordInfo();
Element rootElement = getRootElement(evt); Element rootElement = getRootElement(evt);
Element deviceIdElement = rootElement.element("DeviceID"); Element deviceIdElement = rootElement.element("DeviceID");
String deviceId = deviceIdElement.getText().toString(); String channelId = deviceIdElement.getText().toString();
Device device = storager.queryVideoDevice(deviceId); String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + deviceId + channelId;
if (device != null ) { if (device != null ) {
rootElement = getRootElement(evt, device.getCharset()); rootElement = getRootElement(evt, device.getCharset());
} }
recordInfo.setDeviceId(deviceId); recordInfo.setDeviceId(deviceId);
recordInfo.setChannelId(channelId);
recordInfo.setName(XmlUtil.getText(rootElement, "Name")); recordInfo.setName(XmlUtil.getText(rootElement, "Name"));
if (XmlUtil.getText(rootElement, "SumNum")== null || XmlUtil.getText(rootElement, "SumNum") =="") { if (XmlUtil.getText(rootElement, "SumNum")== null || XmlUtil.getText(rootElement, "SumNum") =="") {
recordInfo.setSumNum(0); recordInfo.setSumNum(0);
@ -854,10 +918,9 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
if (recordListElement == null || recordInfo.getSumNum() == 0) { if (recordListElement == null || recordInfo.getSumNum() == 0) {
logger.info("无录像数据"); logger.info("无录像数据");
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setDeviceId(deviceId); msg.setKey(key);
msg.setType(DeferredResultHolder.CALLBACK_CMD_RECORDINFO);
msg.setData(recordInfo); msg.setData(recordInfo);
deferredResultHolder.invokeResult(msg); deferredResultHolder.invokeAllResult(msg);
} else { } else {
Iterator<Element> recordListIterator = recordListElement.elementIterator(); Iterator<Element> recordListIterator = recordListElement.elementIterator();
List<RecordItem> recordList = new ArrayList<RecordItem>(); List<RecordItem> recordList = new ArrayList<RecordItem>();
@ -956,10 +1019,20 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
*/ */
private void processMessageMediaStatus(RequestEvent evt){ private void processMessageMediaStatus(RequestEvent evt){
try { try {
String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
// 查询设备是否存在
Device device = storager.queryVideoDevice(deviceId);
if (device == null) {
logger.warn("处理DeviceInfo设备信息Message时未找到设备信息");
response404Ack(evt);
return;
}
// 回复200 OK // 回复200 OK
responseAck(evt); responseAck(evt);
Element rootElement = getRootElement(evt); Element rootElement = getRootElement(evt);
String deviceId = XmlUtil.getText(rootElement, "DeviceID"); String channelId = XmlUtil.getText(rootElement, "DeviceID");
String NotifyType =XmlUtil.getText(rootElement, "NotifyType"); String NotifyType =XmlUtil.getText(rootElement, "NotifyType");
if (NotifyType.equals("121")){ if (NotifyType.equals("121")){
logger.info("媒体播放完毕,通知关流"); logger.info("媒体播放完毕,通知关流");
@ -981,8 +1054,19 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
*/ */
private void processMessageBroadcast(RequestEvent evt) { private void processMessageBroadcast(RequestEvent evt) {
try { try {
String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
// 查询设备是否存在
Device device = storager.queryVideoDevice(deviceId);
if (device == null) {
logger.warn("处理DeviceInfo设备信息Message时未找到设备信息");
response404Ack(evt);
return;
}
Element rootElement = getRootElement(evt); Element rootElement = getRootElement(evt);
String deviceId = XmlUtil.getText(rootElement, "DeviceID"); String channelId = XmlUtil.getText(rootElement, "DeviceID");
String key = DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId + channelId;
// 回复200 OK // 回复200 OK
responseAck(evt); responseAck(evt);
if (rootElement.getName().equals("Response")) { if (rootElement.getName().equals("Response")) {
@ -993,10 +1077,9 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
logger.debug(json.toJSONString()); logger.debug(json.toJSONString());
} }
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setDeviceId(deviceId); msg.setKey(key);
msg.setType(DeferredResultHolder.CALLBACK_CMD_BROADCAST);
msg.setData(json); msg.setData(json);
deferredResultHolder.invokeResult(msg); deferredResultHolder.invokeAllResult(msg);
} else { } else {
// 此处是上级发出的Broadcast指令 // 此处是上级发出的Broadcast指令
} }

41
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java

@ -78,9 +78,11 @@ public class PlayServiceImpl implements IPlayService {
@Override @Override
public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) { public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) {
PlayResult playResult = new PlayResult(); PlayResult playResult = new PlayResult();
RequestMessage msg = new RequestMessage();
String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId;
msg.setKey(key);
msg.setId(playResult.getUuid());
if (mediaServerItem == null) { if (mediaServerItem == null) {
RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + playResult.getUuid());
WVPResult wvpResult = new WVPResult(); WVPResult wvpResult = new WVPResult();
wvpResult.setCode(-1); wvpResult.setCode(-1);
wvpResult.setMsg("未找到可用的zlm"); wvpResult.setMsg("未找到可用的zlm");
@ -88,20 +90,19 @@ public class PlayServiceImpl implements IPlayService {
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
return playResult; return playResult;
} }
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
playResult.setDevice(device); playResult.setDevice(device);
UUID uuid = UUID.randomUUID(); String uuid = UUID.randomUUID().toString();
playResult.setUuid(uuid.toString()); playResult.setUuid(uuid);
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(userSetup.getPlayTimeout()); DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(userSetup.getPlayTimeout());
playResult.setResult(result); playResult.setResult(result);
// 录像查询以channelId作为deviceId查询 // 录像查询以channelId作为deviceId查询
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid, result); resultHolder.put(key, uuid, result);
// 超时处理 // 超时处理
result.onTimeout(()->{ result.onTimeout(()->{
logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId)); logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));
RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + playResult.getUuid());
WVPResult wvpResult = new WVPResult(); WVPResult wvpResult = new WVPResult();
wvpResult.setCode(-1); wvpResult.setCode(-1);
SIPDialog dialog = streamSession.getDialog(deviceId, channelId); SIPDialog dialog = streamSession.getDialog(deviceId, channelId);
@ -115,7 +116,8 @@ public class PlayServiceImpl implements IPlayService {
cmder.streamByeCmd(device.getDeviceId(), channelId); cmder.streamByeCmd(device.getDeviceId(), channelId);
// 释放rtpserver // 释放rtpserver
mediaServerService.closeRTPServer(playResult.getDevice(), channelId); mediaServerService.closeRTPServer(playResult.getDevice(), channelId);
resultHolder.invokeResult(msg); // 回复之前所有的点播请求
resultHolder.invokeAllResult(msg);
}); });
result.onCompletion(()->{ result.onCompletion(()->{
// 点播结束时调用截图接口 // 点播结束时调用截图接口
@ -169,15 +171,13 @@ public class PlayServiceImpl implements IPlayService {
} }
}, (event) -> { }, (event) -> {
// 点播返回sip错误 // 点播返回sip错误
RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid);
Response response = event.getResponse(); Response response = event.getResponse();
mediaServerService.closeRTPServer(playResult.getDevice(), channelId); mediaServerService.closeRTPServer(playResult.getDevice(), channelId);
WVPResult wvpResult = new WVPResult(); WVPResult wvpResult = new WVPResult();
wvpResult.setCode(-1); wvpResult.setCode(-1);
wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
msg.setData(wvpResult); msg.setData(wvpResult);
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
if (errorEvent != null) { if (errorEvent != null) {
errorEvent.response(event); errorEvent.response(event);
} }
@ -186,13 +186,11 @@ public class PlayServiceImpl implements IPlayService {
} else { } else {
String streamId = streamInfo.getStreamId(); String streamId = streamInfo.getStreamId();
if (streamId == null) { if (streamId == null) {
RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid);
WVPResult wvpResult = new WVPResult(); WVPResult wvpResult = new WVPResult();
wvpResult.setCode(-1); wvpResult.setCode(-1);
wvpResult.setMsg(String.format("点播失败, redis缓存streamId等于null")); wvpResult.setMsg(String.format("点播失败, redis缓存streamId等于null"));
msg.setData(wvpResult); msg.setData(wvpResult);
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
return playResult; return playResult;
} }
String mediaServerId = streamInfo.getMediaServerId(); String mediaServerId = streamInfo.getMediaServerId();
@ -200,8 +198,6 @@ public class PlayServiceImpl implements IPlayService {
JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId); JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId);
if (rtpInfo != null && rtpInfo.getBoolean("exist")) { if (rtpInfo != null && rtpInfo.getBoolean("exist")) {
RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid);
WVPResult wvpResult = new WVPResult(); WVPResult wvpResult = new WVPResult();
wvpResult.setCode(0); wvpResult.setCode(0);
@ -209,7 +205,7 @@ public class PlayServiceImpl implements IPlayService {
wvpResult.setData(streamInfo); wvpResult.setData(streamInfo);
msg.setData(wvpResult); msg.setData(wvpResult);
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
if (hookEvent != null) { if (hookEvent != null) {
hookEvent.response(mediaServerItem, JSONObject.parseObject(JSON.toJSONString(streamInfo))); hookEvent.response(mediaServerItem, JSONObject.parseObject(JSON.toJSONString(streamInfo)));
} }
@ -229,15 +225,13 @@ public class PlayServiceImpl implements IPlayService {
onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString()); onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString());
}, (event) -> { }, (event) -> {
mediaServerService.closeRTPServer(playResult.getDevice(), channelId); mediaServerService.closeRTPServer(playResult.getDevice(), channelId);
RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid);
Response response = event.getResponse(); Response response = event.getResponse();
WVPResult wvpResult = new WVPResult(); WVPResult wvpResult = new WVPResult();
wvpResult.setCode(-1); wvpResult.setCode(-1);
wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
msg.setData(wvpResult); msg.setData(wvpResult);
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
}); });
} }
} }
@ -248,7 +242,8 @@ public class PlayServiceImpl implements IPlayService {
@Override @Override
public void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { public void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) {
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid); msg.setId(uuid);
msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId);
StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid); StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid);
if (streamInfo != null) { if (streamInfo != null) {
DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
@ -265,11 +260,11 @@ public class PlayServiceImpl implements IPlayService {
wvpResult.setData(streamInfo); wvpResult.setData(streamInfo);
msg.setData(wvpResult); msg.setData(wvpResult);
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
} else { } else {
logger.warn("设备预览API调用失败!"); logger.warn("设备预览API调用失败!");
msg.setData("设备预览API调用失败!"); msg.setData("设备预览API调用失败!");
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
} }
} }

11
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java

@ -1,6 +1,7 @@
package com.genersoft.iot.vmp.vmanager.gb28181.MobilePosition; package com.genersoft.iot.vmp.vmanager.gb28181.MobilePosition;
import java.util.List; import java.util.List;
import java.util.UUID;
import javax.sip.message.Response; import javax.sip.message.Response;
@ -111,10 +112,13 @@ public class MobilePositionController {
@GetMapping("/realtime/{deviceId}") @GetMapping("/realtime/{deviceId}")
public DeferredResult<ResponseEntity<MobilePosition>> realTimePosition(@PathVariable String deviceId) { public DeferredResult<ResponseEntity<MobilePosition>> realTimePosition(@PathVariable String deviceId) {
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
String uuid = UUID.randomUUID().toString();
String key = DeferredResultHolder.CALLBACK_CMD_MOBILEPOSITION + deviceId;
cmder.mobilePostitionQuery(device, event -> { cmder.mobilePostitionQuery(device, event -> {
Response response = event.getResponse(); Response response = event.getResponse();
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_MOBILEPOSITION + deviceId); msg.setId(uuid);
msg.setKey(key);
msg.setData(String.format("获取移动位置信息失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); msg.setData(String.format("获取移动位置信息失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
@ -123,11 +127,12 @@ public class MobilePositionController {
logger.warn(String.format("获取移动位置信息超时")); logger.warn(String.format("获取移动位置信息超时"));
// 释放rtpserver // 释放rtpserver
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId); msg.setId(uuid);
msg.setKey(key);
msg.setData("Timeout"); msg.setData("Timeout");
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result); resultHolder.put(key, uuid, result);
return result; return result;
} }

24
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceConfig.java

@ -28,6 +28,8 @@ import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.context.request.async.DeferredResult;
import java.util.UUID;
@Api(tags = "国标设备配置") @Api(tags = "国标设备配置")
@CrossOrigin @CrossOrigin
@RestController @RestController
@ -66,7 +68,7 @@ public class DeviceConfig {
@ApiImplicitParam(name = "heartBeatCount", value ="心跳计数" ,dataTypeClass = String.class), @ApiImplicitParam(name = "heartBeatCount", value ="心跳计数" ,dataTypeClass = String.class),
}) })
public DeferredResult<ResponseEntity<String>> homePositionApi(@PathVariable String deviceId, public DeferredResult<ResponseEntity<String>> homePositionApi(@PathVariable String deviceId,
@RequestParam(required = false) String channelId, String channelId,
@RequestParam(required = false) String name, @RequestParam(required = false) String name,
@RequestParam(required = false) String expiration, @RequestParam(required = false) String expiration,
@RequestParam(required = false) String heartBeatInterval, @RequestParam(required = false) String heartBeatInterval,
@ -75,10 +77,13 @@ public class DeviceConfig {
logger.debug("报警复位API调用"); logger.debug("报警复位API调用");
} }
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
String uuid = UUID.randomUUID().toString();
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + deviceId + channelId;
cmder.deviceBasicConfigCmd(device, channelId, name, expiration, heartBeatInterval, heartBeatCount, event -> { cmder.deviceBasicConfigCmd(device, channelId, name, expiration, heartBeatInterval, heartBeatCount, event -> {
Response response = event.getResponse(); Response response = event.getResponse();
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + (StringUtils.isEmpty(channelId) ? deviceId : channelId)); msg.setId(uuid);
msg.setKey(key);
msg.setData(String.format("设备配置操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); msg.setData(String.format("设备配置操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
@ -87,7 +92,8 @@ public class DeviceConfig {
logger.warn(String.format("设备配置操作超时, 设备未返回应答指令")); logger.warn(String.format("设备配置操作超时, 设备未返回应答指令"));
// 释放rtpserver // 释放rtpserver
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + (StringUtils.isEmpty(channelId) ? deviceId : channelId)); msg.setId(uuid);
msg.setKey(key);
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("DeviceID", deviceId); json.put("DeviceID", deviceId);
json.put("Status", "Timeout"); json.put("Status", "Timeout");
@ -95,7 +101,7 @@ public class DeviceConfig {
msg.setData(json); //("看守位控制操作超时, 设备未返回应答指令"); msg.setData(json); //("看守位控制操作超时, 设备未返回应答指令");
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + (StringUtils.isEmpty(channelId) ? deviceId : channelId), result); resultHolder.put(key, uuid, result);
return result; return result;
} }
@ -119,11 +125,14 @@ public class DeviceConfig {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("设备状态查询API调用"); logger.debug("设备状态查询API调用");
} }
String key = DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (StringUtils.isEmpty(channelId) ? deviceId : channelId);
String uuid = UUID.randomUUID().toString();
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
cmder.deviceConfigQuery(device, channelId, configType, event -> { cmder.deviceConfigQuery(device, channelId, configType, event -> {
Response response = event.getResponse(); Response response = event.getResponse();
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (StringUtils.isEmpty(channelId) ? deviceId : channelId)); msg.setId(uuid);
msg.setKey(key);
msg.setData(String.format("获取设备配置失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); msg.setData(String.format("获取设备配置失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
@ -132,11 +141,12 @@ public class DeviceConfig {
logger.warn(String.format("获取设备配置超时")); logger.warn(String.format("获取设备配置超时"));
// 释放rtpserver // 释放rtpserver
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (StringUtils.isEmpty(channelId) ? deviceId : channelId)); msg.setId(uuid);
msg.setKey(key);
msg.setData("Timeout. Device did not response to this command."); msg.setData("Timeout. Device did not response to this command.");
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (StringUtils.isEmpty(channelId) ? deviceId : channelId), result); resultHolder.put(key, uuid, result);
return result; return result;
} }

74
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceControl.java

@ -29,6 +29,8 @@ import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.context.request.async.DeferredResult;
import java.util.UUID;
@Api(tags = "国标设备控制") @Api(tags = "国标设备控制")
@CrossOrigin @CrossOrigin
@RestController @RestController
@ -89,28 +91,36 @@ public class DeviceControl {
}) })
@GetMapping("/record/{deviceId}/{recordCmdStr}") @GetMapping("/record/{deviceId}/{recordCmdStr}")
public DeferredResult<ResponseEntity<String>> recordApi(@PathVariable String deviceId, public DeferredResult<ResponseEntity<String>> recordApi(@PathVariable String deviceId,
@PathVariable String recordCmdStr, @RequestParam(required = false) String channelId) { @PathVariable String recordCmdStr, String channelId) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("开始/停止录像API调用"); logger.debug("开始/停止录像API调用");
} }
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
cmder.recordCmd(device, channelId, recordCmdStr, event -> { String uuid = UUID.randomUUID().toString();
Response response = event.getResponse(); String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + channelId;
RequestMessage msg = new RequestMessage(); DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L);
msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (StringUtils.isEmpty(channelId) ? deviceId : channelId));
msg.setData(String.format("开始/停止录像操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeResult(msg);
});
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L);
result.onTimeout(() -> { result.onTimeout(() -> {
logger.warn(String.format("开始/停止录像操作超时, 设备未返回应答指令")); logger.warn(String.format("开始/停止录像操作超时, 设备未返回应答指令"));
// 释放rtpserver // 释放rtpserver
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (StringUtils.isEmpty(channelId) ? deviceId : channelId)); msg.setKey(key);
msg.setId(uuid);
msg.setData("Timeout. Device did not response to this command."); msg.setData("Timeout. Device did not response to this command.");
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
});
resultHolder.put(key, uuid, result);
if (resultHolder.exist(key, null)){
return result;
}
cmder.recordCmd(device, channelId, recordCmdStr, event -> {
Response response = event.getResponse();
RequestMessage msg = new RequestMessage();
msg.setId(uuid);
msg.setKey(key);
msg.setData(String.format("开始/停止录像操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeAllResult(msg);
}); });
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (StringUtils.isEmpty(channelId) ? deviceId : channelId), result);
return result; return result;
} }
@ -123,32 +133,38 @@ public class DeviceControl {
@ApiOperation("布防/撤防命令") @ApiOperation("布防/撤防命令")
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(name = "deviceId", value = "设备ID", required = true, dataTypeClass = String.class), @ApiImplicitParam(name = "deviceId", value = "设备ID", required = true, dataTypeClass = String.class),
@ApiImplicitParam(name = "channelId", value ="通道编码" ,dataTypeClass = String.class),
@ApiImplicitParam(name = "guardCmdStr", value ="命令, 可选值:SetGuard(布防),ResetGuard(撤防)", required = true, @ApiImplicitParam(name = "guardCmdStr", value ="命令, 可选值:SetGuard(布防),ResetGuard(撤防)", required = true,
dataTypeClass = String.class) dataTypeClass = String.class)
}) })
@GetMapping("/guard/{deviceId}/{guardCmdStr}") @GetMapping("/guard/{deviceId}/{guardCmdStr}")
public DeferredResult<ResponseEntity<String>> guardApi(@PathVariable String deviceId, @PathVariable String guardCmdStr) { public DeferredResult<ResponseEntity<String>> guardApi(@PathVariable String deviceId, String channelId, @PathVariable String guardCmdStr) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("布防/撤防API调用"); logger.debug("布防/撤防API调用");
} }
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + channelId;
String uuid =UUID.randomUUID().toString();
cmder.guardCmd(device, guardCmdStr, event -> { cmder.guardCmd(device, guardCmdStr, event -> {
Response response = event.getResponse(); Response response = event.getResponse();
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId); msg.setId(uuid);
msg.setKey(key);
msg.setData(String.format("布防/撤防操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); msg.setData(String.format("布防/撤防操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L); DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L);
resultHolder.put(key, uuid, result);
result.onTimeout(() -> { result.onTimeout(() -> {
logger.warn(String.format("布防/撤防操作超时, 设备未返回应答指令")); logger.warn(String.format("布防/撤防操作超时, 设备未返回应答指令"));
// 释放rtpserver // 释放rtpserver
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId); msg.setKey(key);
msg.setId(uuid);
msg.setData("Timeout. Device did not response to this command."); msg.setData("Timeout. Device did not response to this command.");
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId, result);
return result; return result;
} }
@ -162,21 +178,25 @@ public class DeviceControl {
@ApiOperation("报警复位") @ApiOperation("报警复位")
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(name = "deviceId", value = "设备ID", required = true, dataTypeClass = String.class), @ApiImplicitParam(name = "deviceId", value = "设备ID", required = true, dataTypeClass = String.class),
@ApiImplicitParam(name = "channelId", value ="通道编码" ,dataTypeClass = String.class),
@ApiImplicitParam(name = "alarmMethod", value ="报警方式", dataTypeClass = String.class), @ApiImplicitParam(name = "alarmMethod", value ="报警方式", dataTypeClass = String.class),
@ApiImplicitParam(name = "alarmType", value ="报警类型", dataTypeClass = String.class), @ApiImplicitParam(name = "alarmType", value ="报警类型", dataTypeClass = String.class),
}) })
@GetMapping("/reset_alarm/{deviceId}") @GetMapping("/reset_alarm/{deviceId}")
public DeferredResult<ResponseEntity<String>> resetAlarmApi(@PathVariable String deviceId, public DeferredResult<ResponseEntity<String>> resetAlarmApi(@PathVariable String deviceId, String channelId,
@RequestParam(required = false) String alarmMethod, @RequestParam(required = false) String alarmMethod,
@RequestParam(required = false) String alarmType) { @RequestParam(required = false) String alarmType) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("报警复位API调用"); logger.debug("报警复位API调用");
} }
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
String uuid = UUID.randomUUID().toString();
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + channelId;
cmder.alarmCmd(device, alarmMethod, alarmType, event -> { cmder.alarmCmd(device, alarmMethod, alarmType, event -> {
Response response = event.getResponse(); Response response = event.getResponse();
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId); msg.setId(uuid);
msg.setKey(key);
msg.setData(String.format("报警复位操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); msg.setData(String.format("报警复位操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
@ -185,11 +205,12 @@ public class DeviceControl {
logger.warn(String.format("报警复位操作超时, 设备未返回应答指令")); logger.warn(String.format("报警复位操作超时, 设备未返回应答指令"));
// 释放rtpserver // 释放rtpserver
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId); msg.setId(uuid);
msg.setKey(key);
msg.setData("Timeout. Device did not response to this command."); msg.setData("Timeout. Device did not response to this command.");
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId, result); resultHolder.put(key, uuid, result);
return result; return result;
} }
@ -236,6 +257,7 @@ public class DeviceControl {
@ApiOperation("看守位控制") @ApiOperation("看守位控制")
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(name = "deviceId", value = "设备ID", required = true, dataTypeClass = String.class), @ApiImplicitParam(name = "deviceId", value = "设备ID", required = true, dataTypeClass = String.class),
@ApiImplicitParam(name = "channelId", value ="通道编码" ,dataTypeClass = String.class),
@ApiImplicitParam(name = "enabled", value = "是否开启看守位 1:开启,0:关闭", required = true, dataTypeClass = String.class), @ApiImplicitParam(name = "enabled", value = "是否开启看守位 1:开启,0:关闭", required = true, dataTypeClass = String.class),
@ApiImplicitParam(name = "resetTime", value = "自动归位时间间隔", dataTypeClass = String.class), @ApiImplicitParam(name = "resetTime", value = "自动归位时间间隔", dataTypeClass = String.class),
@ApiImplicitParam(name = "presetIndex", value = "调用预置位编号", dataTypeClass = String.class), @ApiImplicitParam(name = "presetIndex", value = "调用预置位编号", dataTypeClass = String.class),
@ -246,15 +268,18 @@ public class DeviceControl {
@PathVariable String enabled, @PathVariable String enabled,
@RequestParam(required = false) String resetTime, @RequestParam(required = false) String resetTime,
@RequestParam(required = false) String presetIndex, @RequestParam(required = false) String presetIndex,
@RequestParam(required = false) String channelId) { String channelId) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("报警复位API调用"); logger.debug("报警复位API调用");
} }
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (StringUtils.isEmpty(channelId) ? deviceId : channelId);
String uuid = UUID.randomUUID().toString();
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
cmder.homePositionCmd(device, channelId, enabled, resetTime, presetIndex, event -> { cmder.homePositionCmd(device, channelId, enabled, resetTime, presetIndex, event -> {
Response response = event.getResponse(); Response response = event.getResponse();
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (StringUtils.isEmpty(channelId) ? deviceId : channelId)); msg.setId(uuid);
msg.setKey(key);
msg.setData(String.format("看守位控制操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); msg.setData(String.format("看守位控制操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
@ -263,7 +288,8 @@ public class DeviceControl {
logger.warn(String.format("看守位控制操作超时, 设备未返回应答指令")); logger.warn(String.format("看守位控制操作超时, 设备未返回应答指令"));
// 释放rtpserver // 释放rtpserver
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (StringUtils.isEmpty(channelId) ? deviceId : channelId)); msg.setId(uuid);
msg.setKey(key);
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("DeviceID", deviceId); json.put("DeviceID", deviceId);
json.put("Status", "Timeout"); json.put("Status", "Timeout");
@ -271,7 +297,7 @@ public class DeviceControl {
msg.setData(json); //("看守位控制操作超时, 设备未返回应答指令"); msg.setData(json); //("看守位控制操作超时, 设备未返回应答指令");
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (StringUtils.isEmpty(channelId) ? deviceId : channelId), result); resultHolder.put(key, uuid, result);
return result; return result;
} }
} }

52
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java

@ -24,6 +24,7 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import javax.sip.message.Response; import javax.sip.message.Response;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.UUID;
@Api(tags = "国标设备查询", value = "国标设备查询") @Api(tags = "国标设备查询", value = "国标设备查询")
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@ -143,23 +144,32 @@ public class DeviceQuery {
logger.debug("设备通道信息同步API调用,deviceId:" + deviceId); logger.debug("设备通道信息同步API调用,deviceId:" + deviceId);
} }
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
cmder.catalogQuery(device, event -> { String key = DeferredResultHolder.CALLBACK_CMD_CATALOG + deviceId;
Response response = event.getResponse(); String uuid = UUID.randomUUID().toString();
RequestMessage msg = new RequestMessage(); DeferredResult<ResponseEntity<Device>> result = new DeferredResult<ResponseEntity<Device>>(15*1000L);
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>>(15*1000L);
result.onTimeout(()->{ result.onTimeout(()->{
logger.warn(String.format("设备通道信息同步超时")); logger.warn(String.format("设备通道信息同步超时"));
// 释放rtpserver // 释放rtpserver
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId); msg.setKey(key);
msg.setId(uuid);
msg.setData("Timeout"); msg.setData("Timeout");
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
}); });
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result); // 等待其他相同请求返回时一起返回
if (resultHolder.exist(key, null)) {
return result;
}
cmder.catalogQuery(device, event -> {
Response response = event.getResponse();
RequestMessage msg = new RequestMessage();
msg.setKey(key);
msg.setId(uuid);
msg.setData(String.format("同步通道失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeAllResult(msg);
});
resultHolder.put(key, uuid, result);
return result; return result;
} }
@ -316,10 +326,13 @@ public class DeviceQuery {
logger.debug("设备状态查询API调用"); logger.debug("设备状态查询API调用");
} }
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
String uuid = UUID.randomUUID().toString();
String key = DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId;
cmder.deviceStatusQuery(device, event -> { cmder.deviceStatusQuery(device, event -> {
Response response = event.getResponse(); Response response = event.getResponse();
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId); msg.setId(uuid);
msg.setKey(key);
msg.setData(String.format("获取设备状态失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); msg.setData(String.format("获取设备状态失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
@ -328,11 +341,12 @@ public class DeviceQuery {
logger.warn(String.format("获取设备状态超时")); logger.warn(String.format("获取设备状态超时"));
// 释放rtpserver // 释放rtpserver
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId); msg.setId(uuid);
msg.setKey(key);
msg.setData("Timeout. Device did not response to this command."); msg.setData("Timeout. Device did not response to this command.");
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId, result); resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId, uuid, result);
return result; return result;
} }
@ -369,10 +383,13 @@ public class DeviceQuery {
logger.debug("设备报警查询API调用"); logger.debug("设备报警查询API调用");
} }
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
String key = DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId;
String uuid = UUID.randomUUID().toString();
cmder.alarmInfoQuery(device, startPriority, endPriority, alarmMethod, alarmType, startTime, endTime, event -> { cmder.alarmInfoQuery(device, startPriority, endPriority, alarmMethod, alarmType, startTime, endTime, event -> {
Response response = event.getResponse(); Response response = event.getResponse();
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId); msg.setId(uuid);
msg.setKey(key);
msg.setData(String.format("设备报警查询失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); msg.setData(String.format("设备报警查询失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
@ -381,11 +398,12 @@ public class DeviceQuery {
logger.warn(String.format("设备报警查询超时")); logger.warn(String.format("设备报警查询超时"));
// 释放rtpserver // 释放rtpserver
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId); msg.setId(uuid);
msg.setKey(key);
msg.setData("设备报警查询超时"); msg.setData("设备报警查询超时");
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId, result); resultHolder.put(DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId, uuid, result);
return result; return result;
} }

50
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java

@ -103,28 +103,31 @@ public class PlayController {
logger.debug(String.format("设备预览/回放停止API调用,streamId:%s_%s", deviceId, channelId )); logger.debug(String.format("设备预览/回放停止API调用,streamId:%s_%s", deviceId, channelId ));
UUID uuid = UUID.randomUUID(); String uuid = UUID.randomUUID().toString();
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(); DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>();
// 录像查询以channelId作为deviceId查询 // 录像查询以channelId作为deviceId查询
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_STOP + uuid, result); String key = DeferredResultHolder.CALLBACK_CMD_STOP + deviceId + channelId;
resultHolder.put(key, uuid, result);
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
cmder.streamByeCmd(deviceId, channelId, (event) -> { cmder.streamByeCmd(deviceId, channelId, (event) -> {
StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
if (streamInfo == null) { if (streamInfo == null) {
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_STOP + uuid); msg.setId(uuid);
msg.setKey(key);
msg.setData("点播未找到"); msg.setData("点播未找到");
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
storager.stopPlay(deviceId, channelId); storager.stopPlay(deviceId, channelId);
}else { }else {
redisCatchStorage.stopPlay(streamInfo); redisCatchStorage.stopPlay(streamInfo);
storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_STOP + uuid); msg.setId(uuid);
msg.setKey(key);
//Response response = event.getResponse(); //Response response = event.getResponse();
msg.setData(String.format("success")); msg.setData(String.format("success"));
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
} }
mediaServerService.closeRTPServer(device, channelId); mediaServerService.closeRTPServer(device, channelId);
}); });
@ -134,24 +137,27 @@ public class PlayController {
json.put("deviceId", deviceId); json.put("deviceId", deviceId);
json.put("channelId", channelId); json.put("channelId", channelId);
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid); msg.setId(uuid);
msg.setKey(key);
msg.setData(json.toString()); msg.setData(json.toString());
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
} else { } else {
logger.warn("设备预览/回放停止API调用失败!"); logger.warn("设备预览/回放停止API调用失败!");
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid); msg.setId(uuid);
msg.setKey(key);
msg.setData("streamId null"); msg.setData("streamId null");
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
} }
// 超时处理 // 超时处理
result.onTimeout(()->{ result.onTimeout(()->{
logger.warn(String.format("设备预览/回放停止超时,deviceId/channelId:%s_%s ", deviceId, channelId)); logger.warn(String.format("设备预览/回放停止超时,deviceId/channelId:%s_%s ", deviceId, channelId));
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_STOP + uuid); msg.setId(uuid);
msg.setKey(key);
msg.setData("Timeout"); msg.setData("Timeout");
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
}); });
return result; return result;
} }
@ -259,10 +265,18 @@ public class PlayController {
} }
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L); DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L);
String key = DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId;
if (resultHolder.exist(key, null)) {
result.setResult(new ResponseEntity<>("设备使用中",HttpStatus.OK));
return result;
}
String uuid = UUID.randomUUID().toString();
if (device == null) { if (device == null) {
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId, result);
resultHolder.put(key, key, result);
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId); msg.setKey(key);
msg.setId(uuid);
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("DeviceID", deviceId); json.put("DeviceID", deviceId);
json.put("CmdType", "Broadcast"); json.put("CmdType", "Broadcast");
@ -275,7 +289,8 @@ public class PlayController {
cmder.audioBroadcastCmd(device, (event) -> { cmder.audioBroadcastCmd(device, (event) -> {
Response response = event.getResponse(); Response response = event.getResponse();
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId); msg.setKey(key);
msg.setId(uuid);
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("DeviceID", deviceId); json.put("DeviceID", deviceId);
json.put("CmdType", "Broadcast"); json.put("CmdType", "Broadcast");
@ -288,7 +303,8 @@ public class PlayController {
result.onTimeout(() -> { result.onTimeout(() -> {
logger.warn(String.format("语音广播操作超时, 设备未返回应答指令")); logger.warn(String.format("语音广播操作超时, 设备未返回应答指令"));
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId); msg.setKey(key);
msg.setId(uuid);
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("DeviceID", deviceId); json.put("DeviceID", deviceId);
json.put("CmdType", "Broadcast"); json.put("CmdType", "Broadcast");
@ -297,7 +313,7 @@ public class PlayController {
msg.setData(json); msg.setData(json);
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId, result); resultHolder.put(key, uuid, result);
return result; return result;
} }

24
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java

@ -76,30 +76,37 @@ public class DownloadController {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug(String.format("历史媒体下载 API调用,deviceId:%s,channelId:%s,downloadSpeed:%s", deviceId, channelId, downloadSpeed)); logger.debug(String.format("历史媒体下载 API调用,deviceId:%s,channelId:%s,downloadSpeed:%s", deviceId, channelId, downloadSpeed));
} }
UUID uuid = UUID.randomUUID(); String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId + startTime + endTime;
String uuid = UUID.randomUUID().toString();
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(30000L); DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(30000L);
// 超时处理 // 超时处理
result.onTimeout(()->{ result.onTimeout(()->{
logger.warn(String.format("设备下载响应超时,deviceId:%s ,channelId:%s", deviceId, channelId)); logger.warn(String.format("设备下载响应超时,deviceId:%s ,channelId:%s", deviceId, channelId));
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid); msg.setId(uuid);
msg.setKey(key);
msg.setData("Timeout"); msg.setData("Timeout");
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
}); });
resultHolder.put(key, uuid, result);
if(resultHolder.exist(key, null)) {
return result;
}
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId); StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId);
if (streamInfo != null) { if (streamInfo != null) {
// 停止之前的下载 // 停止之前的下载
cmder.streamByeCmd(deviceId, channelId); cmder.streamByeCmd(deviceId, channelId);
} }
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid, result);
MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
if (newMediaServerItem == null) { if (newMediaServerItem == null) {
logger.warn(String.format("设备下载响应超时,deviceId:%s ,channelId:%s", deviceId, channelId)); logger.warn(String.format("设备下载响应超时,deviceId:%s ,channelId:%s", deviceId, channelId));
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid); msg.setId(uuid);
msg.setKey(key);
msg.setData("Timeout"); msg.setData("Timeout");
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
return result; return result;
} }
@ -111,9 +118,10 @@ public class DownloadController {
}, event -> { }, event -> {
Response response = event.getResponse(); Response response = event.getResponse();
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid); msg.setId(uuid);
msg.setKey(key);
msg.setData(String.format("回放失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); msg.setData(String.format("回放失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeResult(msg); resultHolder.invokeAllResult(msg);
}); });
return result; return result;

15
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java

@ -76,9 +76,9 @@ public class PlaybackController {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId)); logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId));
} }
UUID uuid = UUID.randomUUID(); String uuid = UUID.randomUUID().toString();
String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId + startTime + endTime;
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(30000L); DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(30000L);
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
if (device == null) { if (device == null) {
result.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST)); result.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST));
@ -91,7 +91,8 @@ public class PlaybackController {
result.onTimeout(()->{ result.onTimeout(()->{
logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId));
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid); msg.setId(uuid);
msg.setKey(key);
msg.setData("Timeout"); msg.setData("Timeout");
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
@ -101,12 +102,13 @@ public class PlaybackController {
// 停止之前的回放 // 停止之前的回放
cmder.streamByeCmd(deviceId, channelId); cmder.streamByeCmd(deviceId, channelId);
} }
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid, result); resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId + startTime + endTime, uuid, result);
if (newMediaServerItem == null) { if (newMediaServerItem == null) {
logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId));
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid); msg.setId(uuid);
msg.setKey(key);
msg.setData("Timeout"); msg.setData("Timeout");
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
return result; return result;
@ -118,7 +120,8 @@ public class PlaybackController {
}, event -> { }, event -> {
Response response = event.getResponse(); Response response = event.getResponse();
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PLAY + uuid); msg.setId(uuid);
msg.setKey(key);
msg.setData(String.format("回放失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); msg.setData(String.format("回放失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });

30
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/ptz/PtzController.java

@ -21,6 +21,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import java.util.UUID;
@Api(tags = "云台控制") @Api(tags = "云台控制")
@CrossOrigin @CrossOrigin
@RestController @RestController
@ -101,23 +103,31 @@ public class PtzController {
logger.debug("设备预置位查询API调用"); logger.debug("设备预置位查询API调用");
} }
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
cmder.presetQuery(device, channelId, event -> { String uuid = UUID.randomUUID().toString();
Response response = event.getResponse(); String key = DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + (StringUtils.isEmpty(channelId) ? deviceId : channelId);
RequestMessage msg = new RequestMessage(); DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String >> (3 * 1000L);
msg.setId(DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + (StringUtils.isEmpty(channelId) ? deviceId : channelId));
msg.setData(String.format("获取设备预置位失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeResult(msg);
});
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String >> (3 * 1000L);
result.onTimeout(()->{ result.onTimeout(()->{
logger.warn(String.format("获取设备预置位超时")); logger.warn(String.format("获取设备预置位超时"));
// 释放rtpserver // 释放rtpserver
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + (StringUtils.isEmpty(channelId) ? deviceId : channelId)); msg.setId(uuid);
msg.setKey(key);
msg.setData("获取设备预置位超时"); msg.setData("获取设备预置位超时");
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + (StringUtils.isEmpty(channelId) ? deviceId : channelId), result); resultHolder.put(key, uuid, result);
if (resultHolder.exist(key, null)) {
return result;
}
cmder.presetQuery(device, channelId, event -> {
Response response = event.getResponse();
RequestMessage msg = new RequestMessage();
msg.setId(uuid);
msg.setKey(key);
msg.setData(String.format("获取设备预置位失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
resultHolder.invokeResult(msg);
});
return result; return result;
} }
} }

12
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/record/GBRecordController.java

@ -22,6 +22,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.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import java.util.UUID;
@Api(tags = "国标录像") @Api(tags = "国标录像")
@CrossOrigin @CrossOrigin
@RestController @RestController
@ -56,13 +58,15 @@ public class GBRecordController {
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
cmder.recordInfoQuery(device, channelId, startTime, endTime); cmder.recordInfoQuery(device, channelId, startTime, endTime);
// 指定超时时间 1分钟30秒 // 指定超时时间 1分钟30秒
DeferredResult<ResponseEntity<RecordInfo>> result = new DeferredResult<ResponseEntity<RecordInfo>>(90*1000L); DeferredResult<ResponseEntity<RecordInfo>> result = new DeferredResult<>(90*1000L);
String uuid = UUID.randomUUID().toString();
String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + deviceId + channelId;
// 录像查询以channelId作为deviceId查询 // 录像查询以channelId作为deviceId查询
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_RECORDINFO+channelId, result); resultHolder.put(key, uuid, result);
result.onTimeout(()->{ result.onTimeout(()->{
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setDeviceId(deviceId); msg.setId(uuid);
msg.setType(DeferredResultHolder.CALLBACK_CMD_RECORDINFO); msg.setKey(key);
msg.setData("timeout"); msg.setData("timeout");
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });

14
src/main/java/com/genersoft/iot/vmp/vmanager/onvif/ONVIFController.java

@ -40,17 +40,18 @@ public class ONVIFController {
@ResponseBody @ResponseBody
public DeferredResult<ResponseEntity<WVPResult>> search(@RequestParam(required = false)Integer timeout){ public DeferredResult<ResponseEntity<WVPResult>> search(@RequestParam(required = false)Integer timeout){
DeferredResult<ResponseEntity<WVPResult>> result = new DeferredResult<>(timeout + 10L); DeferredResult<ResponseEntity<WVPResult>> result = new DeferredResult<>(timeout + 10L);
UUID uuid = UUID.randomUUID(); String uuid = UUID.randomUUID().toString();
result.onTimeout(()->{ result.onTimeout(()->{
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_ONVIF + uuid); msg.setKey(DeferredResultHolder.CALLBACK_ONVIF );
msg.setId(uuid);
WVPResult<String> wvpResult = new WVPResult(); WVPResult<String> wvpResult = new WVPResult();
wvpResult.setCode(0); wvpResult.setCode(0);
wvpResult.setMsg("搜索超时"); wvpResult.setMsg("搜索超时");
msg.setData(wvpResult); msg.setData(wvpResult);
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
resultHolder.put(DeferredResultHolder.CALLBACK_ONVIF + uuid, result); resultHolder.put(DeferredResultHolder.CALLBACK_ONVIF, uuid, result);
onvifServer.search(timeout, (errorCode, onvifDevices) ->{ onvifServer.search(timeout, (errorCode, onvifDevices) ->{
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
@ -87,17 +88,18 @@ public class ONVIFController {
){ ){
DeferredResult<ResponseEntity<WVPResult>> result = new DeferredResult<>(timeout + 10L); DeferredResult<ResponseEntity<WVPResult>> result = new DeferredResult<>(timeout + 10L);
UUID uuid = UUID.randomUUID(); String uuid = UUID.randomUUID().toString();
result.onTimeout(()->{ result.onTimeout(()->{
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_ONVIF + uuid); msg.setId(uuid);
msg.setKey(DeferredResultHolder.CALLBACK_ONVIF);
WVPResult<String> wvpResult = new WVPResult(); WVPResult<String> wvpResult = new WVPResult();
wvpResult.setCode(0); wvpResult.setCode(0);
wvpResult.setMsg("获取onvif的rtsp地址超时"); wvpResult.setMsg("获取onvif的rtsp地址超时");
msg.setData(wvpResult); msg.setData(wvpResult);
resultHolder.invokeResult(msg); resultHolder.invokeResult(msg);
}); });
resultHolder.put(DeferredResultHolder.CALLBACK_ONVIF + uuid, result); resultHolder.put(DeferredResultHolder.CALLBACK_ONVIF, uuid, result);
OnvifDevice onvifDevice = new OnvifDevice(hostname, username, password); OnvifDevice onvifDevice = new OnvifDevice(hostname, username, password);
onvifServer.getRTSPUrl(timeout, onvifDevice, (errorCode, url) ->{ onvifServer.getRTSPUrl(timeout, onvifDevice, (errorCode, url) ->{
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();

1
web_src/src/components/MediaServerManger.vue

@ -127,7 +127,6 @@
} }
} }
console.log("aadada: "+ resultVal)
return resultVal; return resultVal;
}, },
dateFormat: function(/** timestamp=0 **/) { dateFormat: function(/** timestamp=0 **/) {

Loading…
Cancel
Save