Commit d7a1b94f905c5f28c9c8f2d48c3f9e28ebcf9cc4

Authored by 648540858
2 parents ab74d1cf a574ff09

Merge branch 'wvp-28181-2.0'

# Conflicts:
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java
Showing 67 changed files with 1532 additions and 1237 deletions

Too many changes to show.

To preserve performance only 67 of 76 files are displayed.

src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
@@ -64,8 +64,8 @@ public class MediaConfig{ @@ -64,8 +64,8 @@ public class MediaConfig{
64 @Value("${media.secret}") 64 @Value("${media.secret}")
65 private String secret; 65 private String secret;
66 66
67 - @Value("${media.stream-none-reader-delay-ms:10000}")  
68 - private int streamNoneReaderDelayMS = 10000; 67 + @Value("${media.stream-none-reader-delay-ms:15000}")
  68 + private int streamNoneReaderDelayMS = 15000;
69 69
70 @Value("${media.rtp.enable}") 70 @Value("${media.rtp.enable}")
71 private boolean rtpEnable; 71 private boolean rtpEnable;
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
@@ -31,6 +31,8 @@ public class UserSetting { @@ -31,6 +31,8 @@ public class UserSetting {
31 31
32 private Boolean logInDatebase = Boolean.TRUE; 32 private Boolean logInDatebase = Boolean.TRUE;
33 33
  34 + private Boolean usePushingAsStatus = Boolean.TRUE;
  35 +
34 private String serverId = "000000"; 36 private String serverId = "000000";
35 37
36 private String thirdPartyGBIdReg = "[\\s\\S]*"; 38 private String thirdPartyGBIdReg = "[\\s\\S]*";
@@ -136,4 +138,12 @@ public class UserSetting { @@ -136,4 +138,12 @@ public class UserSetting {
136 public void setPlatformPlayTimeout(int platformPlayTimeout) { 138 public void setPlatformPlayTimeout(int platformPlayTimeout) {
137 this.platformPlayTimeout = platformPlayTimeout; 139 this.platformPlayTimeout = platformPlayTimeout;
138 } 140 }
  141 +
  142 + public Boolean isUsePushingAsStatus() {
  143 + return usePushingAsStatus;
  144 + }
  145 +
  146 + public void setUsePushingAsStatus(Boolean usePushingAsStatus) {
  147 + this.usePushingAsStatus = usePushingAsStatus;
  148 + }
139 } 149 }
src/main/java/com/genersoft/iot/vmp/conf/redis/RedisConfig.java
@@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.conf.redis; @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.conf.redis;
3 3
4 import com.alibaba.fastjson.parser.ParserConfig; 4 import com.alibaba.fastjson.parser.ParserConfig;
5 import com.genersoft.iot.vmp.common.VideoManagerConstants; 5 import com.genersoft.iot.vmp.common.VideoManagerConstants;
6 -import com.genersoft.iot.vmp.service.impl.*; 6 +import com.genersoft.iot.vmp.service.redisMsg.*;
7 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.cache.annotation.CachingConfigurerSupport; 8 import org.springframework.cache.annotation.CachingConfigurerSupport;
9 import org.springframework.context.annotation.Bean; 9 import org.springframework.context.annotation.Bean;
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
1 package com.genersoft.iot.vmp.gb28181; 1 package com.genersoft.iot.vmp.gb28181;
2 2
3 import com.genersoft.iot.vmp.conf.SipConfig; 3 import com.genersoft.iot.vmp.conf.SipConfig;
  4 +import com.genersoft.iot.vmp.gb28181.conf.DefaultProperties;
4 import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver; 5 import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver;
5 import gov.nist.javax.sip.SipProviderImpl; 6 import gov.nist.javax.sip.SipProviderImpl;
6 import gov.nist.javax.sip.SipStackImpl; 7 import gov.nist.javax.sip.SipStackImpl;
@@ -41,43 +42,7 @@ public class SipLayer{ @@ -41,43 +42,7 @@ public class SipLayer{
41 @Bean("sipStack") 42 @Bean("sipStack")
42 @DependsOn({"sipFactory"}) 43 @DependsOn({"sipFactory"})
43 SipStack createSipStack() throws PeerUnavailableException { 44 SipStack createSipStack() throws PeerUnavailableException {
44 - Properties properties = new Properties();  
45 - properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");  
46 - properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getMonitorIp());  
47 - /**  
48 - * 完整配置参考 gov.nist.javax.sip.SipStackImpl,需要下载源码  
49 - * gov/nist/javax/sip/SipStackImpl.class  
50 - * sip消息的解析在 gov.nist.javax.sip.stack.UDPMessageChannel的processIncomingDataPacket方法  
51 - */  
52 -  
53 -// * gov/nist/javax/sip/SipStackImpl.class  
54 - if (logger.isDebugEnabled()) {  
55 - properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false");  
56 - }  
57 - // 接收所有notify请求,即使没有订阅  
58 - properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true");  
59 - properties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false");  
60 - properties.setProperty("gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED", "false");  
61 - // 为_NULL _对话框传递_终止的_事件  
62 - properties.setProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG", "true");  
63 - // 会话清理策略  
64 - properties.setProperty("gov.nist.javax.sip.RELEASE_REFERENCES_STRATEGY", "Normal");  
65 - // 处理由该服务器处理的基于底层TCP的保持生存超时  
66 - properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "60");  
67 - // 获取实际内容长度,不使用header中的长度信息  
68 - properties.setProperty("gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY", "true");  
69 -  
70 - /**  
71 - * sip_server_log.log 和 sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE  
72 - */  
73 - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "ERROR");  
74 -// properties.setProperty("gov.nist.javax.sip.SIP_MESSAGE_VALVE", "com.genersoft.iot.vmp.gb28181.session.SipMessagePreprocessing");  
75 -// if (logger.isDebugEnabled()) {  
76 -// properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "DEBUG");  
77 -// }  
78 -  
79 - sipStack = (SipStackImpl) sipFactory.createSipStack(properties);  
80 - 45 + sipStack = ( SipStackImpl )sipFactory.createSipStack(DefaultProperties.getProperties(sipConfig.getMonitorIp(), false));
81 return sipStack; 46 return sipStack;
82 } 47 }
83 48
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
@@ -381,4 +381,5 @@ public class Device { @@ -381,4 +381,5 @@ public class Device {
381 public void setTreeType(String treeType) { 381 public void setTreeType(String treeType) {
382 this.treeType = treeType; 382 this.treeType = treeType;
383 } 383 }
  384 +
384 } 385 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java
1 package com.genersoft.iot.vmp.gb28181.bean; 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2
  3 +import gov.nist.javax.sip.message.SIPRequest;
  4 +
3 public class SendRtpItem { 5 public class SendRtpItem {
4 6
5 /** 7 /**
@@ -77,11 +79,21 @@ public class SendRtpItem { @@ -77,11 +79,21 @@ public class SendRtpItem {
77 private String serverId; 79 private String serverId;
78 80
79 /** 81 /**
80 - * invitecallId 82 + * invitecallId
81 */ 83 */
82 private String CallId; 84 private String CallId;
83 85
84 /** 86 /**
  87 + * invite 的 fromTag
  88 + */
  89 + private String fromTag;
  90 +
  91 + /**
  92 + * invite 的 toTag
  93 + */
  94 + private String toTag;
  95 +
  96 + /**
85 * 发送时,rtp的pt(uint8_t),不传时默认为96 97 * 发送时,rtp的pt(uint8_t),不传时默认为96
86 */ 98 */
87 private int pt = 96; 99 private int pt = 96;
@@ -96,15 +108,12 @@ public class SendRtpItem { @@ -96,15 +108,12 @@ public class SendRtpItem {
96 */ 108 */
97 private boolean onlyAudio = false; 109 private boolean onlyAudio = false;
98 110
  111 +
99 /** 112 /**
100 * 播放类型 113 * 播放类型
101 */ 114 */
102 private InviteStreamType playType; 115 private InviteStreamType playType;
103 116
104 - private byte[] transaction;  
105 -  
106 - private byte[] dialog;  
107 -  
108 public String getIp() { 117 public String getIp() {
109 return ip; 118 return ip;
110 } 119 }
@@ -225,22 +234,6 @@ public class SendRtpItem { @@ -225,22 +234,6 @@ public class SendRtpItem {
225 this.playType = playType; 234 this.playType = playType;
226 } 235 }
227 236
228 - public byte[] getTransaction() {  
229 - return transaction;  
230 - }  
231 -  
232 - public void setTransaction(byte[] transaction) {  
233 - this.transaction = transaction;  
234 - }  
235 -  
236 - public byte[] getDialog() {  
237 - return dialog;  
238 - }  
239 -  
240 - public void setDialog(byte[] dialog) {  
241 - this.dialog = dialog;  
242 - }  
243 -  
244 public int getPt() { 237 public int getPt() {
245 return pt; 238 return pt;
246 } 239 }
@@ -272,4 +265,20 @@ public class SendRtpItem { @@ -272,4 +265,20 @@ public class SendRtpItem {
272 public void setServerId(String serverId) { 265 public void setServerId(String serverId) {
273 this.serverId = serverId; 266 this.serverId = serverId;
274 } 267 }
  268 +
  269 + public String getFromTag() {
  270 + return fromTag;
  271 + }
  272 +
  273 + public void setFromTag(String fromTag) {
  274 + this.fromTag = fromTag;
  275 + }
  276 +
  277 + public String getToTag() {
  278 + return toTag;
  279 + }
  280 +
  281 + public void setToTag(String toTag) {
  282 + this.toTag = toTag;
  283 + }
275 } 284 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SipMsgInfo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +import org.dom4j.Element;
  4 +
  5 +import javax.sip.RequestEvent;
  6 +
  7 +public class SipMsgInfo {
  8 + private RequestEvent evt;
  9 + private Device device;
  10 + private ParentPlatform platform;
  11 + private Element rootElement;
  12 +
  13 + public SipMsgInfo(RequestEvent evt, Device device, Element rootElement) {
  14 + this.evt = evt;
  15 + this.device = device;
  16 + this.rootElement = rootElement;
  17 + }
  18 +
  19 + public SipMsgInfo(RequestEvent evt, ParentPlatform platform, Element rootElement) {
  20 + this.evt = evt;
  21 + this.platform = platform;
  22 + this.rootElement = rootElement;
  23 + }
  24 +
  25 + public RequestEvent getEvt() {
  26 + return evt;
  27 + }
  28 +
  29 + public void setEvt(RequestEvent evt) {
  30 + this.evt = evt;
  31 + }
  32 +
  33 + public Device getDevice() {
  34 + return device;
  35 + }
  36 +
  37 + public void setDevice(Device device) {
  38 + this.device = device;
  39 + }
  40 +
  41 + public ParentPlatform getPlatform() {
  42 + return platform;
  43 + }
  44 +
  45 + public void setPlatform(ParentPlatform platform) {
  46 + this.platform = platform;
  47 + }
  48 +
  49 + public Element getRootElement() {
  50 + return rootElement;
  51 + }
  52 +
  53 + public void setRootElement(Element rootElement) {
  54 + this.rootElement = rootElement;
  55 + }
  56 +}
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SipTransactionInfo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +import gov.nist.javax.sip.message.SIPRequest;
  4 +
  5 +public class SipTransactionInfo {
  6 +
  7 + private String callId;
  8 + private String fromTag;
  9 + private String toTag;
  10 + private String viaBranch;
  11 +
  12 + public SipTransactionInfo(SIPRequest request) {
  13 + this.callId = request.getCallIdHeader().getCallId();
  14 + this.fromTag = request.getFromTag();
  15 + this.toTag = request.getToTag();
  16 + this.viaBranch = request.getTopmostViaHeader().getBranch();
  17 + }
  18 +
  19 + public SipTransactionInfo() {
  20 + }
  21 +
  22 + public String getCallId() {
  23 + return callId;
  24 + }
  25 +
  26 + public void setCallId(String callId) {
  27 + this.callId = callId;
  28 + }
  29 +
  30 + public String getFromTag() {
  31 + return fromTag;
  32 + }
  33 +
  34 + public void setFromTag(String fromTag) {
  35 + this.fromTag = fromTag;
  36 + }
  37 +
  38 + public String getToTag() {
  39 + return toTag;
  40 + }
  41 +
  42 + public void setToTag(String toTag) {
  43 + this.toTag = toTag;
  44 + }
  45 +
  46 + public String getViaBranch() {
  47 + return viaBranch;
  48 + }
  49 +
  50 + public void setViaBranch(String viaBranch) {
  51 + this.viaBranch = viaBranch;
  52 + }
  53 +}
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java
@@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.conf.DynamicTask; @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.conf.DynamicTask;
5 import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; 5 import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask;
6 import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeHandlerTask; 6 import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeHandlerTask;
7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; 7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
  8 +import com.genersoft.iot.vmp.service.IPlatformService;
8 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 9 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
9 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 10 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
10 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.beans.factory.annotation.Autowired;
@@ -23,15 +24,6 @@ public class SubscribeHolder { @@ -23,15 +24,6 @@ public class SubscribeHolder {
23 @Autowired 24 @Autowired
24 private DynamicTask dynamicTask; 25 private DynamicTask dynamicTask;
25 26
26 - @Autowired  
27 - private IRedisCatchStorage redisCatchStorage;  
28 -  
29 - @Autowired  
30 - private ISIPCommanderForPlatform sipCommanderForPlatform;  
31 -  
32 - @Autowired  
33 - private IVideoManagerStorage storager;  
34 -  
35 private final String taskOverduePrefix = "subscribe_overdue_"; 27 private final String taskOverduePrefix = "subscribe_overdue_";
36 28
37 private static ConcurrentHashMap<String, SubscribeInfo> catalogMap = new ConcurrentHashMap<>(); 29 private static ConcurrentHashMap<String, SubscribeInfo> catalogMap = new ConcurrentHashMap<>();
@@ -62,15 +54,13 @@ public class SubscribeHolder { @@ -62,15 +54,13 @@ public class SubscribeHolder {
62 } 54 }
63 // 添加任务处理订阅过期 55 // 添加任务处理订阅过期
64 dynamicTask.stop(taskOverdueKey); 56 dynamicTask.stop(taskOverdueKey);
65 -  
66 } 57 }
67 58
68 public void putMobilePositionSubscribe(String platformId, SubscribeInfo subscribeInfo) { 59 public void putMobilePositionSubscribe(String platformId, SubscribeInfo subscribeInfo) {
69 mobilePositionMap.put(platformId, subscribeInfo); 60 mobilePositionMap.put(platformId, subscribeInfo);
70 String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + "MobilePosition_" + platformId; 61 String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + "MobilePosition_" + platformId;
71 // 添加任务处理GPS定时推送 62 // 添加任务处理GPS定时推送
72 - dynamicTask.startCron(key, new MobilePositionSubscribeHandlerTask(redisCatchStorage, sipCommanderForPlatform,  
73 - storager, platformId, subscribeInfo.getSn(), key, this, dynamicTask), 63 + dynamicTask.startCron(key, new MobilePositionSubscribeHandlerTask(platformId),
74 subscribeInfo.getGpsInterval() * 1000); 64 subscribeInfo.getGpsInterval() * 1000);
75 String taskOverdueKey = taskOverduePrefix + "MobilePosition_" + platformId; 65 String taskOverdueKey = taskOverduePrefix + "MobilePosition_" + platformId;
76 // 添加任务处理订阅过期 66 // 添加任务处理订阅过期
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java
1 package com.genersoft.iot.vmp.gb28181.bean; 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2
3 import com.genersoft.iot.vmp.utils.SerializeUtils; 3 import com.genersoft.iot.vmp.utils.SerializeUtils;
  4 +import gov.nist.javax.sip.message.SIPRequest;
  5 +import gov.nist.javax.sip.message.SIPResponse;
4 6
  7 +import javax.sip.ClientTransaction;
5 import javax.sip.Dialog; 8 import javax.sip.Dialog;
6 import javax.sip.RequestEvent; 9 import javax.sip.RequestEvent;
7 import javax.sip.ServerTransaction; 10 import javax.sip.ServerTransaction;
@@ -11,30 +14,24 @@ import javax.sip.message.Request; @@ -11,30 +14,24 @@ import javax.sip.message.Request;
11 public class SubscribeInfo { 14 public class SubscribeInfo {
12 15
13 16
14 - public SubscribeInfo(RequestEvent evt, String id) { 17 + public SubscribeInfo(ServerTransaction serverTransaction, String id) {
15 this.id = id; 18 this.id = id;
16 - Request request = evt.getRequest();  
17 - ExpiresHeader expiresHeader = (ExpiresHeader)request.getHeader(ExpiresHeader.NAME);  
18 - this.expires = expiresHeader.getExpires(); 19 + SIPRequest request = (SIPRequest)serverTransaction.getRequest();
  20 + this.request = request;
  21 + this.expires = request.getExpires().getExpires();
19 EventHeader eventHeader = (EventHeader)request.getHeader(EventHeader.NAME); 22 EventHeader eventHeader = (EventHeader)request.getHeader(EventHeader.NAME);
20 this.eventId = eventHeader.getEventId(); 23 this.eventId = eventHeader.getEventId();
21 this.eventType = eventHeader.getEventType(); 24 this.eventType = eventHeader.getEventType();
22 - this.transaction = evt.getServerTransaction();  
23 - this.dialog = evt.getDialog();  
24 - CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);  
25 - this.callId = callIdHeader.getCallId();  
26 - }  
27 25
28 - public SubscribeInfo() {  
29 } 26 }
30 27
31 private String id; 28 private String id;
  29 +
  30 + private SIPRequest request;
32 private int expires; 31 private int expires;
33 - private String callId;  
34 private String eventId; 32 private String eventId;
35 private String eventType; 33 private String eventType;
36 - private ServerTransaction transaction;  
37 - private Dialog dialog; 34 + private SIPResponse response;
38 35
39 /** 36 /**
40 * 以下为可选字段 37 * 以下为可选字段
@@ -43,29 +40,28 @@ public class SubscribeInfo { @@ -43,29 +40,28 @@ public class SubscribeInfo {
43 private String sn; 40 private String sn;
44 private int gpsInterval; 41 private int gpsInterval;
45 42
46 -  
47 public String getId() { 43 public String getId() {
48 return id; 44 return id;
49 } 45 }
50 46
51 - public int getExpires() {  
52 - return expires; 47 + public void setId(String id) {
  48 + this.id = id;
53 } 49 }
54 50
55 - public String getCallId() {  
56 - return callId; 51 + public SIPRequest getRequest() {
  52 + return request;
57 } 53 }
58 54
59 - public void setId(String id) {  
60 - this.id = id; 55 + public void setRequest(SIPRequest request) {
  56 + this.request = request;
61 } 57 }
62 58
63 - public void setExpires(int expires) {  
64 - this.expires = expires; 59 + public int getExpires() {
  60 + return expires;
65 } 61 }
66 62
67 - public void setCallId(String callId) {  
68 - this.callId = callId; 63 + public void setExpires(int expires) {
  64 + this.expires = expires;
69 } 65 }
70 66
71 public String getEventId() { 67 public String getEventId() {
@@ -84,20 +80,12 @@ public class SubscribeInfo { @@ -84,20 +80,12 @@ public class SubscribeInfo {
84 this.eventType = eventType; 80 this.eventType = eventType;
85 } 81 }
86 82
87 - public ServerTransaction getTransaction() {  
88 - return transaction;  
89 - }  
90 -  
91 - public void setTransaction(ServerTransaction transaction) {  
92 - this.transaction = transaction;  
93 - }  
94 -  
95 - public Dialog getDialog() {  
96 - return dialog; 83 + public SIPResponse getResponse() {
  84 + return response;
97 } 85 }
98 86
99 - public void setDialog(Dialog dialog) {  
100 - this.dialog = dialog; 87 + public void setResponse(SIPResponse response) {
  88 + this.response = response;
101 } 89 }
102 90
103 public String getSn() { 91 public String getSn() {
src/main/java/com/genersoft/iot/vmp/gb28181/conf/DefaultProperties.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.conf;
  2 +
  3 +import java.util.Properties;
  4 +
  5 +/**
  6 + * 获取sip默认配置
  7 + * @author lin
  8 + */
  9 +public class DefaultProperties {
  10 +
  11 + public static Properties getProperties(String ip, boolean isDebug) {
  12 + Properties properties = new Properties();
  13 + properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
  14 + properties.setProperty("javax.sip.IP_ADDRESS", ip);
  15 + properties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off");
  16 + /**
  17 + * 完整配置参考 gov.nist.javax.sip.SipStackImpl,需要下载源码
  18 + * gov/nist/javax/sip/SipStackImpl.class
  19 + * sip消息的解析在 gov.nist.javax.sip.stack.UDPMessageChannel的processIncomingDataPacket方法
  20 + */
  21 +
  22 +// * gov/nist/javax/sip/SipStackImpl.class
  23 + if (isDebug) {
  24 + properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false");
  25 + }
  26 + // 接收所有notify请求,即使没有订阅
  27 + properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true");
  28 + properties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false");
  29 + properties.setProperty("gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED", "false");
  30 + // 为_NULL _对话框传递_终止的_事件
  31 + properties.setProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG", "true");
  32 + // 会话清理策略
  33 + properties.setProperty("gov.nist.javax.sip.RELEASE_REFERENCES_STRATEGY", "Normal");
  34 + // 处理由该服务器处理的基于底层TCP的保持生存超时
  35 + properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "60");
  36 + // 获取实际内容长度,不使用header中的长度信息
  37 + properties.setProperty("gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY", "true");
  38 +
  39 + /**
  40 + * sip_server_log.log 和 sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE
  41 + */
  42 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "ERROR");
  43 +
  44 + return properties;
  45 + }
  46 +}
src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
1 package com.genersoft.iot.vmp.gb28181.event; 1 package com.genersoft.iot.vmp.gb28181.event;
2 2
3 import com.genersoft.iot.vmp.gb28181.bean.DeviceNotFoundEvent; 3 import com.genersoft.iot.vmp.gb28181.bean.DeviceNotFoundEvent;
  4 +import gov.nist.javax.sip.message.SIPRequest;
4 import org.slf4j.Logger; 5 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory; 6 import org.slf4j.LoggerFactory;
6 import org.springframework.scheduling.annotation.Scheduled; 7 import org.springframework.scheduling.annotation.Scheduled;
@@ -104,22 +105,27 @@ public class SipSubscribe { @@ -104,22 +105,27 @@ public class SipSubscribe {
104 this.type = EventResultType.timeout; 105 this.type = EventResultType.timeout;
105 this.msg = "消息超时未回复"; 106 this.msg = "消息超时未回复";
106 this.statusCode = -1024; 107 this.statusCode = -1024;
107 - this.dialog = timeoutEvent.getClientTransaction().getDialog();  
108 - this.callId = this.dialog != null?timeoutEvent.getClientTransaction().getDialog().getCallId().getCallId(): null; 108 + if (timeoutEvent.isServerTransaction()) {
  109 + this.callId = ((SIPRequest)timeoutEvent.getServerTransaction().getRequest()).getCallIdHeader().getCallId();
  110 + }else {
  111 + this.callId = ((SIPRequest)timeoutEvent.getClientTransaction().getRequest()).getCallIdHeader().getCallId();
  112 + }
109 }else if (event instanceof TransactionTerminatedEvent) { 113 }else if (event instanceof TransactionTerminatedEvent) {
110 TransactionTerminatedEvent transactionTerminatedEvent = (TransactionTerminatedEvent)event; 114 TransactionTerminatedEvent transactionTerminatedEvent = (TransactionTerminatedEvent)event;
111 this.type = EventResultType.transactionTerminated; 115 this.type = EventResultType.transactionTerminated;
112 this.msg = "事务已结束"; 116 this.msg = "事务已结束";
113 this.statusCode = -1024; 117 this.statusCode = -1024;
114 - this.callId = transactionTerminatedEvent.getClientTransaction().getDialog().getCallId().getCallId();  
115 - this.dialog = transactionTerminatedEvent.getClientTransaction().getDialog(); 118 + if (transactionTerminatedEvent.isServerTransaction()) {
  119 + this.callId = ((SIPRequest)transactionTerminatedEvent.getServerTransaction().getRequest()).getCallIdHeader().getCallId();
  120 + }else {
  121 + this.callId = ((SIPRequest)transactionTerminatedEvent.getClientTransaction().getRequest()).getCallIdHeader().getCallId();
  122 + }
116 }else if (event instanceof DialogTerminatedEvent) { 123 }else if (event instanceof DialogTerminatedEvent) {
117 DialogTerminatedEvent dialogTerminatedEvent = (DialogTerminatedEvent)event; 124 DialogTerminatedEvent dialogTerminatedEvent = (DialogTerminatedEvent)event;
118 this.type = EventResultType.dialogTerminated; 125 this.type = EventResultType.dialogTerminated;
119 this.msg = "会话已结束"; 126 this.msg = "会话已结束";
120 this.statusCode = -1024; 127 this.statusCode = -1024;
121 this.callId = dialogTerminatedEvent.getDialog().getCallId().getCallId(); 128 this.callId = dialogTerminatedEvent.getDialog().getCallId().getCallId();
122 - this.dialog = dialogTerminatedEvent.getDialog();  
123 }else if (event instanceof DeviceNotFoundEvent) { 129 }else if (event instanceof DeviceNotFoundEvent) {
124 DeviceNotFoundEvent deviceNotFoundEvent = (DeviceNotFoundEvent)event; 130 DeviceNotFoundEvent deviceNotFoundEvent = (DeviceNotFoundEvent)event;
125 this.type = EventResultType.deviceNotFoundEvent; 131 this.type = EventResultType.deviceNotFoundEvent;
src/main/java/com/genersoft/iot/vmp/gb28181/task/ISubscribeTask.java
@@ -7,6 +7,4 @@ import javax.sip.DialogState; @@ -7,6 +7,4 @@ import javax.sip.DialogState;
7 */ 7 */
8 public interface ISubscribeTask extends Runnable{ 8 public interface ISubscribeTask extends Runnable{
9 void stop(); 9 void stop();
10 -  
11 - DialogState getDialogState();  
12 } 10 }
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/CatalogSubscribeTask.java
@@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.conf.DynamicTask; @@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.conf.DynamicTask;
4 import com.genersoft.iot.vmp.gb28181.bean.Device; 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
5 import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; 5 import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask;
6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; 6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
  7 +import gov.nist.javax.sip.message.SIPRequest;
7 import org.slf4j.Logger; 8 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory; 9 import org.slf4j.LoggerFactory;
9 import org.springframework.scheduling.annotation.Async; 10 import org.springframework.scheduling.annotation.Async;
@@ -12,6 +13,8 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @@ -12,6 +13,8 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
12 import javax.sip.Dialog; 13 import javax.sip.Dialog;
13 import javax.sip.DialogState; 14 import javax.sip.DialogState;
14 import javax.sip.ResponseEvent; 15 import javax.sip.ResponseEvent;
  16 +import javax.sip.header.ToHeader;
  17 +import java.text.ParseException;
15 import java.util.Timer; 18 import java.util.Timer;
16 import java.util.TimerTask; 19 import java.util.TimerTask;
17 20
@@ -23,7 +26,7 @@ public class CatalogSubscribeTask implements ISubscribeTask { @@ -23,7 +26,7 @@ public class CatalogSubscribeTask implements ISubscribeTask {
23 private final Logger logger = LoggerFactory.getLogger(CatalogSubscribeTask.class); 26 private final Logger logger = LoggerFactory.getLogger(CatalogSubscribeTask.class);
24 private Device device; 27 private Device device;
25 private final ISIPCommander sipCommander; 28 private final ISIPCommander sipCommander;
26 - private Dialog dialog; 29 + private SIPRequest request;
27 30
28 private DynamicTask dynamicTask; 31 private DynamicTask dynamicTask;
29 32
@@ -41,24 +44,26 @@ public class CatalogSubscribeTask implements ISubscribeTask { @@ -41,24 +44,26 @@ public class CatalogSubscribeTask implements ISubscribeTask {
41 if (dynamicTask.get(taskKey) != null) { 44 if (dynamicTask.get(taskKey) != null) {
42 dynamicTask.stop(taskKey); 45 dynamicTask.stop(taskKey);
43 } 46 }
44 - sipCommander.catalogSubscribe(device, dialog, eventResult -> {  
45 - if (eventResult.dialog != null || eventResult.dialog.getState().equals(DialogState.CONFIRMED)) {  
46 - dialog = eventResult.dialog;  
47 - } 47 + SIPRequest sipRequest = sipCommander.catalogSubscribe(device, request, eventResult -> {
48 ResponseEvent event = (ResponseEvent) eventResult.event; 48 ResponseEvent event = (ResponseEvent) eventResult.event;
49 - if (event.getResponse().getRawContent() != null) {  
50 - // 成功  
51 - logger.info("[目录订阅]成功: {}", device.getDeviceId());  
52 - }else {  
53 - // 成功  
54 - logger.info("[目录订阅]成功: {}", device.getDeviceId()); 49 + // 成功
  50 + logger.info("[目录订阅]成功: {}", device.getDeviceId());
  51 + ToHeader toHeader = (ToHeader)event.getResponse().getHeader(ToHeader.NAME);
  52 + try {
  53 + this.request.getToHeader().setTag(toHeader.getTag());
  54 + } catch (ParseException e) {
  55 + logger.info("[目录订阅]成功: 但为request设置ToTag失败");
  56 + this.request = null;
55 } 57 }
56 },eventResult -> { 58 },eventResult -> {
57 - dialog = null; 59 + this.request = null;
58 // 失败 60 // 失败
59 logger.warn("[目录订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg); 61 logger.warn("[目录订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);
60 dynamicTask.startDelay(taskKey, CatalogSubscribeTask.this, 2000); 62 dynamicTask.startDelay(taskKey, CatalogSubscribeTask.this, 2000);
61 }); 63 });
  64 + if (sipRequest != null) {
  65 + this.request = sipRequest;
  66 + }
62 } 67 }
63 68
64 @Override 69 @Override
@@ -74,29 +79,19 @@ public class CatalogSubscribeTask implements ISubscribeTask { @@ -74,29 +79,19 @@ public class CatalogSubscribeTask implements ISubscribeTask {
74 if (dynamicTask.get(taskKey) != null) { 79 if (dynamicTask.get(taskKey) != null) {
75 dynamicTask.stop(taskKey); 80 dynamicTask.stop(taskKey);
76 } 81 }
77 - if (dialog != null && dialog.getState().equals(DialogState.CONFIRMED)) {  
78 - device.setSubscribeCycleForCatalog(0);  
79 - sipCommander.catalogSubscribe(device, dialog, eventResult -> {  
80 - ResponseEvent event = (ResponseEvent) eventResult.event;  
81 - if (event.getResponse().getRawContent() != null) {  
82 - // 成功  
83 - logger.info("[取消目录订阅订阅]成功: {}", device.getDeviceId());  
84 - }else {  
85 - // 成功  
86 - logger.info("[取消目录订阅订阅]成功: {}", device.getDeviceId());  
87 - }  
88 - },eventResult -> {  
89 - // 失败  
90 - logger.warn("[取消目录订阅订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);  
91 - });  
92 - }  
93 - }  
94 -  
95 - @Override  
96 - public DialogState getDialogState() {  
97 - if (dialog == null) {  
98 - return null;  
99 - }  
100 - return dialog.getState(); 82 + device.setSubscribeCycleForCatalog(0);
  83 + sipCommander.catalogSubscribe(device, request, eventResult -> {
  84 + ResponseEvent event = (ResponseEvent) eventResult.event;
  85 + if (event.getResponse().getRawContent() != null) {
  86 + // 成功
  87 + logger.info("[取消目录订阅订阅]成功: {}", device.getDeviceId());
  88 + }else {
  89 + // 成功
  90 + logger.info("[取消目录订阅订阅]成功: {}", device.getDeviceId());
  91 + }
  92 + },eventResult -> {
  93 + // 失败
  94 + logger.warn("[取消目录订阅订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);
  95 + });
101 } 96 }
102 } 97 }
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java
@@ -4,9 +4,11 @@ import com.genersoft.iot.vmp.conf.DynamicTask; @@ -4,9 +4,11 @@ import com.genersoft.iot.vmp.conf.DynamicTask;
4 import com.genersoft.iot.vmp.gb28181.bean.*; 4 import com.genersoft.iot.vmp.gb28181.bean.*;
5 import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; 5 import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask;
6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; 6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
  7 +import com.genersoft.iot.vmp.service.IPlatformService;
7 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; 8 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
8 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 9 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
9 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 10 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
  11 +import com.genersoft.iot.vmp.utils.SpringBeanFactory;
10 import org.slf4j.Logger; 12 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 13 import org.slf4j.LoggerFactory;
12 import org.springframework.scheduling.annotation.Async; 14 import org.springframework.scheduling.annotation.Async;
@@ -20,71 +22,23 @@ import java.util.List; @@ -20,71 +22,23 @@ import java.util.List;
20 */ 22 */
21 public class MobilePositionSubscribeHandlerTask implements ISubscribeTask { 23 public class MobilePositionSubscribeHandlerTask implements ISubscribeTask {
22 24
23 - private Logger logger = LoggerFactory.getLogger(MobilePositionSubscribeHandlerTask.class);  
24 25
25 - private IRedisCatchStorage redisCatchStorage;  
26 - private IVideoManagerStorage storager;  
27 - private ISIPCommanderForPlatform sipCommanderForPlatform;  
28 - private SubscribeHolder subscribeHolder;  
29 - private ParentPlatform platform; 26 + private IPlatformService platformService;
  27 + private String platformId;
30 28
31 - private String sn;  
32 - private String key;  
33 29
34 - public MobilePositionSubscribeHandlerTask(IRedisCatchStorage redisCatchStorage,  
35 - ISIPCommanderForPlatform sipCommanderForPlatform,  
36 - IVideoManagerStorage storager,  
37 - String platformId,  
38 - String sn,  
39 - String key,  
40 - SubscribeHolder subscribeInfo,  
41 - DynamicTask dynamicTask) {  
42 - this.redisCatchStorage = redisCatchStorage;  
43 - this.storager = storager;  
44 - this.platform = storager.queryParentPlatByServerGBId(platformId);  
45 - this.sn = sn;  
46 - this.key = key;  
47 - this.sipCommanderForPlatform = sipCommanderForPlatform;  
48 - this.subscribeHolder = subscribeInfo; 30 + public MobilePositionSubscribeHandlerTask(String platformId) {
  31 + this.platformService = SpringBeanFactory.getBean("platformServiceImpl");
  32 + this.platformId = platformId;
49 } 33 }
50 34
51 @Override 35 @Override
52 public void run() { 36 public void run() {
53 -  
54 - if (platform == null) {  
55 - return;  
56 - }  
57 - SubscribeInfo subscribe = subscribeHolder.getMobilePositionSubscribe(platform.getServerGBId());  
58 - if (subscribe != null) {  
59 -  
60 - // TODO 暂时只处理视频流的回复,后续增加对国标设备的支持  
61 - List<DeviceChannel> gbStreams = storager.queryGbStreamListInPlatform(platform.getServerGBId());  
62 - if (gbStreams.size() == 0) {  
63 - return;  
64 - }  
65 - for (DeviceChannel deviceChannel : gbStreams) {  
66 - String gbId = deviceChannel.getChannelId();  
67 - GPSMsgInfo gpsMsgInfo = redisCatchStorage.getGpsMsgInfo(gbId);  
68 - // 无最新位置不发送  
69 - if (gpsMsgInfo != null) {  
70 - // 经纬度都为0不发送  
71 - if (gpsMsgInfo.getLng() == 0 && gpsMsgInfo.getLat() == 0) {  
72 - continue;  
73 - }  
74 - // 发送GPS消息  
75 - sipCommanderForPlatform.sendNotifyMobilePosition(platform, gpsMsgInfo, subscribe);  
76 - }  
77 - }  
78 - } 37 + platformService.sendNotifyMobilePosition(this.platformId);
79 } 38 }
80 39
81 @Override 40 @Override
82 public void stop() { 41 public void stop() {
83 42
84 } 43 }
85 -  
86 - @Override  
87 - public DialogState getDialogState() {  
88 - return null;  
89 - }  
90 } 44 }
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeTask.java
@@ -4,6 +4,8 @@ import com.genersoft.iot.vmp.conf.DynamicTask; @@ -4,6 +4,8 @@ import com.genersoft.iot.vmp.conf.DynamicTask;
4 import com.genersoft.iot.vmp.gb28181.bean.Device; 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
5 import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; 5 import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask;
6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; 6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
  7 +import gov.nist.javax.sip.message.SIPRequest;
  8 +import gov.nist.javax.sip.message.SIPResponse;
7 import org.dom4j.Element; 9 import org.dom4j.Element;
8 import org.slf4j.Logger; 10 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory; 11 import org.slf4j.LoggerFactory;
@@ -12,6 +14,8 @@ import org.springframework.scheduling.annotation.Async; @@ -12,6 +14,8 @@ import org.springframework.scheduling.annotation.Async;
12 import javax.sip.Dialog; 14 import javax.sip.Dialog;
13 import javax.sip.DialogState; 15 import javax.sip.DialogState;
14 import javax.sip.ResponseEvent; 16 import javax.sip.ResponseEvent;
  17 +import javax.sip.header.ToHeader;
  18 +import java.text.ParseException;
15 import java.util.Timer; 19 import java.util.Timer;
16 import java.util.TimerTask; 20 import java.util.TimerTask;
17 21
@@ -21,9 +25,10 @@ import java.util.TimerTask; @@ -21,9 +25,10 @@ import java.util.TimerTask;
21 */ 25 */
22 public class MobilePositionSubscribeTask implements ISubscribeTask { 26 public class MobilePositionSubscribeTask implements ISubscribeTask {
23 private final Logger logger = LoggerFactory.getLogger(MobilePositionSubscribeTask.class); 27 private final Logger logger = LoggerFactory.getLogger(MobilePositionSubscribeTask.class);
24 - private Device device;  
25 - private ISIPCommander sipCommander;  
26 - private Dialog dialog; 28 + private Device device;
  29 + private ISIPCommander sipCommander;
  30 +
  31 + private SIPRequest request;
27 private DynamicTask dynamicTask; 32 private DynamicTask dynamicTask;
28 private String taskKey = "mobile-position-subscribe-timeout"; 33 private String taskKey = "mobile-position-subscribe-timeout";
29 34
@@ -38,24 +43,26 @@ public class MobilePositionSubscribeTask implements ISubscribeTask { @@ -38,24 +43,26 @@ public class MobilePositionSubscribeTask implements ISubscribeTask {
38 if (dynamicTask.get(taskKey) != null) { 43 if (dynamicTask.get(taskKey) != null) {
39 dynamicTask.stop(taskKey); 44 dynamicTask.stop(taskKey);
40 } 45 }
41 - sipCommander.mobilePositionSubscribe(device, dialog, eventResult -> {  
42 - if (eventResult.dialog != null || eventResult.dialog.getState().equals(DialogState.CONFIRMED)) {  
43 - dialog = eventResult.dialog;  
44 - } 46 + SIPRequest sipRequest = sipCommander.mobilePositionSubscribe(device, request, eventResult -> {
  47 + // 成功
  48 + logger.info("[移动位置订阅]成功: {}", device.getDeviceId());
45 ResponseEvent event = (ResponseEvent) eventResult.event; 49 ResponseEvent event = (ResponseEvent) eventResult.event;
46 - if (event.getResponse().getRawContent() != null) {  
47 - // 成功  
48 - logger.info("[移动位置订阅]成功: {}", device.getDeviceId());  
49 - }else {  
50 - // 成功  
51 - logger.info("[移动位置订阅]成功: {}", device.getDeviceId()); 50 + ToHeader toHeader = (ToHeader)event.getResponse().getHeader(ToHeader.NAME);
  51 + try {
  52 + this.request.getToHeader().setTag(toHeader.getTag());
  53 + } catch (ParseException e) {
  54 + logger.info("[移动位置订阅]成功: 为request设置ToTag失败");
  55 + this.request = null;
52 } 56 }
53 },eventResult -> { 57 },eventResult -> {
54 - dialog = null; 58 + this.request = null;
55 // 失败 59 // 失败
56 logger.warn("[移动位置订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg); 60 logger.warn("[移动位置订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);
57 dynamicTask.startDelay(taskKey, MobilePositionSubscribeTask.this, 2000); 61 dynamicTask.startDelay(taskKey, MobilePositionSubscribeTask.this, 2000);
58 }); 62 });
  63 + if (sipRequest != null) {
  64 + this.request = sipRequest;
  65 + }
59 66
60 } 67 }
61 68
@@ -71,29 +78,19 @@ public class MobilePositionSubscribeTask implements ISubscribeTask { @@ -71,29 +78,19 @@ public class MobilePositionSubscribeTask implements ISubscribeTask {
71 if (dynamicTask.get(taskKey) != null) { 78 if (dynamicTask.get(taskKey) != null) {
72 dynamicTask.stop(taskKey); 79 dynamicTask.stop(taskKey);
73 } 80 }
74 - if (dialog != null && dialog.getState().equals(DialogState.CONFIRMED)) {  
75 - logger.info("取消移动订阅时dialog状态为{}", dialog.getState());  
76 - device.setSubscribeCycleForMobilePosition(0);  
77 - sipCommander.mobilePositionSubscribe(device, dialog, eventResult -> {  
78 - ResponseEvent event = (ResponseEvent) eventResult.event;  
79 - if (event.getResponse().getRawContent() != null) {  
80 - // 成功  
81 - logger.info("[取消移动位置订阅]成功: {}", device.getDeviceId());  
82 - }else {  
83 - // 成功  
84 - logger.info("[取消移动位置订阅]成功: {}", device.getDeviceId());  
85 - }  
86 - },eventResult -> {  
87 - // 失败  
88 - logger.warn("[取消移动位置订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);  
89 - });  
90 - }  
91 - }  
92 - @Override  
93 - public DialogState getDialogState() {  
94 - if (dialog == null) {  
95 - return null;  
96 - }  
97 - return dialog.getState(); 81 + device.setSubscribeCycleForMobilePosition(0);
  82 + sipCommander.mobilePositionSubscribe(device, request, eventResult -> {
  83 + ResponseEvent event = (ResponseEvent) eventResult.event;
  84 + if (event.getResponse().getRawContent() != null) {
  85 + // 成功
  86 + logger.info("[取消移动位置订阅]成功: {}", device.getDeviceId());
  87 + }else {
  88 + // 成功
  89 + logger.info("[取消移动位置订阅]成功: {}", device.getDeviceId());
  90 + }
  91 + },eventResult -> {
  92 + // 失败
  93 + logger.warn("[取消移动位置订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);
  94 + });
98 } 95 }
99 } 96 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java
@@ -69,12 +69,9 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { @@ -69,12 +69,9 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
69 * @param requestEvent RequestEvent事件 69 * @param requestEvent RequestEvent事件
70 */ 70 */
71 @Override 71 @Override
72 - @Async 72 + @Async("taskExecutor")
73 public void processRequest(RequestEvent requestEvent) { 73 public void processRequest(RequestEvent requestEvent) {
74 String method = requestEvent.getRequest().getMethod(); 74 String method = requestEvent.getRequest().getMethod();
75 - if ("NOTIFY".equalsIgnoreCase(requestEvent.getRequest().getMethod())) {  
76 - System.out.println();  
77 - }  
78 ISIPRequestProcessor sipRequestProcessor = requestProcessorMap.get(method); 75 ISIPRequestProcessor sipRequestProcessor = requestProcessorMap.get(method);
79 if (sipRequestProcessor == null) { 76 if (sipRequestProcessor == null) {
80 logger.warn("不支持方法{}的request", method); 77 logger.warn("不支持方法{}的request", method);
@@ -89,7 +86,7 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { @@ -89,7 +86,7 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
89 * @param responseEvent responseEvent事件 86 * @param responseEvent responseEvent事件
90 */ 87 */
91 @Override 88 @Override
92 - @Async 89 + @Async("taskExecutor")
93 public void processResponse(ResponseEvent responseEvent) { 90 public void processResponse(ResponseEvent responseEvent) {
94 Response response = responseEvent.getResponse(); 91 Response response = responseEvent.getResponse();
95 int status = response.getStatusCode(); 92 int status = response.getStatusCode();
@@ -173,6 +170,12 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { @@ -173,6 +170,12 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
173 170
174 @Override 171 @Override
175 public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) { 172 public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
  173 +// if (transactionTerminatedEvent.isServerTransaction()) {
  174 +// ServerTransaction serverTransaction = transactionTerminatedEvent.getServerTransaction();
  175 +// serverTransaction.get
  176 +// }
  177 +
  178 +
176 // Transaction transaction = null; 179 // Transaction transaction = null;
177 // System.out.println("processTransactionTerminated"); 180 // System.out.println("processTransactionTerminated");
178 // if (transactionTerminatedEvent.isServerTransaction()) { 181 // if (transactionTerminatedEvent.isServerTransaction()) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
8 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 8 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
9 import gov.nist.javax.sip.message.SIPRequest; 9 import gov.nist.javax.sip.message.SIPRequest;
  10 +import gov.nist.javax.sip.message.SIPRequest;
10 import gov.nist.javax.sip.stack.SIPDialog; 11 import gov.nist.javax.sip.stack.SIPDialog;
11 12
12 import javax.sip.Dialog; 13 import javax.sip.Dialog;
@@ -158,7 +159,7 @@ public interface ISIPCommander { @@ -158,7 +159,7 @@ public interface ISIPCommander {
158 */ 159 */
159 void playbackControlCmd(Device device, StreamInfo streamInfo, String content,SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent); 160 void playbackControlCmd(Device device, StreamInfo streamInfo, String content,SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent);
160 161
161 - 162 +
162 /** 163 /**
163 * 语音广播 164 * 语音广播
164 * 165 *
@@ -311,7 +312,7 @@ public interface ISIPCommander { @@ -311,7 +312,7 @@ public interface ISIPCommander {
311 * @param device 视频设备 312 * @param device 视频设备
312 * @return true = 命令发送成功 313 * @return true = 命令发送成功
313 */ 314 */
314 - boolean mobilePositionSubscribe(Device device, Dialog dialog, SipSubscribe.Event okEvent , SipSubscribe.Event errorEvent); 315 + SIPRequest mobilePositionSubscribe(Device device, SIPRequest request, SipSubscribe.Event okEvent , SipSubscribe.Event errorEvent);
315 316
316 /** 317 /**
317 * 订阅、取消订阅报警信息 318 * 订阅、取消订阅报警信息
@@ -331,7 +332,7 @@ public interface ISIPCommander { @@ -331,7 +332,7 @@ public interface ISIPCommander {
331 * @param device 视频设备 332 * @param device 视频设备
332 * @return true = 命令发送成功 333 * @return true = 命令发送成功
333 */ 334 */
334 - boolean catalogSubscribe(Device device, Dialog dialog, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent); 335 + SIPRequest catalogSubscribe(Device device, SIPRequest request, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent);
335 336
336 /** 337 /**
337 * 拉框控制命令 338 * 拉框控制命令
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
@@ -117,4 +117,5 @@ public interface ISIPCommanderForPlatform { @@ -117,4 +117,5 @@ public interface ISIPCommanderForPlatform {
117 * @param callId callId 117 * @param callId callId
118 */ 118 */
119 void streamByeCmd(ParentPlatform platform, String callId); 119 void streamByeCmd(ParentPlatform platform, String callId);
  120 + void streamByeCmd(ParentPlatform platform, SendRtpItem sendRtpItem);
120 } 121 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
@@ -2,10 +2,13 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; @@ -2,10 +2,13 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd;
2 2
3 import com.genersoft.iot.vmp.conf.SipConfig; 3 import com.genersoft.iot.vmp.conf.SipConfig;
4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  5 +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
  6 +import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo;
5 import com.genersoft.iot.vmp.gb28181.utils.SipUtils; 7 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
6 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 8 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
7 import com.genersoft.iot.vmp.utils.GitUtil; 9 import com.genersoft.iot.vmp.utils.GitUtil;
8 import gov.nist.javax.sip.message.MessageFactoryImpl; 10 import gov.nist.javax.sip.message.MessageFactoryImpl;
  11 +import gov.nist.javax.sip.message.SIPRequest;
9 import org.springframework.beans.factory.annotation.Autowired; 12 import org.springframework.beans.factory.annotation.Autowired;
10 import org.springframework.stereotype.Component; 13 import org.springframework.stereotype.Component;
11 import org.springframework.util.DigestUtils; 14 import org.springframework.util.DigestUtils;
@@ -154,8 +157,17 @@ public class SIPRequestHeaderPlarformProvider { @@ -154,8 +157,17 @@ public class SIPRequestHeaderPlarformProvider {
154 return registerRequest; 157 return registerRequest;
155 } 158 }
156 159
  160 + public Request createMessageRequest(ParentPlatform parentPlatform, String content, SendRtpItem sendRtpItem) throws PeerUnavailableException, ParseException, InvalidArgumentException {
  161 + CallIdHeader callIdHeader = sipFactory.createHeaderFactory().createCallIdHeader(sendRtpItem.getCallId());
  162 + return createMessageRequest(parentPlatform, content, sendRtpItem.getToTag(), SipUtils.getNewViaTag(), sendRtpItem.getFromTag(), callIdHeader);
  163 + }
157 164
158 public Request createMessageRequest(ParentPlatform parentPlatform, String content, String fromTag, String viaTag, CallIdHeader callIdHeader) throws PeerUnavailableException, ParseException, InvalidArgumentException { 165 public Request createMessageRequest(ParentPlatform parentPlatform, String content, String fromTag, String viaTag, CallIdHeader callIdHeader) throws PeerUnavailableException, ParseException, InvalidArgumentException {
  166 + return createMessageRequest(parentPlatform, content, fromTag, viaTag, null, callIdHeader);
  167 + }
  168 +
  169 +
  170 + public Request createMessageRequest(ParentPlatform parentPlatform, String content, String fromTag, String viaTag, String toTag, CallIdHeader callIdHeader) throws PeerUnavailableException, ParseException, InvalidArgumentException {
159 Request request = null; 171 Request request = null;
160 String serverAddress = parentPlatform.getServerIP()+ ":" + parentPlatform.getServerPort(); 172 String serverAddress = parentPlatform.getServerIP()+ ":" + parentPlatform.getServerPort();
161 // sipuri 173 // sipuri
@@ -174,7 +186,7 @@ public class SIPRequestHeaderPlarformProvider { @@ -174,7 +186,7 @@ public class SIPRequestHeaderPlarformProvider {
174 // to 186 // to
175 SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), serverAddress); 187 SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), serverAddress);
176 Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI); 188 Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
177 - ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, null); 189 + ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag);
178 190
179 // Forwards 191 // Forwards
180 MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70); 192 MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
@@ -192,4 +204,107 @@ public class SIPRequestHeaderPlarformProvider { @@ -192,4 +204,107 @@ public class SIPRequestHeaderPlarformProvider {
192 request.setContent(content, contentTypeHeader); 204 request.setContent(content, contentTypeHeader);
193 return request; 205 return request;
194 } 206 }
  207 +
  208 + public SIPRequest createNotifyRequest(ParentPlatform parentPlatform, String content, SubscribeInfo subscribeInfo) throws PeerUnavailableException, ParseException, InvalidArgumentException {
  209 + SIPRequest request = null;
  210 + // sipuri
  211 + SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP()+ ":" + parentPlatform.getServerPort());
  212 + // via
  213 + ArrayList<ViaHeader> viaHeaders = new ArrayList<>();
  214 + ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(), Integer.parseInt(parentPlatform.getDevicePort()),
  215 + parentPlatform.getTransport(), SipUtils.getNewViaTag());
  216 + viaHeader.setRPort();
  217 + viaHeaders.add(viaHeader);
  218 + // from
  219 + SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(),
  220 + parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort());
  221 + Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
  222 + FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, subscribeInfo.getResponse().getToTag());
  223 + // to
  224 + SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerGBDomain());
  225 + Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
  226 + ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, subscribeInfo.getRequest().getFromTag());
  227 +
  228 + // Forwards
  229 + MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
  230 + // ceq
  231 + CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.NOTIFY);
  232 + MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
  233 + // 设置编码, 防止中文乱码
  234 + messageFactory.setDefaultContentEncodingCharset("gb2312");
  235 +
  236 + CallIdHeader callIdHeader = sipFactory.createHeaderFactory().createCallIdHeader(subscribeInfo.getRequest().getCallIdHeader().getCallId());
  237 +
  238 + request = (SIPRequest) messageFactory.createRequest(requestURI, Request.NOTIFY, callIdHeader, cSeqHeader, fromHeader,
  239 + toHeader, viaHeaders, maxForwards);
  240 +
  241 + request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
  242 +
  243 + EventHeader event = sipFactory.createHeaderFactory().createEventHeader(subscribeInfo.getEventType());
  244 + if (subscribeInfo.getEventId() != null) {
  245 + event.setEventId(subscribeInfo.getEventId());
  246 + }
  247 +
  248 + request.addHeader(event);
  249 +
  250 + SubscriptionStateHeader active = sipFactory.createHeaderFactory().createSubscriptionStateHeader("active");
  251 + request.setHeader(active);
  252 +
  253 + String sipAddress = sipConfig.getIp() + ":" + sipConfig.getPort();
  254 + Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory()
  255 + .createSipURI(parentPlatform.getDeviceGBId(), sipAddress));
  256 + request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
  257 +
  258 + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
  259 + request.setContent(content, contentTypeHeader);
  260 + return request;
  261 + }
  262 +
  263 + public SIPRequest createByeRequest(ParentPlatform platform, SendRtpItem sendRtpItem) throws PeerUnavailableException, ParseException, InvalidArgumentException {
  264 +
  265 + if (sendRtpItem == null ) {
  266 + return null;
  267 + }
  268 +
  269 + SIPRequest request = null;
  270 + // sipuri
  271 + SipURI requestURI = sipFactory.createAddressFactory().createSipURI(platform.getServerGBId(), platform.getServerIP()+ ":" + platform.getServerPort());
  272 + // via
  273 + ArrayList<ViaHeader> viaHeaders = new ArrayList<>();
  274 + ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(platform.getDeviceIp(), Integer.parseInt(platform.getDevicePort()),
  275 + platform.getTransport(), SipUtils.getNewViaTag());
  276 + viaHeader.setRPort();
  277 + viaHeaders.add(viaHeader);
  278 + // from
  279 + SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(),
  280 + platform.getDeviceIp() + ":" + platform.getDevicePort());
  281 + Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
  282 + FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, sendRtpItem.getToTag());
  283 + // to
  284 + SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(platform.getServerGBId(), platform.getServerGBDomain());
  285 + Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
  286 + ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, sendRtpItem.getFromTag());
  287 +
  288 + // Forwards
  289 + MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
  290 + // ceq
  291 + CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.BYE);
  292 + MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
  293 + // 设置编码, 防止中文乱码
  294 + messageFactory.setDefaultContentEncodingCharset("gb2312");
  295 +
  296 + CallIdHeader callIdHeader = sipFactory.createHeaderFactory().createCallIdHeader(sendRtpItem.getCallId());
  297 +
  298 + request = (SIPRequest) messageFactory.createRequest(requestURI, Request.BYE, callIdHeader, cSeqHeader, fromHeader,
  299 + toHeader, viaHeaders, maxForwards);
  300 +
  301 + request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
  302 +
  303 + String sipAddress = sipConfig.getIp() + ":" + sipConfig.getPort();
  304 + Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory()
  305 + .createSipURI(platform.getDeviceGBId(), sipAddress));
  306 + request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
  307 +
  308 + return request;
  309 + }
195 } 310 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
@@ -16,6 +16,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -16,6 +16,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
16 import com.genersoft.iot.vmp.utils.GitUtil; 16 import com.genersoft.iot.vmp.utils.GitUtil;
17 import gov.nist.javax.sip.SipProviderImpl; 17 import gov.nist.javax.sip.SipProviderImpl;
18 import gov.nist.javax.sip.SipStackImpl; 18 import gov.nist.javax.sip.SipStackImpl;
  19 +import gov.nist.javax.sip.message.SIPRequest;
19 import gov.nist.javax.sip.stack.SIPDialog; 20 import gov.nist.javax.sip.stack.SIPDialog;
20 import org.springframework.beans.factory.annotation.Autowired; 21 import org.springframework.beans.factory.annotation.Autowired;
21 import org.springframework.beans.factory.annotation.Qualifier; 22 import org.springframework.beans.factory.annotation.Qualifier;
@@ -199,24 +200,24 @@ public class SIPRequestHeaderProvider { @@ -199,24 +200,24 @@ public class SIPRequestHeaderProvider {
199 return request; 200 return request;
200 } 201 }
201 202
202 - public Request createSubscribeRequest(Device device, String content, String viaTag, String fromTag, String toTag, Integer expires, String event, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException { 203 + public Request createSubscribeRequest(Device device, String content, SIPRequest requestOld, Integer expires, String event, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException {
203 Request request = null; 204 Request request = null;
204 // sipuri 205 // sipuri
205 SipURI requestURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress()); 206 SipURI requestURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress());
206 // via 207 // via
207 ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); 208 ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
208 ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getIp(), sipConfig.getPort(), 209 ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getIp(), sipConfig.getPort(),
209 - device.getTransport(), viaTag); 210 + device.getTransport(), SipUtils.getNewViaTag());
210 viaHeader.setRPort(); 211 viaHeader.setRPort();
211 viaHeaders.add(viaHeader); 212 viaHeaders.add(viaHeader);
212 // from 213 // from
213 SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain()); 214 SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain());
214 Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI); 215 Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
215 - FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag); 216 + FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, requestOld == null ? SipUtils.getNewFromTag() :requestOld.getFromTag());
216 // to 217 // to
217 SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress()); 218 SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress());
218 Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI); 219 Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
219 - ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag); 220 + ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, requestOld == null ? null :requestOld.getToTag());
220 221
221 // Forwards 222 // Forwards
222 MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70); 223 MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
@@ -238,7 +239,7 @@ public class SIPRequestHeaderProvider { @@ -238,7 +239,7 @@ public class SIPRequestHeaderProvider {
238 // Event 239 // Event
239 EventHeader eventHeader = sipFactory.createHeaderFactory().createEventHeader(event); 240 EventHeader eventHeader = sipFactory.createHeaderFactory().createEventHeader(event);
240 241
241 - int random = (int)Math.random() * 1000000000; 242 + int random = (int) Math.floor(Math.random() * 10000);
242 eventHeader.setEventId(random + ""); 243 eventHeader.setEventId(random + "");
243 request.addHeader(eventHeader); 244 request.addHeader(eventHeader);
244 245
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -26,6 +26,7 @@ import gov.nist.javax.sip.SipProviderImpl; @@ -26,6 +26,7 @@ import gov.nist.javax.sip.SipProviderImpl;
26 import gov.nist.javax.sip.SipStackImpl; 26 import gov.nist.javax.sip.SipStackImpl;
27 import gov.nist.javax.sip.message.MessageFactoryImpl; 27 import gov.nist.javax.sip.message.MessageFactoryImpl;
28 import gov.nist.javax.sip.message.SIPRequest; 28 import gov.nist.javax.sip.message.SIPRequest;
  29 +import gov.nist.javax.sip.stack.SIPClientTransaction;
29 import gov.nist.javax.sip.stack.SIPDialog; 30 import gov.nist.javax.sip.stack.SIPDialog;
30 import org.slf4j.Logger; 31 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory; 32 import org.slf4j.LoggerFactory;
@@ -435,7 +436,14 @@ public class SIPCommander implements ISIPCommander { @@ -435,7 +436,14 @@ public class SIPCommander implements ISIPCommander {
435 }), e ->{ 436 }), e ->{
436 // 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值 437 // 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值
437 streamSession.put(device.getDeviceId(), channelId ,"play", stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), ((ResponseEvent)e.event).getClientTransaction(), VideoStreamSessionManager.SessionType.play); 438 streamSession.put(device.getDeviceId(), channelId ,"play", stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), ((ResponseEvent)e.event).getClientTransaction(), VideoStreamSessionManager.SessionType.play);
438 - streamSession.put(device.getDeviceId(), channelId ,"play", e.dialog); 439 + Dialog sipDialog = null;
  440 + if (e.dialog == null) {
  441 + SIPClientTransaction clientTransaction = (SIPClientTransaction)((ResponseEvent)e.event).getClientTransaction();
  442 + sipDialog = new SIPDialog(clientTransaction, clientTransaction.getLastResponse());
  443 + }else {
  444 + sipDialog = e.dialog;
  445 + }
  446 + streamSession.put(device.getDeviceId(), channelId ,"play", sipDialog);
439 okEvent.response(e); 447 okEvent.response(e);
440 }); 448 });
441 449
@@ -1446,7 +1454,7 @@ public class SIPCommander implements ISIPCommander { @@ -1446,7 +1454,7 @@ public class SIPCommander implements ISIPCommander {
1446 * @return true = 命令发送成功 1454 * @return true = 命令发送成功
1447 */ 1455 */
1448 @Override 1456 @Override
1449 - public boolean mobilePositionSubscribe(Device device, Dialog dialog, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent) { 1457 + public SIPRequest mobilePositionSubscribe(Device device, SIPRequest requestOld, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent) {
1450 try { 1458 try {
1451 StringBuffer subscribePostitionXml = new StringBuffer(200); 1459 StringBuffer subscribePostitionXml = new StringBuffer(200);
1452 String charset = device.getCharset(); 1460 String charset = device.getCharset();
@@ -1456,38 +1464,27 @@ public class SIPCommander implements ISIPCommander { @@ -1456,38 +1464,27 @@ public class SIPCommander implements ISIPCommander {
1456 subscribePostitionXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); 1464 subscribePostitionXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
1457 subscribePostitionXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); 1465 subscribePostitionXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
1458 if (device.getSubscribeCycleForMobilePosition() > 0) { 1466 if (device.getSubscribeCycleForMobilePosition() > 0) {
1459 - subscribePostitionXml.append("<Interval>" + String.valueOf(device.getMobilePositionSubmissionInterval()) + "</Interval>\r\n"); 1467 + subscribePostitionXml.append("<Interval>" + device.getMobilePositionSubmissionInterval() + "</Interval>\r\n");
1460 } 1468 }
1461 subscribePostitionXml.append("</Query>\r\n"); 1469 subscribePostitionXml.append("</Query>\r\n");
1462 1470
1463 - Request request;  
1464 - if (dialog != null) {  
1465 - SipURI requestURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress());  
1466 - request = dialog.createRequest(Request.SUBSCRIBE);  
1467 - ExpiresHeader expiresHeader = sipFactory.createHeaderFactory().createExpiresHeader(device.getSubscribeCycleForCatalog());  
1468 - request.setExpires(expiresHeader);  
1469 -  
1470 - request.setRequestURI(requestURI); 1471 + CallIdHeader callIdHeader;
1471 1472
1472 - ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");  
1473 - request.setContent(subscribePostitionXml.toString(), contentTypeHeader);  
1474 -  
1475 - CSeqHeader cSeqHeader = (CSeqHeader)request.getHeader(CSeqHeader.NAME);  
1476 - cSeqHeader.setSeqNumber(redisCatchStorage.getCSEQ());  
1477 - request.removeHeader(CSeqHeader.NAME);  
1478 - request.addHeader(cSeqHeader); 1473 + if (requestOld != null) {
  1474 + callIdHeader = sipFactory.createHeaderFactory().createCallIdHeader(requestOld.getCallIdHeader().getCallId());
1479 }else { 1475 }else {
1480 - CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() 1476 + callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
1481 : udpSipProvider.getNewCallId(); 1477 : udpSipProvider.getNewCallId();
1482 - request = headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, device.getSubscribeCycleForMobilePosition(), "presence" ,callIdHeader); //Position;id=" + tm.substring(tm.length() - 4));  
1483 } 1478 }
  1479 + SIPRequest request = (SIPRequest)headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), requestOld, device.getSubscribeCycleForMobilePosition(), "presence" ,callIdHeader); //Position;id=" + tm.substring(tm.length() - 4));
  1480 +
1484 transmitRequest(device, request, errorEvent, okEvent); 1481 transmitRequest(device, request, errorEvent, okEvent);
1485 1482
1486 - return true; 1483 + return request;
1487 1484
1488 } catch ( NumberFormatException | ParseException | InvalidArgumentException | SipException e) { 1485 } catch ( NumberFormatException | ParseException | InvalidArgumentException | SipException e) {
1489 e.printStackTrace(); 1486 e.printStackTrace();
1490 - return false; 1487 + return null;
1491 } 1488 }
1492 } 1489 }
1493 1490
@@ -1537,7 +1534,7 @@ public class SIPCommander implements ISIPCommander { @@ -1537,7 +1534,7 @@ public class SIPCommander implements ISIPCommander {
1537 CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() 1534 CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
1538 : udpSipProvider.getNewCallId(); 1535 : udpSipProvider.getNewCallId();
1539 1536
1540 - Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, expires, "presence" , callIdHeader); 1537 + Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), null, expires, "presence" , callIdHeader);
1541 transmitRequest(device, request); 1538 transmitRequest(device, request);
1542 1539
1543 return true; 1540 return true;
@@ -1549,7 +1546,7 @@ public class SIPCommander implements ISIPCommander { @@ -1549,7 +1546,7 @@ public class SIPCommander implements ISIPCommander {
1549 } 1546 }
1550 1547
1551 @Override 1548 @Override
1552 - public boolean catalogSubscribe(Device device, Dialog dialog, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) { 1549 + public SIPRequest catalogSubscribe(Device device, SIPRequest requestOld, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) {
1553 try { 1550 try {
1554 StringBuffer cmdXml = new StringBuffer(200); 1551 StringBuffer cmdXml = new StringBuffer(200);
1555 String charset = device.getCharset(); 1552 String charset = device.getCharset();
@@ -1560,40 +1557,24 @@ public class SIPCommander implements ISIPCommander { @@ -1560,40 +1557,24 @@ public class SIPCommander implements ISIPCommander {
1560 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); 1557 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
1561 cmdXml.append("</Query>\r\n"); 1558 cmdXml.append("</Query>\r\n");
1562 1559
  1560 + CallIdHeader callIdHeader ;
1563 1561
1564 - Request request;  
1565 - if (dialog != null) {  
1566 - SipURI requestURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress());  
1567 - request = dialog.createRequest(Request.SUBSCRIBE);  
1568 - ExpiresHeader expiresHeader = sipFactory.createHeaderFactory().createExpiresHeader(device.getSubscribeCycleForCatalog());  
1569 - request.setExpires(expiresHeader);  
1570 -  
1571 - request.setRequestURI(requestURI);  
1572 -  
1573 - ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");  
1574 - request.setContent(cmdXml.toString(), contentTypeHeader);  
1575 -  
1576 - CSeqHeader cSeqHeader = (CSeqHeader)request.getHeader(CSeqHeader.NAME);  
1577 - cSeqHeader.setSeqNumber(redisCatchStorage.getCSEQ());  
1578 - request.removeHeader(CSeqHeader.NAME);  
1579 - request.addHeader(cSeqHeader);  
1580 - 1562 + if (requestOld != null) {
  1563 + callIdHeader = sipFactory.createHeaderFactory().createCallIdHeader(requestOld.getCallIdHeader().getCallId());
1581 }else { 1564 }else {
1582 - CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() 1565 + callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
1583 : udpSipProvider.getNewCallId(); 1566 : udpSipProvider.getNewCallId();
1584 -  
1585 - // 有效时间默认为60秒以上  
1586 - request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), SipUtils.getNewViaTag(),  
1587 - SipUtils.getNewFromTag(), null, device.getSubscribeCycleForCatalog(), "Catalog" ,  
1588 - callIdHeader);  
1589 -  
1590 } 1567 }
  1568 +
  1569 + // 有效时间默认为60秒以上
  1570 + SIPRequest request = (SIPRequest)headerProvider.createSubscribeRequest(device, cmdXml.toString(), requestOld, device.getSubscribeCycleForCatalog(), "Catalog" ,
  1571 + callIdHeader);
1591 transmitRequest(device, request, errorEvent, okEvent); 1572 transmitRequest(device, request, errorEvent, okEvent);
1592 - return true; 1573 + return request;
1593 1574
1594 } catch ( NumberFormatException | ParseException | InvalidArgumentException | SipException e) { 1575 } catch ( NumberFormatException | ParseException | InvalidArgumentException | SipException e) {
1595 e.printStackTrace(); 1576 e.printStackTrace();
1596 - return false; 1577 + return null;
1597 } 1578 }
1598 } 1579 }
1599 1580
@@ -1869,61 +1850,4 @@ public class SIPCommander implements ISIPCommander { @@ -1869,61 +1850,4 @@ public class SIPCommander implements ISIPCommander {
1869 } 1850 }
1870 return true; 1851 return true;
1871 } 1852 }
1872 -  
1873 - private void sendNotify(Device device, String catalogXmlContent,  
1874 - SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent )  
1875 - throws SipException, ParseException {  
1876 - MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();  
1877 - String characterSet = device.getCharset();  
1878 - // 设置编码, 防止中文乱码  
1879 - messageFactory.setDefaultContentEncodingCharset(characterSet);  
1880 - Dialog dialog = subscribeInfo.getDialog();  
1881 - if (dialog == null || !dialog.getState().equals(DialogState.CONFIRMED)) {  
1882 - return;  
1883 - }  
1884 - SIPRequest notifyRequest = (SIPRequest)dialog.createRequest(Request.NOTIFY);  
1885 - ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");  
1886 - notifyRequest.setContent(catalogXmlContent, contentTypeHeader);  
1887 -  
1888 - SubscriptionStateHeader subscriptionState = sipFactory.createHeaderFactory()  
1889 - .createSubscriptionStateHeader(SubscriptionStateHeader.ACTIVE);  
1890 - notifyRequest.addHeader(subscriptionState);  
1891 -  
1892 - EventHeader event = sipFactory.createHeaderFactory().createEventHeader(subscribeInfo.getEventType());  
1893 - if (subscribeInfo.getEventId() != null) {  
1894 - event.setEventId(subscribeInfo.getEventId());  
1895 - }  
1896 - notifyRequest.addHeader(event);  
1897 -  
1898 - SipURI sipURI = (SipURI) notifyRequest.getRequestURI();  
1899 - if (subscribeInfo.getTransaction() != null) {  
1900 - SIPRequest request = (SIPRequest) subscribeInfo.getTransaction().getRequest();  
1901 - sipURI.setHost(request.getRemoteAddress().getHostAddress());  
1902 - sipURI.setPort(request.getRemotePort());  
1903 - }else {  
1904 - sipURI.setHost(device.getIp());  
1905 - sipURI.setPort(device.getPort());  
1906 - }  
1907 -  
1908 - ClientTransaction transaction = null;  
1909 - if ("TCP".equals(device.getTransport())) {  
1910 - transaction = tcpSipProvider.getNewClientTransaction(notifyRequest);  
1911 - } else if ("UDP".equals(device.getTransport())) {  
1912 - transaction = udpSipProvider.getNewClientTransaction(notifyRequest);  
1913 - }  
1914 - // 添加错误订阅  
1915 - if (errorEvent != null) {  
1916 - sipSubscribe.addErrorSubscribe(subscribeInfo.getCallId(), errorEvent);  
1917 - }  
1918 - // 添加订阅  
1919 - if (okEvent != null) {  
1920 - sipSubscribe.addOkSubscribe(subscribeInfo.getCallId(), okEvent);  
1921 - }  
1922 - if (transaction == null) {  
1923 - logger.error("平台{}的Transport错误:{}",device.getDeviceId(), device.getTransport());  
1924 - return;  
1925 - }  
1926 - dialog.sendRequest(transaction);  
1927 -  
1928 - }  
1929 } 1853 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
1 package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; 1 package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
2 2
  3 +import com.alibaba.fastjson.JSONObject;
3 import com.genersoft.iot.vmp.gb28181.bean.*; 4 import com.genersoft.iot.vmp.gb28181.bean.*;
4 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 5 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
5 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; 6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
@@ -47,7 +48,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -47,7 +48,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
47 private final Logger logger = LoggerFactory.getLogger(SIPCommanderFroPlatform.class); 48 private final Logger logger = LoggerFactory.getLogger(SIPCommanderFroPlatform.class);
48 49
49 @Autowired 50 @Autowired
50 - private SIPRequestHeaderPlarformProvider headerProviderPlarformProvider; 51 + private SIPRequestHeaderPlarformProvider headerProviderPlatformProvider;
51 52
52 @Autowired 53 @Autowired
53 private IRedisCatchStorage redisCatchStorage; 54 private IRedisCatchStorage redisCatchStorage;
@@ -74,6 +75,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -74,6 +75,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
74 @Autowired 75 @Autowired
75 private SipFactory sipFactory; 76 private SipFactory sipFactory;
76 77
  78 + @Autowired
  79 + private SubscribeHolder subscribeHolder;
  80 +
77 @Override 81 @Override
78 public boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { 82 public boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) {
79 return register(parentPlatform, null, null, errorEvent, okEvent, false, true); 83 return register(parentPlatform, null, null, errorEvent, okEvent, false, true);
@@ -98,7 +102,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -98,7 +102,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
98 callIdHeader = udpSipProvider.getNewCallId(); 102 callIdHeader = udpSipProvider.getNewCallId();
99 } 103 }
100 104
101 - request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, 105 + request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform,
102 redisCatchStorage.getCSEQ(), SipUtils.getNewFromTag(), 106 redisCatchStorage.getCSEQ(), SipUtils.getNewFromTag(),
103 SipUtils.getNewViaTag(), callIdHeader, isRegister); 107 SipUtils.getNewViaTag(), callIdHeader, isRegister);
104 // 将 callid 写入缓存, 等注册成功可以更新状态 108 // 将 callid 写入缓存, 等注册成功可以更新状态
@@ -120,7 +124,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -120,7 +124,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
120 }else { 124 }else {
121 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId() 125 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
122 : udpSipProvider.getNewCallId(); 126 : udpSipProvider.getNewCallId();
123 - request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, SipUtils.getNewFromTag(), null, callId, www, callIdHeader, isRegister); 127 + request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform, SipUtils.getNewFromTag(), null, callId, www, callIdHeader, isRegister);
124 } 128 }
125 129
126 transmitRequest(parentPlatform, request, null, okEvent); 130 transmitRequest(parentPlatform, request, null, okEvent);
@@ -154,7 +158,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -154,7 +158,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
154 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId() 158 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
155 : udpSipProvider.getNewCallId(); 159 : udpSipProvider.getNewCallId();
156 160
157 - Request request = headerProviderPlarformProvider.createMessageRequest( 161 + Request request = headerProviderPlatformProvider.createMessageRequest(
158 parentPlatform, 162 parentPlatform,
159 keepaliveXml.toString(), 163 keepaliveXml.toString(),
160 SipUtils.getNewFromTag(), 164 SipUtils.getNewFromTag(),
@@ -220,7 +224,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -220,7 +224,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
220 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId() 224 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
221 : udpSipProvider.getNewCallId(); 225 : udpSipProvider.getNewCallId();
222 226
223 - Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, catalogXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader); 227 + Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, catalogXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
224 transmitRequest(parentPlatform, request); 228 transmitRequest(parentPlatform, request);
225 229
226 } catch (SipException | ParseException | InvalidArgumentException e) { 230 } catch (SipException | ParseException | InvalidArgumentException e) {
@@ -314,7 +318,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -314,7 +318,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
314 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId() 318 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
315 : udpSipProvider.getNewCallId(); 319 : udpSipProvider.getNewCallId();
316 320
317 - Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, catalogXml, fromTag, SipUtils.getNewViaTag(), callIdHeader); 321 + Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, catalogXml, fromTag, SipUtils.getNewViaTag(), callIdHeader);
318 transmitRequest(parentPlatform, request, null, eventResult -> { 322 transmitRequest(parentPlatform, request, null, eventResult -> {
319 int indexNext = index + parentPlatform.getCatalogGroup(); 323 int indexNext = index + parentPlatform.getCatalogGroup();
320 sendCatalogResponse(channels, parentPlatform, sn, fromTag, indexNext); 324 sendCatalogResponse(channels, parentPlatform, sn, fromTag, indexNext);
@@ -354,7 +358,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -354,7 +358,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
354 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId() 358 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
355 : udpSipProvider.getNewCallId(); 359 : udpSipProvider.getNewCallId();
356 360
357 - Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, deviceInfoXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader); 361 + Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceInfoXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
358 transmitRequest(parentPlatform, request); 362 transmitRequest(parentPlatform, request);
359 363
360 } catch (SipException | ParseException | InvalidArgumentException e) { 364 } catch (SipException | ParseException | InvalidArgumentException e) {
@@ -392,7 +396,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -392,7 +396,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
392 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId() 396 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
393 : udpSipProvider.getNewCallId(); 397 : udpSipProvider.getNewCallId();
394 398
395 - Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader); 399 + Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
396 transmitRequest(parentPlatform, request); 400 transmitRequest(parentPlatform, request);
397 401
398 } catch (SipException | ParseException | InvalidArgumentException e) { 402 } catch (SipException | ParseException | InvalidArgumentException e) {
@@ -427,11 +431,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -427,11 +431,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
427 deviceStatusXml.append("<Altitude>" + gpsMsgInfo.getAltitude() + "</Altitude>\r\n"); 431 deviceStatusXml.append("<Altitude>" + gpsMsgInfo.getAltitude() + "</Altitude>\r\n");
428 deviceStatusXml.append("</Notify>\r\n"); 432 deviceStatusXml.append("</Notify>\r\n");
429 433
430 - CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()  
431 - : udpSipProvider.getNewCallId();  
432 - callIdHeader.setCallId(subscribeInfo.getCallId());  
433 -  
434 - sendNotify(parentPlatform, deviceStatusXml.toString(), subscribeInfo, eventResult -> { 434 + sendNotify(parentPlatform, deviceStatusXml.toString(), subscribeInfo, eventResult -> {
435 logger.error("发送NOTIFY通知消息失败。错误:{} {}", eventResult.statusCode, eventResult.msg); 435 logger.error("发送NOTIFY通知消息失败。错误:{} {}", eventResult.statusCode, eventResult.msg);
436 }, null); 436 }, null);
437 437
@@ -453,8 +453,8 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -453,8 +453,8 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
453 if (parentPlatform == null) { 453 if (parentPlatform == null) {
454 return false; 454 return false;
455 } 455 }
456 - logger.info("[发送 报警订阅] {}/{}->{},{}", parentPlatform.getServerGBId(), deviceAlarm.getChannelId(),  
457 - deviceAlarm.getLongitude(), deviceAlarm.getLatitude()); 456 + logger.info("[发送报警通知] {}/{}->{},{}: {}", parentPlatform.getServerGBId(), deviceAlarm.getChannelId(),
  457 + deviceAlarm.getLongitude(), deviceAlarm.getLatitude(), JSONObject.toJSON(deviceAlarm));
458 try { 458 try {
459 String characterSet = parentPlatform.getCharacterSet(); 459 String characterSet = parentPlatform.getCharacterSet();
460 StringBuffer deviceStatusXml = new StringBuffer(600); 460 StringBuffer deviceStatusXml = new StringBuffer(600);
@@ -477,7 +477,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -477,7 +477,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
477 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId() 477 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
478 : udpSipProvider.getNewCallId(); 478 : udpSipProvider.getNewCallId();
479 479
480 - Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), SipUtils.getNewFromTag(), SipUtils.getNewViaTag(), callIdHeader); 480 + Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), SipUtils.getNewFromTag(), SipUtils.getNewViaTag(), callIdHeader);
481 transmitRequest(parentPlatform, request); 481 transmitRequest(parentPlatform, request);
482 482
483 } catch (SipException | ParseException e) { 483 } catch (SipException | ParseException e) {
@@ -529,18 +529,15 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -529,18 +529,15 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
529 return true; 529 return true;
530 } 530 }
531 531
532 - private void sendNotify(ParentPlatform parentPlatform, String catalogXmlContent, 532 + private ClientTransaction sendNotify(ParentPlatform parentPlatform, String catalogXmlContent,
533 SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent ) 533 SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent )
534 throws NoSuchFieldException, IllegalAccessException, SipException, ParseException, InvalidArgumentException { 534 throws NoSuchFieldException, IllegalAccessException, SipException, ParseException, InvalidArgumentException {
535 MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory(); 535 MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
536 String characterSet = parentPlatform.getCharacterSet(); 536 String characterSet = parentPlatform.getCharacterSet();
537 // 设置编码, 防止中文乱码 537 // 设置编码, 防止中文乱码
538 messageFactory.setDefaultContentEncodingCharset(characterSet); 538 messageFactory.setDefaultContentEncodingCharset(characterSet);
539 - Dialog dialog = subscribeInfo.getDialog();  
540 - if (dialog == null || !dialog.getState().equals(DialogState.CONFIRMED)) {  
541 - return;  
542 - }  
543 - SIPRequest notifyRequest = (SIPRequest)dialog.createRequest(Request.NOTIFY); 539 +
  540 + SIPRequest notifyRequest = headerProviderPlatformProvider.createNotifyRequest(parentPlatform, catalogXmlContent, subscribeInfo);
544 541
545 notifyRequest.getCSeqHeader().setSeqNumber(redisCatchStorage.getCSEQ()); 542 notifyRequest.getCSeqHeader().setSeqNumber(redisCatchStorage.getCSEQ());
546 543
@@ -560,26 +557,32 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -560,26 +557,32 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
560 sipURI.setHost(parentPlatform.getServerIP()); 557 sipURI.setHost(parentPlatform.getServerIP());
561 sipURI.setPort(parentPlatform.getServerPort()); 558 sipURI.setPort(parentPlatform.getServerPort());
562 559
  560 +// ClientTransaction transaction = subscribeInfo.getClientTransaction();
  561 +// if (transaction == null || transaction.getState().equals(TransactionState.COMPLETED)) {
  562 +// if ("TCP".equals(parentPlatform.getTransport())) {
  563 +// transaction = tcpSipProvider.getNewClientTransaction(notifyRequest);
  564 +// } else if ("UDP".equals(parentPlatform.getTransport())) {
  565 +// transaction = udpSipProvider.getNewClientTransaction(notifyRequest);
  566 +// }
  567 +// }
  568 +
563 ClientTransaction transaction = null; 569 ClientTransaction transaction = null;
564 if ("TCP".equals(parentPlatform.getTransport())) { 570 if ("TCP".equals(parentPlatform.getTransport())) {
565 transaction = tcpSipProvider.getNewClientTransaction(notifyRequest); 571 transaction = tcpSipProvider.getNewClientTransaction(notifyRequest);
566 } else if ("UDP".equals(parentPlatform.getTransport())) { 572 } else if ("UDP".equals(parentPlatform.getTransport())) {
567 transaction = udpSipProvider.getNewClientTransaction(notifyRequest); 573 transaction = udpSipProvider.getNewClientTransaction(notifyRequest);
568 } 574 }
  575 +
569 // 添加错误订阅 576 // 添加错误订阅
570 if (errorEvent != null) { 577 if (errorEvent != null) {
571 - sipSubscribe.addErrorSubscribe(subscribeInfo.getCallId(), errorEvent); 578 + sipSubscribe.addErrorSubscribe(subscribeInfo.getRequest().getCallIdHeader().getCallId(), errorEvent);
572 } 579 }
573 // 添加订阅 580 // 添加订阅
574 if (okEvent != null) { 581 if (okEvent != null) {
575 - sipSubscribe.addOkSubscribe(subscribeInfo.getCallId(), okEvent); 582 + sipSubscribe.addOkSubscribe(subscribeInfo.getRequest().getCallIdHeader().getCallId(), okEvent);
576 } 583 }
577 - if (transaction == null) {  
578 - logger.error("平台{}的Transport错误:{}",parentPlatform.getServerGBId(), parentPlatform.getTransport());  
579 - return;  
580 - }  
581 - dialog.sendRequest(transaction);  
582 - 584 + transaction.sendRequest();
  585 + return transaction;
583 } 586 }
584 587
585 private String getCatalogXmlContentForCatalogAddOrUpdate(ParentPlatform parentPlatform, List<DeviceChannel> channels, int sumNum, String type, SubscribeInfo subscribeInfo) { 588 private String getCatalogXmlContentForCatalogAddOrUpdate(ParentPlatform parentPlatform, List<DeviceChannel> channels, int sumNum, String type, SubscribeInfo subscribeInfo) {
@@ -755,7 +758,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -755,7 +758,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
755 // callid 758 // callid
756 CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() 759 CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
757 : udpSipProvider.getNewCallId(); 760 : udpSipProvider.getNewCallId();
758 - Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, recordXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader); 761 + Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, recordXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
759 transmitRequest(parentPlatform, request); 762 transmitRequest(parentPlatform, request);
760 763
761 } catch (SipException | ParseException | InvalidArgumentException e) { 764 } catch (SipException | ParseException | InvalidArgumentException e) {
@@ -774,36 +777,8 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -774,36 +777,8 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
774 return false; 777 return false;
775 } 778 }
776 779
777 - byte[] dialogByteArray = sendRtpItem.getDialog();  
778 - if (dialogByteArray == null) {  
779 - return false;  
780 - }  
781 try{ 780 try{
782 - SIPDialog dialog = (SIPDialog) SerializeUtils.deSerialize(dialogByteArray);  
783 - SipStack sipStack;  
784 - if ("TCP".equals(platform.getTransport())) {  
785 - sipStack = tcpSipProvider.getSipStack();  
786 - } else {  
787 - sipStack = udpSipProvider.getSipStack();  
788 - }  
789 - SIPDialog sipDialog = ((SipStackImpl) sipStack).putDialog(dialog);  
790 - if (dialog != sipDialog) {  
791 - dialog = sipDialog;  
792 - }  
793 - if ("TCP".equals(platform.getTransport())) {  
794 - dialog.setSipProvider(tcpSipProvider);  
795 - } else {  
796 - dialog.setSipProvider(udpSipProvider);  
797 - }  
798 -  
799 - Field sipStackField = SIPDialog.class.getDeclaredField("sipStack");  
800 - sipStackField.setAccessible(true);  
801 - sipStackField.set(dialog, sipStack);  
802 - Field eventListenersField = SIPDialog.class.getDeclaredField("eventListeners");  
803 - eventListenersField.setAccessible(true);  
804 - eventListenersField.set(dialog, new HashSet<>());  
805 781
806 - SIPRequest messageRequest = (SIPRequest)dialog.createRequest(Request.MESSAGE);  
807 String characterSet = platform.getCharacterSet(); 782 String characterSet = platform.getCharacterSet();
808 StringBuffer mediaStatusXml = new StringBuffer(200); 783 StringBuffer mediaStatusXml = new StringBuffer(200);
809 mediaStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n"); 784 mediaStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
@@ -813,6 +788,10 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -813,6 +788,10 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
813 mediaStatusXml.append("<DeviceID>" + sendRtpItem.getChannelId() + "</DeviceID>\r\n"); 788 mediaStatusXml.append("<DeviceID>" + sendRtpItem.getChannelId() + "</DeviceID>\r\n");
814 mediaStatusXml.append("<NotifyType>121</NotifyType>\r\n"); 789 mediaStatusXml.append("<NotifyType>121</NotifyType>\r\n");
815 mediaStatusXml.append("</Notify>\r\n"); 790 mediaStatusXml.append("</Notify>\r\n");
  791 +
  792 + SIPRequest messageRequest = (SIPRequest)headerProviderPlatformProvider.createMessageRequest(platform, mediaStatusXml.toString(),
  793 + sendRtpItem);
  794 +
816 ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); 795 ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
817 messageRequest.setContent(mediaStatusXml.toString(), contentTypeHeader); 796 messageRequest.setContent(mediaStatusXml.toString(), contentTypeHeader);
818 SipURI sipURI = (SipURI) messageRequest.getRequestURI(); 797 SipURI sipURI = (SipURI) messageRequest.getRequestURI();
@@ -824,17 +803,15 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -824,17 +803,15 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
824 }else { 803 }else {
825 clientTransaction = udpSipProvider.getNewClientTransaction(messageRequest); 804 clientTransaction = udpSipProvider.getNewClientTransaction(messageRequest);
826 } 805 }
827 - dialog.sendRequest(clientTransaction); 806 + clientTransaction.sendRequest();
828 } catch (SipException e) { 807 } catch (SipException e) {
829 e.printStackTrace(); 808 e.printStackTrace();
830 return false; 809 return false;
831 } catch (ParseException e) { 810 } catch (ParseException e) {
832 e.printStackTrace(); 811 e.printStackTrace();
833 return false; 812 return false;
834 - } catch (NoSuchFieldException e) {  
835 - e.printStackTrace();  
836 - } catch (IllegalAccessException e) {  
837 - e.printStackTrace(); 813 + } catch (InvalidArgumentException e) {
  814 + throw new RuntimeException(e);
838 } 815 }
839 return true; 816 return true;
840 817
@@ -848,61 +825,46 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -848,61 +825,46 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
848 } 825 }
849 SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platform.getServerGBId(), null, null, callId); 826 SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platform.getServerGBId(), null, null, callId);
850 if (sendRtpItem != null) { 827 if (sendRtpItem != null) {
851 - String mediaServerId = sendRtpItem.getMediaServerId();  
852 - MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);  
853 - if (mediaServerItem != null) {  
854 - mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());  
855 - zlmrtpServerFactory.closeRTPServer(mediaServerItem, sendRtpItem.getStreamId());  
856 - }  
857 - byte[] dialogByteArray = sendRtpItem.getDialog();  
858 - if (dialogByteArray != null) {  
859 - SIPDialog dialog = (SIPDialog) SerializeUtils.deSerialize(dialogByteArray);  
860 - SipStack sipStack;  
861 - if ("TCP".equals(platform.getTransport())) {  
862 - sipStack = tcpSipProvider.getSipStack();  
863 - } else {  
864 - sipStack = udpSipProvider.getSipStack();  
865 - }  
866 - SIPDialog sipDialog = ((SipStackImpl) sipStack).putDialog(dialog);  
867 - if (dialog != sipDialog) {  
868 - dialog = sipDialog;  
869 - }  
870 - try {  
871 - if ("TCP".equals(platform.getTransport())) {  
872 - dialog.setSipProvider(tcpSipProvider);  
873 - } else {  
874 - dialog.setSipProvider(udpSipProvider);  
875 - }  
876 - Field sipStackField = SIPDialog.class.getDeclaredField("sipStack");  
877 - sipStackField.setAccessible(true);  
878 - sipStackField.set(dialog, sipStack);  
879 - Field eventListenersField = SIPDialog.class.getDeclaredField("eventListeners");  
880 - eventListenersField.setAccessible(true);  
881 - eventListenersField.set(dialog, new HashSet<>());  
882 -  
883 - Request byeRequest = dialog.createRequest(Request.BYE);  
884 -  
885 - SipURI byeURI = (SipURI) byeRequest.getRequestURI();  
886 - byeURI.setHost(platform.getServerIP());  
887 - byeURI.setPort(platform.getServerPort());  
888 - ClientTransaction clientTransaction;  
889 - if ("TCP".equals(platform.getTransport())) {  
890 - clientTransaction = tcpSipProvider.getNewClientTransaction(byeRequest);  
891 - } else {  
892 - clientTransaction = udpSipProvider.getNewClientTransaction(byeRequest);  
893 - }  
894 - dialog.sendRequest(clientTransaction);  
895 - } catch (SipException e) {  
896 - e.printStackTrace();  
897 - } catch (ParseException e) {  
898 - e.printStackTrace();  
899 - } catch (NoSuchFieldException e) {  
900 - e.printStackTrace();  
901 - } catch (IllegalAccessException e) {  
902 - e.printStackTrace();  
903 - } 828 + streamByeCmd(platform, sendRtpItem);
  829 + }
  830 + }
  831 +
  832 + @Override
  833 + public void streamByeCmd(ParentPlatform platform, SendRtpItem sendRtpItem) {
  834 + if (sendRtpItem == null ) {
  835 + logger.info("[向上级发送BYE], sendRtpItem 为NULL");
  836 + return;
  837 + }
  838 + if (platform == null) {
  839 + logger.info("[向上级发送BYE], platform 为NULL");
  840 + return;
  841 + }
  842 + logger.info("[向上级发送BYE], {}/{}", platform.getServerGBId(), sendRtpItem.getChannelId());
  843 + String mediaServerId = sendRtpItem.getMediaServerId();
  844 + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
  845 + if (mediaServerItem != null) {
  846 + mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
  847 + zlmrtpServerFactory.closeRTPServer(mediaServerItem, sendRtpItem.getStreamId());
  848 + }
  849 + try {
904 850
  851 + SIPRequest byeRequest = headerProviderPlatformProvider.createByeRequest(platform, sendRtpItem);
  852 + if (byeRequest == null) {
  853 + logger.warn("[向上级发送bye]:无法创建 byeRequest");
  854 + }
  855 + ClientTransaction clientTransaction;
  856 + if ("TCP".equals(platform.getTransport())) {
  857 + clientTransaction = tcpSipProvider.getNewClientTransaction(byeRequest);
  858 + } else {
  859 + clientTransaction = udpSipProvider.getNewClientTransaction(byeRequest);
905 } 860 }
  861 + clientTransaction.sendRequest();
  862 + } catch (SipException e) {
  863 + e.printStackTrace();
  864 + } catch (ParseException e) {
  865 + e.printStackTrace();
  866 + } catch (InvalidArgumentException e) {
  867 + throw new RuntimeException(e);
906 } 868 }
907 } 869 }
908 } 870 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request;
2 2
3 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 3 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  4 +import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
4 import gov.nist.javax.sip.SipProviderImpl; 5 import gov.nist.javax.sip.SipProviderImpl;
5 import gov.nist.javax.sip.SipStackImpl; 6 import gov.nist.javax.sip.SipStackImpl;
6 import gov.nist.javax.sip.message.SIPRequest; 7 import gov.nist.javax.sip.message.SIPRequest;
  8 +import gov.nist.javax.sip.message.SIPResponse;
7 import gov.nist.javax.sip.stack.SIPServerTransaction; 9 import gov.nist.javax.sip.stack.SIPServerTransaction;
8 import org.apache.commons.lang3.ArrayUtils; 10 import org.apache.commons.lang3.ArrayUtils;
9 import org.dom4j.Document; 11 import org.dom4j.Document;
@@ -19,10 +21,7 @@ import javax.sip.*; @@ -19,10 +21,7 @@ import javax.sip.*;
19 import javax.sip.address.Address; 21 import javax.sip.address.Address;
20 import javax.sip.address.AddressFactory; 22 import javax.sip.address.AddressFactory;
21 import javax.sip.address.SipURI; 23 import javax.sip.address.SipURI;
22 -import javax.sip.header.ContentTypeHeader;  
23 -import javax.sip.header.ExpiresHeader;  
24 -import javax.sip.header.HeaderFactory;  
25 -import javax.sip.header.ViaHeader; 24 +import javax.sip.header.*;
26 import javax.sip.message.MessageFactory; 25 import javax.sip.message.MessageFactory;
27 import javax.sip.message.Request; 26 import javax.sip.message.Request;
28 import javax.sip.message.Response; 27 import javax.sip.message.Response;
@@ -59,9 +58,6 @@ public abstract class SIPRequestProcessorParent { @@ -59,9 +58,6 @@ public abstract class SIPRequestProcessorParent {
59 public ServerTransaction getServerTransaction(RequestEvent evt) { 58 public ServerTransaction getServerTransaction(RequestEvent evt) {
60 Request request = evt.getRequest(); 59 Request request = evt.getRequest();
61 ServerTransaction serverTransaction = evt.getServerTransaction(); 60 ServerTransaction serverTransaction = evt.getServerTransaction();
62 - if (serverTransaction != null) {  
63 - System.out.println(serverTransaction.getState().toString());  
64 - }  
65 // 判断TCP还是UDP 61 // 判断TCP还是UDP
66 ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); 62 ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
67 String transport = reqViaHeader.getTransport(); 63 String transport = reqViaHeader.getTransport();
@@ -120,105 +116,107 @@ public abstract class SIPRequestProcessorParent { @@ -120,105 +116,107 @@ public abstract class SIPRequestProcessorParent {
120 return null; 116 return null;
121 } 117 }
122 118
  119 + class ResponseAckExtraParam{
  120 + String content;
  121 + ContentTypeHeader contentTypeHeader;
  122 + SipURI sipURI;
  123 + int expires = -1;
  124 + }
  125 +
123 /*** 126 /***
124 * 回复状态码 127 * 回复状态码
125 * 100 trying 128 * 100 trying
126 * 200 OK 129 * 200 OK
127 * 400 130 * 400
128 * 404 131 * 404
129 - * @param evt  
130 - * @throws SipException  
131 - * @throws InvalidArgumentException  
132 - * @throws ParseException  
133 */ 132 */
134 - public void responseAck(RequestEvent evt, int statusCode) throws SipException, InvalidArgumentException, ParseException {  
135 - Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());  
136 - ServerTransaction serverTransaction = getServerTransaction(evt);  
137 - if (serverTransaction == null) {  
138 - logger.warn("回复失败:{}", response);  
139 - return; 133 + public SIPResponse responseAck(ServerTransaction serverTransaction, int statusCode) throws SipException, InvalidArgumentException, ParseException {
  134 + return responseAck(serverTransaction, statusCode, null);
  135 + }
  136 +
  137 + public SIPResponse responseAck(ServerTransaction serverTransaction, int statusCode, String msg) throws SipException, InvalidArgumentException, ParseException {
  138 + return responseAck(serverTransaction, statusCode, msg, null);
  139 + }
  140 +
  141 + public SIPResponse responseAck(ServerTransaction serverTransaction, int statusCode, String msg, ResponseAckExtraParam responseAckExtraParam) throws SipException, InvalidArgumentException, ParseException {
  142 + ToHeader toHeader = (ToHeader) serverTransaction.getRequest().getHeader(ToHeader.NAME);
  143 + if (toHeader.getTag() == null) {
  144 + toHeader.setTag(SipUtils.getNewTag());
140 } 145 }
141 - serverTransaction.sendResponse(response);  
142 - if (statusCode >= 200 && !"NOTIFY".equalsIgnoreCase(evt.getRequest().getMethod())) { 146 + SIPResponse response = (SIPResponse)getMessageFactory().createResponse(statusCode, serverTransaction.getRequest());
  147 + if (msg != null) {
  148 + response.setReasonPhrase(msg);
  149 + }
  150 + if (responseAckExtraParam != null) {
  151 + if (responseAckExtraParam.sipURI != null && serverTransaction.getRequest().getMethod().equals(Request.INVITE)) {
  152 + logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort());
  153 + Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(
  154 + SipFactory.getInstance().createAddressFactory().createSipURI(responseAckExtraParam.sipURI.getUser(), responseAckExtraParam.sipURI.getHost()+":"+responseAckExtraParam.sipURI.getPort()
  155 + ));
  156 + response.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress));
  157 + }
  158 + if (responseAckExtraParam.contentTypeHeader != null) {
  159 + response.setContent(responseAckExtraParam.content, responseAckExtraParam.contentTypeHeader);
  160 + }
143 161
144 - if (serverTransaction.getDialog() != null) {  
145 - serverTransaction.getDialog().delete(); 162 + if (serverTransaction.getRequest().getMethod().equals(Request.SUBSCRIBE)) {
  163 + if (responseAckExtraParam.expires == -1) {
  164 + logger.error("[参数不全] 2xx的SUBSCRIBE回复,必须设置Expires header");
  165 + }else {
  166 + ExpiresHeader expiresHeader = SipFactory.getInstance().createHeaderFactory().createExpiresHeader(responseAckExtraParam.expires);
  167 + response.addHeader(expiresHeader);
  168 + }
  169 + }
  170 + }else {
  171 + if (serverTransaction.getRequest().getMethod().equals(Request.SUBSCRIBE)) {
  172 + logger.error("[参数不全] 2xx的SUBSCRIBE回复,必须设置Expires header");
146 } 173 }
147 } 174 }
148 - }  
149 -  
150 - public void responseAck(RequestEvent evt, int statusCode, String msg) throws SipException, InvalidArgumentException, ParseException {  
151 - Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());  
152 - response.setReasonPhrase(msg);  
153 - ServerTransaction serverTransaction = getServerTransaction(evt);  
154 serverTransaction.sendResponse(response); 175 serverTransaction.sendResponse(response);
155 - if (statusCode >= 200 && !"NOTIFY".equalsIgnoreCase(evt.getRequest().getMethod())) { 176 + if (statusCode >= 200 && !"NOTIFY".equalsIgnoreCase(serverTransaction.getRequest().getMethod())) {
156 if (serverTransaction.getDialog() != null) { 177 if (serverTransaction.getDialog() != null) {
157 serverTransaction.getDialog().delete(); 178 serverTransaction.getDialog().delete();
158 } 179 }
159 } 180 }
  181 + return response;
160 } 182 }
161 183
162 /** 184 /**
163 * 回复带sdp的200 185 * 回复带sdp的200
164 - * @param evt  
165 - * @param sdp  
166 - * @throws SipException  
167 - * @throws InvalidArgumentException  
168 - * @throws ParseException  
169 */ 186 */
170 - public void responseSdpAck(RequestEvent evt, String sdp, ParentPlatform platform) throws SipException, InvalidArgumentException, ParseException {  
171 - Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());  
172 - SipFactory sipFactory = SipFactory.getInstance();  
173 - ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");  
174 - response.setContent(sdp, contentTypeHeader); 187 + public SIPResponse responseSdpAck(ServerTransaction serverTransaction, String sdp, ParentPlatform platform) throws SipException, InvalidArgumentException, ParseException {
  188 +
  189 + ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
175 190
176 // 兼容国标中的使用编码@域名作为RequestURI的情况 191 // 兼容国标中的使用编码@域名作为RequestURI的情况
177 - SipURI sipURI = (SipURI)evt.getRequest().getRequestURI(); 192 + SipURI sipURI = (SipURI)serverTransaction.getRequest().getRequestURI();
178 if (sipURI.getPort() == -1) { 193 if (sipURI.getPort() == -1) {
179 - sipURI = sipFactory.createAddressFactory().createSipURI(platform.getServerGBId(), platform.getServerIP()+":"+platform.getServerPort()); 194 + sipURI = SipFactory.getInstance().createAddressFactory().createSipURI(platform.getServerGBId(), platform.getServerIP()+":"+platform.getServerPort());
180 } 195 }
181 - logger.debug("responseSdpAck SipURI: {}:{}", sipURI.getHost(), sipURI.getPort()); 196 + ResponseAckExtraParam responseAckExtraParam = new ResponseAckExtraParam();
  197 + responseAckExtraParam.contentTypeHeader = contentTypeHeader;
  198 + responseAckExtraParam.content = sdp;
  199 + responseAckExtraParam.sipURI = sipURI;
182 200
183 - Address concatAddress = sipFactory.createAddressFactory().createAddress(  
184 - sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost()+":"+sipURI.getPort()  
185 - ));  
186 - response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));  
187 - ServerTransaction serverTransaction = getServerTransaction(evt);  
188 - if (serverTransaction == null) {  
189 -  
190 - }  
191 - getServerTransaction(evt).sendResponse(response); 201 + return responseAck(serverTransaction, Response.OK, null, responseAckExtraParam);
192 } 202 }
193 203
194 /** 204 /**
195 * 回复带xml的200 205 * 回复带xml的200
196 - * @param evt  
197 - * @param xml  
198 - * @throws SipException  
199 - * @throws InvalidArgumentException  
200 - * @throws ParseException  
201 */ 206 */
202 - public Response responseXmlAck(RequestEvent evt, String xml, ParentPlatform platform) throws SipException, InvalidArgumentException, ParseException {  
203 - Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());  
204 - SipFactory sipFactory = SipFactory.getInstance();  
205 - ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");  
206 - response.setContent(xml, contentTypeHeader); 207 + public SIPResponse responseXmlAck(ServerTransaction serverTransaction, String xml, ParentPlatform platform, Integer expires) throws SipException, InvalidArgumentException, ParseException {
  208 + ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
207 209
208 - // 兼容国标中的使用编码@域名作为RequestURI的情况  
209 - SipURI sipURI = (SipURI)evt.getRequest().getRequestURI(); 210 + SipURI sipURI = (SipURI)serverTransaction.getRequest().getRequestURI();
210 if (sipURI.getPort() == -1) { 211 if (sipURI.getPort() == -1) {
211 - sipURI = sipFactory.createAddressFactory().createSipURI(platform.getServerGBId(), platform.getServerIP()+":"+platform.getServerPort()); 212 + sipURI = SipFactory.getInstance().createAddressFactory().createSipURI(platform.getServerGBId(), platform.getServerIP()+":"+platform.getServerPort());
212 } 213 }
213 - logger.debug("responseXmlAck SipURI: {}:{}", sipURI.getHost(), sipURI.getPort());  
214 -  
215 - Address concatAddress = sipFactory.createAddressFactory().createAddress(  
216 - sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost()+":"+sipURI.getPort()  
217 - ));  
218 - response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));  
219 - response.addHeader(evt.getRequest().getHeader(ExpiresHeader.NAME));  
220 - getServerTransaction(evt).sendResponse(response);  
221 - return response; 214 + ResponseAckExtraParam responseAckExtraParam = new ResponseAckExtraParam();
  215 + responseAckExtraParam.contentTypeHeader = contentTypeHeader;
  216 + responseAckExtraParam.content = xml;
  217 + responseAckExtraParam.sipURI = sipURI;
  218 + responseAckExtraParam.expires = expires;
  219 + return responseAck(serverTransaction, Response.OK, null, responseAckExtraParam);
222 } 220 }
223 221
224 public Element getRootElement(RequestEvent evt) throws DocumentException { 222 public Element getRootElement(RequestEvent evt) throws DocumentException {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
@@ -16,7 +16,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; @@ -16,7 +16,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
16 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 16 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
17 import com.genersoft.iot.vmp.service.IMediaServerService; 17 import com.genersoft.iot.vmp.service.IMediaServerService;
18 import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg; 18 import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg;
19 -import com.genersoft.iot.vmp.service.impl.RedisGbPlayMsgListener; 19 +import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener;
20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
21 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 21 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
22 import gov.nist.javax.sip.message.SIPRequest; 22 import gov.nist.javax.sip.message.SIPRequest;
@@ -29,6 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired; @@ -29,6 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired;
29 import org.springframework.stereotype.Component; 29 import org.springframework.stereotype.Component;
30 30
31 import javax.sip.*; 31 import javax.sip.*;
  32 +import javax.sip.RequestEvent;
32 import javax.sip.address.SipURI; 33 import javax.sip.address.SipURI;
33 import javax.sip.header.CallIdHeader; 34 import javax.sip.header.CallIdHeader;
34 import javax.sip.header.FromHeader; 35 import javax.sip.header.FromHeader;
@@ -93,47 +94,41 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -93,47 +94,41 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
93 */ 94 */
94 @Override 95 @Override
95 public void process(RequestEvent evt) { 96 public void process(RequestEvent evt) {
96 - Dialog dialog = evt.getDialog();  
97 - CallIdHeader callIdHeader = (CallIdHeader) evt.getRequest().getHeader(CallIdHeader.NAME);  
98 - if (dialog == null) {  
99 - return; 97 + CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
  98 +
  99 + String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
  100 + logger.info("[收到ACK]: platformGbId->{}", platformGbId);
  101 + ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformGbId);
  102 + // 取消设置的超时任务
  103 + dynamicTask.stop(callIdHeader.getCallId());
  104 + String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
  105 + SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId, null, callIdHeader.getCallId());
  106 + String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
  107 + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
  108 + logger.info("收到ACK,rtp/{}开始向上级推流, 目标 {}:{},SSRC={}", sendRtpItem.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc());
  109 + Map<String, Object> param = new HashMap<>();
  110 + param.put("vhost","__defaultVhost__");
  111 + param.put("app",sendRtpItem.getApp());
  112 + param.put("stream",sendRtpItem.getStreamId());
  113 + param.put("ssrc", sendRtpItem.getSsrc());
  114 + param.put("src_port", sendRtpItem.getLocalPort());
  115 + param.put("pt", sendRtpItem.getPt());
  116 + param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
  117 + param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
  118 + if (!sendRtpItem.isTcp() && parentPlatform.isRtcp()) {
  119 + // 开启rtcp保活
  120 + param.put("udp_rtcp_timeout", "1");
  121 + }
  122 +
  123 + JSONObject jsonObject;
  124 + if (sendRtpItem.isTcpActive()) {
  125 + jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param);
  126 + } else {
  127 + param.put("is_udp", is_Udp);
  128 + param.put("dst_url", sendRtpItem.getIp());
  129 + param.put("dst_port", sendRtpItem.getPort());
  130 + jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
100 } 131 }
101 - if (dialog.getState() == DialogState.CONFIRMED) {  
102 - String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();  
103 - logger.info("ACK请求: platformGbId->{}", platformGbId);  
104 - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformGbId);  
105 - // 取消设置的超时任务  
106 - dynamicTask.stop(callIdHeader.getCallId());  
107 -// String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();  
108 - SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, null, null, callIdHeader.getCallId());  
109 - String is_Udp = sendRtpItem.isTcp() ? "0" : "1";  
110 - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());  
111 - logger.info("[收到ACK],开始使用{}向上级推流 {}/{}->{}:{}({})", sendRtpItem.isTcp() ? "TCP" : "UDP",  
112 - sendRtpItem.getApp(), sendRtpItem.getStreamId(),  
113 - sendRtpItem.getIp(), sendRtpItem.getPort(),  
114 - sendRtpItem.getSsrc());  
115 - Map<String, Object> param = new HashMap<>();  
116 - param.put("vhost", "__defaultVhost__");  
117 - param.put("app", sendRtpItem.getApp());  
118 - param.put("stream", sendRtpItem.getStreamId());  
119 - param.put("ssrc", sendRtpItem.getSsrc());  
120 - param.put("src_port", sendRtpItem.getLocalPort());  
121 - param.put("pt", sendRtpItem.getPt());  
122 - param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");  
123 - param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");  
124 - if (!sendRtpItem.isTcp() && parentPlatform.isRtcp()) {  
125 - // 开启rtcp保活  
126 - param.put("udp_rtcp_timeout", "1");  
127 - }  
128 - JSONObject jsonObject;  
129 - if (sendRtpItem.isTcpActive()) {  
130 - jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param);  
131 - } else {  
132 - param.put("is_udp", is_Udp);  
133 - param.put("dst_url", sendRtpItem.getIp());  
134 - param.put("dst_port", sendRtpItem.getPort());  
135 - jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);  
136 - }  
137 132
138 if (jsonObject == null) { 133 if (jsonObject == null) {
139 logger.error("RTP推流失败: 请检查ZLM服务"); 134 logger.error("RTP推流失败: 请检查ZLM服务");
@@ -155,12 +150,8 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -155,12 +150,8 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
155 // 语音对讲 150 // 语音对讲
156 try { 151 try {
157 cmder.streamByeCmd((SIPDialog) evt.getDialog(), sendRtpItem.getChannelId(), (SIPRequest) evt.getRequest(), null); 152 cmder.streamByeCmd((SIPDialog) evt.getDialog(), sendRtpItem.getChannelId(), (SIPRequest) evt.getRequest(), null);
158 - } catch (SipException e) {  
159 - throw new RuntimeException(e);  
160 - } catch (ParseException e) {  
161 - throw new RuntimeException(e);  
162 - } catch (InvalidArgumentException e) {  
163 - throw new RuntimeException(e); 153 + } catch (SipException | ParseException | InvalidArgumentException e) {
  154 + logger.error("[命令发送失败] 停止语音对讲: {}", e.getMessage());
164 } 155 }
165 } else { 156 } else {
166 // 向上级平台 157 // 向上级平台
@@ -188,12 +179,8 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -188,12 +179,8 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
188 if (jsonObject == null) { 179 if (jsonObject == null) {
189 logger.error("RTP推流失败: 请检查ZLM服务"); 180 logger.error("RTP推流失败: 请检查ZLM服务");
190 } else if (jsonObject.getInteger("code") == 0) { 181 } else if (jsonObject.getInteger("code") == 0) {
  182 + logger.info("调用ZLM推流接口, 结果: {}", jsonObject);
191 logger.info("RTP推流成功[ {}/{} ],{}->{}:{}, " ,param.get("app"), param.get("stream"), jsonObject.getString("local_port"), param.get("dst_url"), param.get("dst_port")); 183 logger.info("RTP推流成功[ {}/{} ],{}->{}:{}, " ,param.get("app"), param.get("stream"), jsonObject.getString("local_port"), param.get("dst_url"), param.get("dst_port"));
192 - byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());  
193 - sendRtpItem.setDialog(dialogByteArray);  
194 - byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());  
195 - sendRtpItem.setTransaction(transactionByteArray);  
196 - redisCatchStorage.updateSendRTPSever(sendRtpItem);  
197 } else { 184 } else {
198 logger.error("RTP推流失败: {}, 参数:{}",jsonObject.getString("msg"),JSONObject.toJSON(param)); 185 logger.error("RTP推流失败: {}, 参数:{}",jsonObject.getString("msg"),JSONObject.toJSON(param));
199 if (sendRtpItem.isOnlyAudio()) { 186 if (sendRtpItem.isOnlyAudio()) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
@@ -82,77 +82,69 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In @@ -82,77 +82,69 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
82 @Override 82 @Override
83 public void process(RequestEvent evt) { 83 public void process(RequestEvent evt) {
84 try { 84 try {
85 - responseAck(evt, Response.OK);  
86 - Dialog dialog = evt.getDialog(); 85 + responseAck(getServerTransaction(evt), Response.OK);
87 CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME); 86 CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
88 - if (dialog == null) {  
89 - return;  
90 - }  
91 - if (dialog.getState().equals(DialogState.TERMINATED)) {  
92 - String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();  
93 - String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();  
94 - SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, null, null, callIdHeader.getCallId());  
95 - logger.info("收到bye, [{}/{}]", platformGbId, channelId);  
96 - if (sendRtpItem != null ){  
97 - String streamId = sendRtpItem.getStreamId();  
98 - Map<String, Object> param = new HashMap<>();  
99 - param.put("vhost","__defaultVhost__");  
100 - param.put("app",sendRtpItem.getApp());  
101 - param.put("stream",streamId);  
102 - param.put("ssrc",sendRtpItem.getSsrc());  
103 - logger.info("收到bye:停止向上级推流:" + streamId);  
104 - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());  
105 - zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);  
106 - redisCatchStorage.deleteSendRTPServer(platformGbId, sendRtpItem.getChannelId(), callIdHeader.getCallId(), null);  
107 - redisCatchStorage.deleteSendRTPServer(platformGbId, channelId, callIdHeader.getCallId(), null);  
108 - zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);  
109 - int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId);  
110 - if (totalReaderCount <= 0) {  
111 - logger.info("收到bye: {} 无其它观看者,通知设备停止推流", streamId);  
112 - if (sendRtpItem.getPlayType().equals(InviteStreamType.PLAY)) {  
113 - cmder.streamByeCmd(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId(), streamId, null);  
114 - }  
115 - if (sendRtpItem.isOnlyAudio()) {  
116 - playService.stopAudioBroadcast(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());  
117 - }  
118 - if (sendRtpItem.getPlayType().equals(InviteStreamType.PUSH)) {  
119 - MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0,  
120 - sendRtpItem.getApp(), sendRtpItem.getStreamId(), sendRtpItem.getChannelId(),  
121 - sendRtpItem.getPlatformId(), null, null, sendRtpItem.getMediaServerId());  
122 - redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel);  
123 - } 87 + String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
  88 + String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
  89 + SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId, null, callIdHeader.getCallId());
  90 + logger.info("[收到bye] {}/{}", platformGbId, channelId);
  91 + if (sendRtpItem != null){
  92 + String streamId = sendRtpItem.getStreamId();
  93 + Map<String, Object> param = new HashMap<>();
  94 + param.put("vhost","__defaultVhost__");
  95 + param.put("app",sendRtpItem.getApp());
  96 + param.put("stream",streamId);
  97 + param.put("ssrc",sendRtpItem.getSsrc());
  98 + logger.info("[收到bye] 停止向上级推流:{}", streamId);
  99 + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
  100 + redisCatchStorage.deleteSendRTPServer(platformGbId, channelId, callIdHeader.getCallId(), null);
  101 + zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
  102 + int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId);
  103 + if (totalReaderCount <= 0) {
  104 + logger.info("[收到bye] {} 无其它观看者,通知设备停止推流", streamId);
  105 + if (sendRtpItem.getPlayType().equals(InviteStreamType.PLAY)) {
  106 + cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId, streamId, null);
124 } 107 }
125 - }  
126 - // 可能是设备主动停止  
127 - Device device = storager.queryVideoDeviceByChannelId(platformGbId);  
128 - if (device != null) {  
129 - storager.stopPlay(device.getDeviceId(), channelId);  
130 - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);  
131 - if (streamInfo != null) {  
132 - redisCatchStorage.stopPlay(streamInfo);  
133 - mediaServerService.closeRTPServer(streamInfo.getMediaServerId(), streamInfo.getStream()); 108 + if (sendRtpItem.isOnlyAudio()) {
  109 + playService.stopAudioBroadcast(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
134 } 110 }
135 - SsrcTransaction ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "play", null);  
136 - if (ssrcTransactionForPlay != null){  
137 - SIPDialog dialogForPlay = (SIPDialog) SerializeUtils.deSerialize(ssrcTransactionForPlay.getDialog());  
138 - if (dialogForPlay.getCallId().getCallId().equals(callIdHeader.getCallId())){  
139 - // 释放ssrc  
140 - MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlay.getMediaServerId());  
141 - if (mediaServerItem != null) {  
142 - mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransactionForPlay.getSsrc());  
143 - }  
144 - streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlay.getStream());  
145 - } 111 + if (sendRtpItem.getPlayType().equals(InviteStreamType.PUSH)) {
  112 + MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0,
  113 + sendRtpItem.getApp(), sendRtpItem.getStreamId(), sendRtpItem.getChannelId(),
  114 + sendRtpItem.getPlatformId(), null, null, sendRtpItem.getMediaServerId());
  115 + redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel);
146 } 116 }
147 - SsrcTransaction ssrcTransactionForPlayBack = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, callIdHeader.getCallId(), null);  
148 - if (ssrcTransactionForPlayBack != null) { 117 + }
  118 + }
  119 + // 可能是设备主动停止
  120 + Device device = storager.queryVideoDeviceByChannelId(platformGbId);
  121 + if (device != null) {
  122 + storager.stopPlay(device.getDeviceId(), channelId);
  123 + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);
  124 + if (streamInfo != null) {
  125 + redisCatchStorage.stopPlay(streamInfo);
  126 + mediaServerService.closeRTPServer(streamInfo.getMediaServerId(), streamInfo.getStream());
  127 + }
  128 + SsrcTransaction ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "play", null);
  129 + if (ssrcTransactionForPlay != null){
  130 + SIPDialog dialogForPlay = (SIPDialog) SerializeUtils.deSerialize(ssrcTransactionForPlay.getDialog());
  131 + if (dialogForPlay.getCallId().getCallId().equals(callIdHeader.getCallId())){
149 // 释放ssrc 132 // 释放ssrc
150 - MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlayBack.getMediaServerId()); 133 + MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlay.getMediaServerId());
151 if (mediaServerItem != null) { 134 if (mediaServerItem != null) {
152 - mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransactionForPlayBack.getSsrc()); 135 + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransactionForPlay.getSsrc());
153 } 136 }
154 - streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlayBack.getStream()); 137 + streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlay.getStream());
  138 + }
  139 + }
  140 + SsrcTransaction ssrcTransactionForPlayBack = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, callIdHeader.getCallId(), null);
  141 + if (ssrcTransactionForPlayBack != null) {
  142 + // 释放ssrc
  143 + MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlayBack.getMediaServerId());
  144 + if (mediaServerItem != null) {
  145 + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransactionForPlayBack.getSsrc());
155 } 146 }
  147 + streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlayBack.getStream());
156 } 148 }
157 } 149 }
158 } catch (SipException e) { 150 } catch (SipException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -14,7 +14,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; @@ -14,7 +14,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
14 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; 14 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
15 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; 15 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
16 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; 16 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
17 -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;  
18 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; 17 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
19 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; 18 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
20 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 19 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
@@ -32,7 +31,8 @@ import com.genersoft.iot.vmp.service.IStreamPushService; @@ -32,7 +31,8 @@ import com.genersoft.iot.vmp.service.IStreamPushService;
32 import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; 31 import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
33 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 32 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
34 import com.genersoft.iot.vmp.service.impl.RedisGbPlayMsgListener; 33 import com.genersoft.iot.vmp.service.impl.RedisGbPlayMsgListener;
35 -import com.genersoft.iot.vmp.service.impl.RedisPushStreamResponseListener; 34 +import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener;
  35 +import com.genersoft.iot.vmp.service.redisMsg.RedisPushStreamResponseListener;
36 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 36 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
37 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 37 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
38 import com.genersoft.iot.vmp.utils.DateUtil; 38 import com.genersoft.iot.vmp.utils.DateUtil;
@@ -43,6 +43,8 @@ import gov.nist.javax.sdp.TimeDescriptionImpl; @@ -43,6 +43,8 @@ import gov.nist.javax.sdp.TimeDescriptionImpl;
43 import gov.nist.javax.sdp.fields.TimeField; 43 import gov.nist.javax.sdp.fields.TimeField;
44 import gov.nist.javax.sip.message.SIPRequest; 44 import gov.nist.javax.sip.message.SIPRequest;
45 import gov.nist.javax.sip.stack.SIPDialog; 45 import gov.nist.javax.sip.stack.SIPDialog;
  46 +import gov.nist.javax.sip.message.SIPRequest;
  47 +import gov.nist.javax.sip.message.SIPResponse;
46 import org.slf4j.Logger; 48 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory; 49 import org.slf4j.LoggerFactory;
48 import org.springframework.beans.factory.InitializingBean; 50 import org.springframework.beans.factory.InitializingBean;
@@ -160,17 +162,19 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -160,17 +162,19 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
160 String channelId = SipUtils.getChannelIdFromRequest(request); 162 String channelId = SipUtils.getChannelIdFromRequest(request);
161 String requesterId = SipUtils.getUserIdFromFromHeader(request); 163 String requesterId = SipUtils.getUserIdFromFromHeader(request);
162 CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME); 164 CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
  165 + ServerTransaction serverTransaction = getServerTransaction(evt);
163 if (requesterId == null || channelId == null) { 166 if (requesterId == null || channelId == null) {
164 logger.info("无法从FromHeader的Address中获取到平台id,返回400"); 167 logger.info("无法从FromHeader的Address中获取到平台id,返回400");
165 // 参数不全, 发400,请求错误 168 // 参数不全, 发400,请求错误
166 - responseAck(evt, Response.BAD_REQUEST); 169 + responseAck(serverTransaction, Response.BAD_REQUEST);
167 return; 170 return;
168 } 171 }
169 172
  173 +
170 // 查询请求是否来自上级平台\设备 174 // 查询请求是否来自上级平台\设备
171 ParentPlatform platform = storager.queryParentPlatByServerGBId(requesterId); 175 ParentPlatform platform = storager.queryParentPlatByServerGBId(requesterId);
172 if (platform == null) { 176 if (platform == null) {
173 - inviteFromDeviceHandle(evt, requesterId, channelId); 177 + inviteFromDeviceHandle(serverTransaction, requesterId);
174 } else { 178 } else {
175 // 查询平台下是否有该通道 179 // 查询平台下是否有该通道
176 DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId); 180 DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
@@ -182,12 +186,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -182,12 +186,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
182 StreamProxyItem proxyByAppAndStream =null; 186 StreamProxyItem proxyByAppAndStream =null;
183 // 不是通道可能是直播流 187 // 不是通道可能是直播流
184 if (channel != null && gbStream == null) { 188 if (channel != null && gbStream == null) {
185 - if (channel.getStatus() == 0) {  
186 - logger.info("通道离线,返回400");  
187 - responseAck(evt, Response.BAD_REQUEST, "channel [" + channel.getChannelId() + "] offline");  
188 - return;  
189 - }  
190 - responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中 189 +// if (channel.getStatus() == 0) {
  190 +// logger.info("通道离线,返回400");
  191 +// responseAck(serverTransaction, Response.BAD_REQUEST, "channel [" + channel.getChannelId() + "] offline");
  192 +// return;
  193 +// }
  194 + // 通道存在,发100,TRYING
  195 + responseAck(serverTransaction, Response.TRYING);
191 } else if (channel == null && gbStream != null) { 196 } else if (channel == null && gbStream != null) {
192 197
193 String mediaServerId = gbStream.getMediaServerId(); 198 String mediaServerId = gbStream.getMediaServerId();
@@ -195,13 +200,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -195,13 +200,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
195 if (mediaServerItem == null) { 200 if (mediaServerItem == null) {
196 if ("proxy".equals(gbStream.getStreamType())) { 201 if ("proxy".equals(gbStream.getStreamType())) {
197 logger.info("[ app={}, stream={} ]找不到zlm {},返回410", gbStream.getApp(), gbStream.getStream(), mediaServerId); 202 logger.info("[ app={}, stream={} ]找不到zlm {},返回410", gbStream.getApp(), gbStream.getStream(), mediaServerId);
198 - responseAck(evt, Response.GONE); 203 + responseAck(serverTransaction, Response.GONE);
199 return; 204 return;
200 } else { 205 } else {
201 streamPushItem = streamPushService.getPush(gbStream.getApp(), gbStream.getStream()); 206 streamPushItem = streamPushService.getPush(gbStream.getApp(), gbStream.getStream());
202 if (streamPushItem == null || streamPushItem.getServerId().equals(userSetting.getServerId())) { 207 if (streamPushItem == null || streamPushItem.getServerId().equals(userSetting.getServerId())) {
203 logger.info("[ app={}, stream={} ]找不到zlm {},返回410", gbStream.getApp(), gbStream.getStream(), mediaServerId); 208 logger.info("[ app={}, stream={} ]找不到zlm {},返回410", gbStream.getApp(), gbStream.getStream(), mediaServerId);
204 - responseAck(evt, Response.GONE); 209 + responseAck(serverTransaction, Response.GONE);
205 return; 210 return;
206 } 211 }
207 } 212 }
@@ -210,25 +215,25 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -210,25 +215,25 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
210 streamPushItem = streamPushService.getPush(gbStream.getApp(), gbStream.getStream()); 215 streamPushItem = streamPushService.getPush(gbStream.getApp(), gbStream.getStream());
211 if (streamPushItem == null) { 216 if (streamPushItem == null) {
212 logger.info("[ app={}, stream={} ]找不到zlm {},返回410", gbStream.getApp(), gbStream.getStream(), mediaServerId); 217 logger.info("[ app={}, stream={} ]找不到zlm {},返回410", gbStream.getApp(), gbStream.getStream(), mediaServerId);
213 - responseAck(evt, Response.GONE); 218 + responseAck(serverTransaction, Response.GONE);
214 return; 219 return;
215 } 220 }
216 }else if("proxy".equals(gbStream.getStreamType())){ 221 }else if("proxy".equals(gbStream.getStreamType())){
217 proxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(gbStream.getApp(), gbStream.getStream()); 222 proxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(gbStream.getApp(), gbStream.getStream());
218 if (proxyByAppAndStream == null) { 223 if (proxyByAppAndStream == null) {
219 logger.info("[ app={}, stream={} ]找不到zlm {},返回410", gbStream.getApp(), gbStream.getStream(), mediaServerId); 224 logger.info("[ app={}, stream={} ]找不到zlm {},返回410", gbStream.getApp(), gbStream.getStream(), mediaServerId);
220 - responseAck(evt, Response.GONE); 225 + responseAck(serverTransaction, Response.GONE);
221 return; 226 return;
222 } 227 }
223 } 228 }
224 } 229 }
225 - responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中 230 + responseAck(serverTransaction, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
226 } else if (catalog != null) { 231 } else if (catalog != null) {
227 - responseAck(evt, Response.BAD_REQUEST, "catalog channel can not play"); // 目录不支持点播 232 + responseAck(serverTransaction, Response.BAD_REQUEST, "catalog channel can not play"); // 目录不支持点播
228 return; 233 return;
229 } else { 234 } else {
230 logger.info("通道不存在,返回404"); 235 logger.info("通道不存在,返回404");
231 - responseAck(evt, Response.NOT_FOUND); // 通道不存在,发404,资源不存在 236 + responseAck(serverTransaction, Response.NOT_FOUND); // 通道不存在,发404,资源不存在
232 return; 237 return;
233 } 238 }
234 // 解析sdp消息, 使用jainsip 自带的sdp解析方式 239 // 解析sdp消息, 使用jainsip 自带的sdp解析方式
@@ -241,7 +246,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -241,7 +246,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
241 String ssrc; 246 String ssrc;
242 SessionDescription sdp; 247 SessionDescription sdp;
243 if (ssrcIndex >= 0) { 248 if (ssrcIndex >= 0) {
244 - //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 249 + //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段
245 ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); 250 ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
246 String substring = contentString.substring(0, contentString.indexOf("y=")); 251 String substring = contentString.substring(0, contentString.indexOf("y="));
247 sdp = SdpFactory.getInstance().createSessionDescription(substring); 252 sdp = SdpFactory.getInstance().createSessionDescription(substring);
@@ -288,9 +293,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -288,9 +293,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
288 mediaTransmissionTCP = true; 293 mediaTransmissionTCP = true;
289 if ("active".equalsIgnoreCase(setup)) { 294 if ("active".equalsIgnoreCase(setup)) {
290 tcpActive = true; 295 tcpActive = true;
291 - // 不支持tcp主动  
292 - responseAck(evt, Response.NOT_IMPLEMENTED, "tcp active not support"); // 目录不支持点播  
293 - return;  
294 } else if ("passive".equalsIgnoreCase(setup)) { 296 } else if ("passive".equalsIgnoreCase(setup)) {
295 tcpActive = false; 297 tcpActive = false;
296 } 298 }
@@ -302,7 +304,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -302,7 +304,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
302 if (port == -1) { 304 if (port == -1) {
303 logger.info("不支持的媒体格式,返回415"); 305 logger.info("不支持的媒体格式,返回415");
304 // 回复不支持的格式 306 // 回复不支持的格式
305 - responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415 307 + responseAck(serverTransaction, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415
306 return; 308 return;
307 } 309 }
308 String username = sdp.getOrigin().getUsername(); 310 String username = sdp.getOrigin().getUsername();
@@ -315,24 +317,25 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -315,24 +317,25 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
315 device = storager.queryVideoDeviceByPlatformIdAndChannelId(requesterId, channelId); 317 device = storager.queryVideoDeviceByPlatformIdAndChannelId(requesterId, channelId);
316 if (device == null) { 318 if (device == null) {
317 logger.warn("点播平台{}的通道{}时未找到设备信息", requesterId, channel); 319 logger.warn("点播平台{}的通道{}时未找到设备信息", requesterId, channel);
318 - responseAck(evt, Response.SERVER_INTERNAL_ERROR); 320 + responseAck(serverTransaction, Response.SERVER_INTERNAL_ERROR);
319 return; 321 return;
320 } 322 }
321 mediaServerItem = playService.getNewMediaServerItem(device); 323 mediaServerItem = playService.getNewMediaServerItem(device);
322 if (mediaServerItem == null) { 324 if (mediaServerItem == null) {
323 logger.warn("未找到可用的zlm"); 325 logger.warn("未找到可用的zlm");
324 - responseAck(evt, Response.BUSY_HERE); 326 + responseAck(serverTransaction, Response.BUSY_HERE);
325 return; 327 return;
326 } 328 }
327 SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, 329 SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
328 device.getDeviceId(), channelId, 330 device.getDeviceId(), channelId,
329 mediaTransmissionTCP); 331 mediaTransmissionTCP);
  332 +
330 if (tcpActive != null) { 333 if (tcpActive != null) {
331 sendRtpItem.setTcpActive(tcpActive); 334 sendRtpItem.setTcpActive(tcpActive);
332 } 335 }
333 if (sendRtpItem == null) { 336 if (sendRtpItem == null) {
334 logger.warn("服务器端口资源不足"); 337 logger.warn("服务器端口资源不足");
335 - responseAck(evt, Response.BUSY_HERE); 338 + responseAck(serverTransaction, Response.BUSY_HERE);
336 return; 339 return;
337 } 340 }
338 sendRtpItem.setCallId(callIdHeader.getCallId()); 341 sendRtpItem.setCallId(callIdHeader.getCallId());
@@ -374,7 +377,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -374,7 +377,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
374 // 回复bye 377 // 回复bye
375 cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId()); 378 cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());
376 }, 60 * 1000); 379 }, 60 * 1000);
377 - responseSdpAck(evt, content.toString(), platform); 380 + responseSdpAck(serverTransaction, content.toString(), platform);
378 381
379 } catch (SipException e) { 382 } catch (SipException e) {
380 e.printStackTrace(); 383 e.printStackTrace();
@@ -389,8 +392,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -389,8 +392,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
389 Response response = null; 392 Response response = null;
390 try { 393 try {
391 response = getMessageFactory().createResponse(event.statusCode, evt.getRequest()); 394 response = getMessageFactory().createResponse(event.statusCode, evt.getRequest());
392 - ServerTransaction serverTransaction = getServerTransaction(evt);  
393 serverTransaction.sendResponse(response); 395 serverTransaction.sendResponse(response);
  396 + System.out.println("未知错误。直接转发设备点播的错误");
394 if (serverTransaction.getDialog() != null) { 397 if (serverTransaction.getDialog() != null) {
395 serverTransaction.getDialog().delete(); 398 serverTransaction.getDialog().delete();
396 } 399 }
@@ -414,7 +417,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -414,7 +417,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
414 } 417 }
415 redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); 418 redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
416 try { 419 try {
417 - responseAck(evt, Response.REQUEST_TIMEOUT); 420 + responseAck(serverTransaction, Response.REQUEST_TIMEOUT);
418 } catch (SipException e) { 421 } catch (SipException e) {
419 e.printStackTrace(); 422 e.printStackTrace();
420 } catch (InvalidArgumentException e) { 423 } catch (InvalidArgumentException e) {
@@ -452,6 +455,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -452,6 +455,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
452 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false); 455 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false);
453 logger.info(JSONObject.toJSONString(ssrcInfo)); 456 logger.info(JSONObject.toJSONString(ssrcInfo));
454 sendRtpItem.setStreamId(ssrcInfo.getStream()); 457 sendRtpItem.setStreamId(ssrcInfo.getStream());
  458 +
455 // 写入redis, 超时时回复 459 // 写入redis, 超时时回复
456 redisCatchStorage.updateSendRTPSever(sendRtpItem); 460 redisCatchStorage.updateSendRTPSever(sendRtpItem);
457 playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg) -> { 461 playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg) -> {
@@ -472,26 +476,26 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -472,26 +476,26 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
472 if("push".equals(gbStream.getStreamType())) { 476 if("push".equals(gbStream.getStreamType())) {
473 if (streamPushItem != null && streamPushItem.isPushIng()) { 477 if (streamPushItem != null && streamPushItem.isPushIng()) {
474 // 推流状态 478 // 推流状态
475 - pushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, 479 + pushStream(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
476 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); 480 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
477 } else { 481 } else {
478 // 未推流 拉起 482 // 未推流 拉起
479 - notifyStreamOnline(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, 483 + notifyStreamOnline(evt, serverTransaction,gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
480 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); 484 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
481 } 485 }
482 }else if ("proxy".equals(gbStream.getStreamType())){ 486 }else if ("proxy".equals(gbStream.getStreamType())){
483 if(null != proxyByAppAndStream &&proxyByAppAndStream.isStatus()){ 487 if(null != proxyByAppAndStream &&proxyByAppAndStream.isStatus()){
484 - pushProxyStream(evt, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive, 488 + pushProxyStream(evt, serverTransaction, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive,
485 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); 489 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
486 }else{ 490 }else{
487 //开启代理拉流 491 //开启代理拉流
488 boolean start1 = streamProxyService.start(gbStream.getApp(), gbStream.getStream()); 492 boolean start1 = streamProxyService.start(gbStream.getApp(), gbStream.getStream());
489 if(start1) { 493 if(start1) {
490 - pushProxyStream(evt, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive, 494 + pushProxyStream(evt, serverTransaction, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive,
491 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); 495 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
492 }else{ 496 }else{
493 //失败后通知 497 //失败后通知
494 - notifyStreamOnline(evt, gbStream, null, platform, callIdHeader, mediaServerItem, port, tcpActive, 498 + notifyStreamOnline(evt, serverTransaction,gbStream, null, platform, callIdHeader, mediaServerItem, port, tcpActive,
495 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); 499 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
496 } 500 }
497 } 501 }
@@ -514,7 +518,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -514,7 +518,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
514 /** 518 /**
515 * 安排推流 519 * 安排推流
516 */ 520 */
517 - private void pushProxyStream(RequestEvent evt, GbStream gbStream, ParentPlatform platform, 521 + private void pushProxyStream(RequestEvent evt, ServerTransaction serverTransaction, GbStream gbStream, ParentPlatform platform,
518 CallIdHeader callIdHeader, MediaServerItem mediaServerItem, 522 CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
519 int port, Boolean tcpActive, boolean mediaTransmissionTCP, 523 int port, Boolean tcpActive, boolean mediaTransmissionTCP,
520 String channelId, String addressStr, String ssrc, String requesterId) throws InvalidArgumentException, ParseException, SipException { 524 String channelId, String addressStr, String ssrc, String requesterId) throws InvalidArgumentException, ParseException, SipException {
@@ -527,7 +531,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -527,7 +531,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
527 531
528 if (sendRtpItem == null) { 532 if (sendRtpItem == null) {
529 logger.warn("服务器端口资源不足"); 533 logger.warn("服务器端口资源不足");
530 - responseAck(evt, Response.BUSY_HERE); 534 + responseAck(serverTransaction, Response.BUSY_HERE);
531 return; 535 return;
532 } 536 }
533 if (tcpActive != null) { 537 if (tcpActive != null) {
@@ -537,17 +541,19 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -537,17 +541,19 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
537 // 写入redis, 超时时回复 541 // 写入redis, 超时时回复
538 sendRtpItem.setStatus(1); 542 sendRtpItem.setStatus(1);
539 sendRtpItem.setCallId(callIdHeader.getCallId()); 543 sendRtpItem.setCallId(callIdHeader.getCallId());
540 - byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());  
541 - sendRtpItem.setDialog(dialogByteArray);  
542 - byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());  
543 - sendRtpItem.setTransaction(transactionByteArray); 544 + SIPRequest request = (SIPRequest) evt.getRequest();
  545 + sendRtpItem.setFromTag(request.getFromTag());
  546 +
  547 + SIPResponse response = sendStreamAck(mediaServerItem, serverTransaction, sendRtpItem, platform, evt);
  548 + if (response != null) {
  549 + sendRtpItem.setToTag(response.getToTag());
  550 + }
544 redisCatchStorage.updateSendRTPSever(sendRtpItem); 551 redisCatchStorage.updateSendRTPSever(sendRtpItem);
545 - sendStreamAck(mediaServerItem, sendRtpItem, platform, evt);  
546 552
547 } 553 }
548 554
549 } 555 }
550 - private void pushStream(RequestEvent evt, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform, 556 + private void pushStream(RequestEvent evt, ServerTransaction serverTransaction, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
551 CallIdHeader callIdHeader, MediaServerItem mediaServerItem, 557 CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
552 int port, Boolean tcpActive, boolean mediaTransmissionTCP, 558 int port, Boolean tcpActive, boolean mediaTransmissionTCP,
553 String channelId, String addressStr, String ssrc, String requesterId) throws InvalidArgumentException, ParseException, SipException { 559 String channelId, String addressStr, String ssrc, String requesterId) throws InvalidArgumentException, ParseException, SipException {
@@ -562,7 +568,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -562,7 +568,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
562 568
563 if (sendRtpItem == null) { 569 if (sendRtpItem == null) {
564 logger.warn("服务器端口资源不足"); 570 logger.warn("服务器端口资源不足");
565 - responseAck(evt, Response.BUSY_HERE); 571 + responseAck(serverTransaction, Response.BUSY_HERE);
566 return; 572 return;
567 } 573 }
568 if (tcpActive != null) { 574 if (tcpActive != null) {
@@ -572,39 +578,43 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -572,39 +578,43 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
572 // 写入redis, 超时时回复 578 // 写入redis, 超时时回复
573 sendRtpItem.setStatus(1); 579 sendRtpItem.setStatus(1);
574 sendRtpItem.setCallId(callIdHeader.getCallId()); 580 sendRtpItem.setCallId(callIdHeader.getCallId());
575 - byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());  
576 - sendRtpItem.setDialog(dialogByteArray);  
577 - byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());  
578 - sendRtpItem.setTransaction(transactionByteArray); 581 +
  582 + SIPRequest request = (SIPRequest) evt.getRequest();
  583 + sendRtpItem.setFromTag(request.getFromTag());
  584 + SIPResponse response = sendStreamAck(mediaServerItem, serverTransaction, sendRtpItem, platform, evt);
  585 + if (response != null) {
  586 + sendRtpItem.setToTag(response.getToTag());
  587 + }
  588 +
579 redisCatchStorage.updateSendRTPSever(sendRtpItem); 589 redisCatchStorage.updateSendRTPSever(sendRtpItem);
580 - sendStreamAck(mediaServerItem, sendRtpItem, platform, evt); 590 +
581 } else { 591 } else {
582 // 不在线 拉起 592 // 不在线 拉起
583 - notifyStreamOnline(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, 593 + notifyStreamOnline(evt, serverTransaction,gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
584 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); 594 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
585 } 595 }
586 596
587 } else { 597 } else {
588 // 其他平台内容 598 // 其他平台内容
589 - otherWvpPushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, 599 + otherWvpPushStream(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
590 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); 600 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
591 } 601 }
592 } 602 }
593 /** 603 /**
594 * 通知流上线 604 * 通知流上线
595 */ 605 */
596 - private void notifyStreamOnline(RequestEvent evt, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform, 606 + private void notifyStreamOnline(RequestEvent evt, ServerTransaction serverTransaction, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
597 CallIdHeader callIdHeader, MediaServerItem mediaServerItem, 607 CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
598 int port, Boolean tcpActive, boolean mediaTransmissionTCP, 608 int port, Boolean tcpActive, boolean mediaTransmissionTCP,
599 String channelId, String addressStr, String ssrc, String requesterId) throws InvalidArgumentException, ParseException, SipException { 609 String channelId, String addressStr, String ssrc, String requesterId) throws InvalidArgumentException, ParseException, SipException {
600 if ("proxy".equals(gbStream.getStreamType())) { 610 if ("proxy".equals(gbStream.getStreamType())) {
601 // TODO 控制启用以使设备上线 611 // TODO 控制启用以使设备上线
602 logger.info("[ app={}, stream={} ]通道未推流,启用流后开始推流", gbStream.getApp(), gbStream.getStream()); 612 logger.info("[ app={}, stream={} ]通道未推流,启用流后开始推流", gbStream.getApp(), gbStream.getStream());
603 - responseAck(evt, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline"); 613 + responseAck(serverTransaction, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline");
604 } else if ("push".equals(gbStream.getStreamType())) { 614 } else if ("push".equals(gbStream.getStreamType())) {
605 if (!platform.isStartOfflinePush()) { 615 if (!platform.isStartOfflinePush()) {
606 // 平台设置中关闭了拉起离线的推流则直接回复 616 // 平台设置中关闭了拉起离线的推流则直接回复
607 - responseAck(evt, Response.TEMPORARILY_UNAVAILABLE, "channel stream not pushing"); 617 + responseAck(serverTransaction, Response.TEMPORARILY_UNAVAILABLE, "channel stream not pushing");
608 return; 618 return;
609 } 619 }
610 // 发送redis消息以使设备上线 620 // 发送redis消息以使设备上线
@@ -619,7 +629,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -619,7 +629,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
619 logger.info("[ app={}, stream={} ] 等待设备开始推流超时", gbStream.getApp(), gbStream.getStream()); 629 logger.info("[ app={}, stream={} ] 等待设备开始推流超时", gbStream.getApp(), gbStream.getStream());
620 try { 630 try {
621 mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream()); 631 mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream());
622 - responseAck(evt, Response.REQUEST_TIMEOUT); // 超时 632 + responseAck(serverTransaction, Response.REQUEST_TIMEOUT); // 超时
623 } catch (SipException e) { 633 } catch (SipException e) {
624 e.printStackTrace(); 634 e.printStackTrace();
625 } catch (InvalidArgumentException e) { 635 } catch (InvalidArgumentException e) {
@@ -642,7 +652,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -642,7 +652,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
642 if (sendRtpItem == null) { 652 if (sendRtpItem == null) {
643 logger.warn("上级点时创建sendRTPItem失败,可能是服务器端口资源不足"); 653 logger.warn("上级点时创建sendRTPItem失败,可能是服务器端口资源不足");
644 try { 654 try {
645 - responseAck(evt, Response.BUSY_HERE); 655 + responseAck(serverTransaction, Response.BUSY_HERE);
646 } catch (SipException e) { 656 } catch (SipException e) {
647 e.printStackTrace(); 657 e.printStackTrace();
648 } catch (InvalidArgumentException e) { 658 } catch (InvalidArgumentException e) {
@@ -659,15 +669,17 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -659,15 +669,17 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
659 // 写入redis, 超时时回复 669 // 写入redis, 超时时回复
660 sendRtpItem.setStatus(1); 670 sendRtpItem.setStatus(1);
661 sendRtpItem.setCallId(callIdHeader.getCallId()); 671 sendRtpItem.setCallId(callIdHeader.getCallId());
662 - byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());  
663 - sendRtpItem.setDialog(dialogByteArray);  
664 - byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());  
665 - sendRtpItem.setTransaction(transactionByteArray); 672 +
  673 + SIPRequest request = (SIPRequest) evt.getRequest();
  674 + sendRtpItem.setFromTag(request.getFromTag());
  675 + SIPResponse response = sendStreamAck(mediaServerItem, serverTransaction, sendRtpItem, platform, evt);
  676 + if (response != null) {
  677 + sendRtpItem.setToTag(response.getToTag());
  678 + }
666 redisCatchStorage.updateSendRTPSever(sendRtpItem); 679 redisCatchStorage.updateSendRTPSever(sendRtpItem);
667 - sendStreamAck(mediaServerItem, sendRtpItem, platform, evt);  
668 } else { 680 } else {
669 // 其他平台内容 681 // 其他平台内容
670 - otherWvpPushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, 682 + otherWvpPushStream(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
671 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); 683 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
672 } 684 }
673 }); 685 });
@@ -678,7 +690,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -678,7 +690,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
678 dynamicTask.stop(callIdHeader.getCallId()); 690 dynamicTask.stop(callIdHeader.getCallId());
679 mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream()); 691 mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream());
680 try { 692 try {
681 - responseAck(evt, Response.TEMPORARILY_UNAVAILABLE, response.getMsg()); 693 + responseAck(serverTransaction, Response.TEMPORARILY_UNAVAILABLE, response.getMsg());
682 } catch (SipException e) { 694 } catch (SipException e) {
683 throw new RuntimeException(e); 695 throw new RuntimeException(e);
684 } catch (InvalidArgumentException e) { 696 } catch (InvalidArgumentException e) {
@@ -694,7 +706,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -694,7 +706,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
694 /** 706 /**
695 * 来自其他wvp的推流 707 * 来自其他wvp的推流
696 */ 708 */
697 - private void otherWvpPushStream(RequestEvent evt, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform, 709 + private void otherWvpPushStream(RequestEvent evt, ServerTransaction serverTransaction, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
698 CallIdHeader callIdHeader, MediaServerItem mediaServerItem, 710 CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
699 int port, Boolean tcpActive, boolean mediaTransmissionTCP, 711 int port, Boolean tcpActive, boolean mediaTransmissionTCP,
700 String channelId, String addressStr, String ssrc, String requesterId) { 712 String channelId, String addressStr, String ssrc, String requesterId) {
@@ -707,7 +719,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -707,7 +719,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
707 if (sendRtpItem == null || responseSendItemMsg.getMediaServerItem() == null) { 719 if (sendRtpItem == null || responseSendItemMsg.getMediaServerItem() == null) {
708 logger.warn("服务器端口资源不足"); 720 logger.warn("服务器端口资源不足");
709 try { 721 try {
710 - responseAck(evt, Response.BUSY_HERE); 722 + responseAck(serverTransaction, Response.BUSY_HERE);
711 } catch (SipException e) { 723 } catch (SipException e) {
712 e.printStackTrace(); 724 e.printStackTrace();
713 } catch (InvalidArgumentException e) { 725 } catch (InvalidArgumentException e) {
@@ -725,12 +737,14 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -725,12 +737,14 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
725 // 写入redis, 超时时回复 737 // 写入redis, 超时时回复
726 sendRtpItem.setStatus(1); 738 sendRtpItem.setStatus(1);
727 sendRtpItem.setCallId(callIdHeader.getCallId()); 739 sendRtpItem.setCallId(callIdHeader.getCallId());
728 - byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());  
729 - sendRtpItem.setDialog(dialogByteArray);  
730 - byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());  
731 - sendRtpItem.setTransaction(transactionByteArray); 740 +
  741 + SIPRequest request = (SIPRequest) evt.getRequest();
  742 + sendRtpItem.setFromTag(request.getFromTag());
  743 + SIPResponse response = sendStreamAck(responseSendItemMsg.getMediaServerItem(), serverTransaction,sendRtpItem, platform, evt);
  744 + if (response != null) {
  745 + sendRtpItem.setToTag(response.getToTag());
  746 + }
732 redisCatchStorage.updateSendRTPSever(sendRtpItem); 747 redisCatchStorage.updateSendRTPSever(sendRtpItem);
733 - sendStreamAck(responseSendItemMsg.getMediaServerItem(), sendRtpItem, platform, evt);  
734 }, (wvpResult) -> { 748 }, (wvpResult) -> {
735 try { 749 try {
736 // 错误 750 // 错误
@@ -740,12 +754,12 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -740,12 +754,12 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
740 StreamPushItem currentStreamPushItem = streamPushService.getPush(streamPushItem.getApp(), streamPushItem.getStream()); 754 StreamPushItem currentStreamPushItem = streamPushService.getPush(streamPushItem.getApp(), streamPushItem.getStream());
741 if (currentStreamPushItem.isPushIng()) { 755 if (currentStreamPushItem.isPushIng()) {
742 // 在线状态 756 // 在线状态
743 - pushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, 757 + pushStream(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
744 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); 758 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
745 759
746 } else { 760 } else {
747 // 不在线 拉起 761 // 不在线 拉起
748 - notifyStreamOnline(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, 762 + notifyStreamOnline(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
749 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); 763 mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
750 } 764 }
751 } 765 }
@@ -759,7 +773,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -759,7 +773,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
759 773
760 774
761 try { 775 try {
762 - responseAck(evt, Response.BUSY_HERE); 776 + responseAck(serverTransaction, Response.BUSY_HERE);
763 } catch (SipException e) { 777 } catch (SipException e) {
764 e.printStackTrace(); 778 e.printStackTrace();
765 } catch (InvalidArgumentException e) { 779 } catch (InvalidArgumentException e) {
@@ -771,7 +785,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -771,7 +785,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
771 }); 785 });
772 } 786 }
773 787
774 - public void sendStreamAck(MediaServerItem mediaServerItem, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt) { 788 + public SIPResponse sendStreamAck(MediaServerItem mediaServerItem, ServerTransaction serverTransaction, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt) {
775 789
776 StringBuffer content = new StringBuffer(200); 790 StringBuffer content = new StringBuffer(200);
777 content.append("v=0\r\n"); 791 content.append("v=0\r\n");
@@ -794,7 +808,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -794,7 +808,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
794 content.append("f=\r\n"); 808 content.append("f=\r\n");
795 809
796 try { 810 try {
797 - responseSdpAck(evt, content.toString(), platform); 811 + return responseSdpAck(serverTransaction, content.toString(), platform);
798 } catch (SipException e) { 812 } catch (SipException e) {
799 e.printStackTrace(); 813 e.printStackTrace();
800 } catch (InvalidArgumentException e) { 814 } catch (InvalidArgumentException e) {
@@ -802,24 +816,25 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -802,24 +816,25 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
802 } catch (ParseException e) { 816 } catch (ParseException e) {
803 e.printStackTrace(); 817 e.printStackTrace();
804 } 818 }
  819 + return null;
805 } 820 }
806 821
807 - public void inviteFromDeviceHandle(RequestEvent evt, String requesterId, String channelId) throws InvalidArgumentException, ParseException, SipException, SdpException { 822 + public void inviteFromDeviceHandle(ServerTransaction serverTransaction, String requesterId, String channelId) throws InvalidArgumentException, ParseException, SipException, SdpException {
808 823
809 // 非上级平台请求,查询是否设备请求(通常为接收语音广播的设备) 824 // 非上级平台请求,查询是否设备请求(通常为接收语音广播的设备)
810 Device device = redisCatchStorage.getDevice(requesterId); 825 Device device = redisCatchStorage.getDevice(requesterId);
811 AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(requesterId, channelId); 826 AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(requesterId, channelId);
812 if (audioBroadcastCatch == null) { 827 if (audioBroadcastCatch == null) {
813 logger.warn("来自设备的Invite请求非语音广播,已忽略,requesterId: {}/{}", requesterId, channelId); 828 logger.warn("来自设备的Invite请求非语音广播,已忽略,requesterId: {}/{}", requesterId, channelId);
814 - responseAck(evt, Response.FORBIDDEN); 829 + responseAck(serverTransaction, Response.FORBIDDEN);
815 return; 830 return;
816 } 831 }
817 - Request request = evt.getRequest(); 832 + Request request = serverTransaction.getRequest();
818 if (device != null) { 833 if (device != null) {
819 logger.info("收到设备" + requesterId + "的语音广播Invite请求"); 834 logger.info("收到设备" + requesterId + "的语音广播Invite请求");
820 - responseAck(evt, Response.TRYING); 835 + responseAck(serverTransaction, Response.TRYING);
821 836
822 - String contentString = new String(request.getRawContent()); 837 + String contentString = new String(serverTransaction.getRequest().getRawContent());
823 // jainSip不支持y=字段, 移除移除以解析。 838 // jainSip不支持y=字段, 移除移除以解析。
824 String substring = contentString; 839 String substring = contentString;
825 String ssrc = "0000000404"; 840 String ssrc = "0000000404";
@@ -867,7 +882,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -867,7 +882,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
867 if (port == -1) { 882 if (port == -1) {
868 logger.info("不支持的媒体格式,返回415"); 883 logger.info("不支持的媒体格式,返回415");
869 // 回复不支持的格式 884 // 回复不支持的格式
870 - responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415 885 + responseAck(serverTransaction, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415
871 return; 886 return;
872 } 887 }
873 String addressStr = sdp.getOrigin().getAddress(); 888 String addressStr = sdp.getOrigin().getAddress();
@@ -876,7 +891,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -876,7 +891,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
876 MediaServerItem mediaServerItem = playService.getNewMediaServerItem(device); 891 MediaServerItem mediaServerItem = playService.getNewMediaServerItem(device);
877 if (mediaServerItem == null) { 892 if (mediaServerItem == null) {
878 logger.warn("未找到可用的zlm"); 893 logger.warn("未找到可用的zlm");
879 - responseAck(evt, Response.BUSY_HERE); 894 + responseAck(serverTransaction, Response.BUSY_HERE);
880 return; 895 return;
881 } 896 }
882 SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, 897 SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
@@ -884,7 +899,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -884,7 +899,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
884 mediaTransmissionTCP); 899 mediaTransmissionTCP);
885 if (sendRtpItem == null) { 900 if (sendRtpItem == null) {
886 logger.warn("服务器端口资源不足"); 901 logger.warn("服务器端口资源不足");
887 - responseAck(evt, Response.BUSY_HERE); 902 + responseAck(serverTransaction, Response.BUSY_HERE);
888 return; 903 return;
889 } 904 }
890 sendRtpItem.setTcp(mediaTransmissionTCP); 905 sendRtpItem.setTcp(mediaTransmissionTCP);
@@ -998,19 +1013,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -998,19 +1013,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
998 parentPlatform.setServerPort(device.getPort()); 1013 parentPlatform.setServerPort(device.getPort());
999 parentPlatform.setServerGBId(device.getDeviceId()); 1014 parentPlatform.setServerGBId(device.getDeviceId());
1000 1015
1001 - responseSdpAck(evt, content.toString(), parentPlatform); 1016 + responseSdpAck(serverTransaction, content.toString(), parentPlatform);
1002 Dialog dialog = evt.getDialog(); 1017 Dialog dialog = evt.getDialog();
1003 audioBroadcastCatch.setDialog((SIPDialog) dialog); 1018 audioBroadcastCatch.setDialog((SIPDialog) dialog);
1004 audioBroadcastCatch.setRequest((SIPRequest) request); 1019 audioBroadcastCatch.setRequest((SIPRequest) request);
1005 audioBroadcastManager.update(audioBroadcastCatch); 1020 audioBroadcastManager.update(audioBroadcastCatch);
1006 - } catch (SipException e) {  
1007 - throw new RuntimeException(e);  
1008 - } catch (InvalidArgumentException e) {  
1009 - throw new RuntimeException(e);  
1010 - } catch (ParseException e) {  
1011 - throw new RuntimeException(e);  
1012 - } catch (SdpParseException e) {  
1013 - throw new RuntimeException(e); 1021 + } catch (SipException | InvalidArgumentException | ParseException | SdpParseException e) {
  1022 + logger.error("[命令发送失败] 语音对讲: {}", e.getMessage());
1014 } 1023 }
1015 }); 1024 });
1016 // } 1025 // }
@@ -1030,7 +1039,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -1030,7 +1039,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
1030 resultHolder.invokeAllResult(requestMessage); 1039 resultHolder.invokeAllResult(requestMessage);
1031 } else { 1040 } else {
1032 logger.warn("来自无效设备/平台的请求"); 1041 logger.warn("来自无效设备/平台的请求");
1033 - responseAck(evt, Response.BAD_REQUEST); 1042 + responseAck(serverTransaction, Response.BAD_REQUEST);
1034 } 1043 }
1035 } 1044 }
1036 } 1045 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java
@@ -34,6 +34,7 @@ import org.springframework.util.StringUtils; @@ -34,6 +34,7 @@ import org.springframework.util.StringUtils;
34 34
35 import javax.sip.InvalidArgumentException; 35 import javax.sip.InvalidArgumentException;
36 import javax.sip.RequestEvent; 36 import javax.sip.RequestEvent;
  37 +import javax.sip.ServerTransaction;
37 import javax.sip.SipException; 38 import javax.sip.SipException;
38 import javax.sip.header.FromHeader; 39 import javax.sip.header.FromHeader;
39 import javax.sip.message.Response; 40 import javax.sip.message.Response;
@@ -78,7 +79,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -78,7 +79,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
78 79
79 private boolean taskQueueHandlerRun = false; 80 private boolean taskQueueHandlerRun = false;
80 81
81 - private final ConcurrentLinkedQueue<HandlerCatchData> taskQueue = new ConcurrentLinkedQueue<>(); 82 + private ConcurrentLinkedQueue<HandlerCatchData> taskQueue = new ConcurrentLinkedQueue<>();
82 83
83 @Qualifier("taskExecutor") 84 @Qualifier("taskExecutor")
84 @Autowired 85 @Autowired
@@ -94,7 +95,8 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -94,7 +95,8 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
94 public void process(RequestEvent evt) { 95 public void process(RequestEvent evt) {
95 try { 96 try {
96 taskQueue.offer(new HandlerCatchData(evt, null, null)); 97 taskQueue.offer(new HandlerCatchData(evt, null, null));
97 - responseAck(evt, Response.OK); 98 + ServerTransaction serverTransaction = getServerTransaction(evt);
  99 + responseAck(serverTransaction, Response.OK);
98 if (!taskQueueHandlerRun) { 100 if (!taskQueueHandlerRun) {
99 taskQueueHandlerRun = true; 101 taskQueueHandlerRun = true;
100 taskExecutor.execute(()-> { 102 taskExecutor.execute(()-> {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java
@@ -17,6 +17,12 @@ import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; @@ -17,6 +17,12 @@ import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
17 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 17 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
18 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 18 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
19 import gov.nist.javax.sip.SipProviderImpl; 19 import gov.nist.javax.sip.SipProviderImpl;
  20 +import gov.nist.javax.sip.message.SIPRequest;
  21 +import gov.nist.javax.sip.message.SIPResponse;
  22 +import gov.nist.javax.sip.stack.SIPClientTransaction;
  23 +import gov.nist.javax.sip.stack.SIPDialog;
  24 +import gov.nist.javax.sip.stack.SIPServerTransaction;
  25 +import gov.nist.javax.sip.stack.SIPServerTransactionImpl;
20 import org.dom4j.DocumentException; 26 import org.dom4j.DocumentException;
21 import org.dom4j.Element; 27 import org.dom4j.Element;
22 import org.slf4j.Logger; 28 import org.slf4j.Logger;
@@ -49,22 +55,6 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme @@ -49,22 +55,6 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
49 @Autowired 55 @Autowired
50 private IVideoManagerStorage storager; 56 private IVideoManagerStorage storager;
51 57
52 - @Lazy  
53 - @Autowired  
54 - @Qualifier(value="tcpSipProvider")  
55 - private SipProviderImpl tcpSipProvider;  
56 -  
57 - @Lazy  
58 - @Autowired  
59 - @Qualifier(value="udpSipProvider")  
60 - private SipProviderImpl udpSipProvider;  
61 -  
62 - @Autowired  
63 - private DynamicTask dynamicTask;  
64 -  
65 - @Autowired  
66 - private UserSetting userSetting;  
67 -  
68 @Autowired 58 @Autowired
69 private SubscribeHolder subscribeHolder; 59 private SubscribeHolder subscribeHolder;
70 60
@@ -81,6 +71,7 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme @@ -81,6 +71,7 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
81 */ 71 */
82 @Override 72 @Override
83 public void process(RequestEvent evt) { 73 public void process(RequestEvent evt) {
  74 + ServerTransaction serverTransaction = getServerTransaction(evt);
84 Request request = evt.getRequest(); 75 Request request = evt.getRequest();
85 try { 76 try {
86 Element rootElement = getRootElement(evt); 77 Element rootElement = getRootElement(evt);
@@ -90,12 +81,12 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme @@ -90,12 +81,12 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
90 } 81 }
91 String cmd = XmlUtil.getText(rootElement, "CmdType"); 82 String cmd = XmlUtil.getText(rootElement, "CmdType");
92 if (CmdType.MOBILE_POSITION.equals(cmd)) { 83 if (CmdType.MOBILE_POSITION.equals(cmd)) {
93 - processNotifyMobilePosition(evt, rootElement); 84 + processNotifyMobilePosition(serverTransaction, rootElement);
94 // } else if (CmdType.ALARM.equals(cmd)) { 85 // } else if (CmdType.ALARM.equals(cmd)) {
95 // logger.info("接收到Alarm订阅"); 86 // logger.info("接收到Alarm订阅");
96 -// processNotifyAlarm(evt, rootElement); 87 +// processNotifyAlarm(serverTransaction, rootElement);
97 } else if (CmdType.CATALOG.equals(cmd)) { 88 } else if (CmdType.CATALOG.equals(cmd)) {
98 - processNotifyCatalogList(evt, rootElement); 89 + processNotifyCatalogList(serverTransaction, rootElement);
99 } else { 90 } else {
100 logger.info("接收到消息:" + cmd); 91 logger.info("接收到消息:" + cmd);
101 92
@@ -108,7 +99,6 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme @@ -108,7 +99,6 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
108 ServerTransaction transaction = getServerTransaction(evt); 99 ServerTransaction transaction = getServerTransaction(evt);
109 if (transaction != null) { 100 if (transaction != null) {
110 transaction.sendResponse(response); 101 transaction.sendResponse(response);
111 - transaction.getDialog().delete();  
112 transaction.terminate(); 102 transaction.terminate();
113 } else { 103 } else {
114 logger.info("processRequest serverTransactionId is null."); 104 logger.info("processRequest serverTransactionId is null.");
@@ -123,24 +113,20 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme @@ -123,24 +113,20 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
123 /** 113 /**
124 * 处理移动位置订阅消息 114 * 处理移动位置订阅消息
125 */ 115 */
126 - private void processNotifyMobilePosition(RequestEvent evt, Element rootElement) throws SipException {  
127 - String platformId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); 116 + private void processNotifyMobilePosition(ServerTransaction serverTransaction, Element rootElement) throws SipException {
  117 + if (serverTransaction == null) {
  118 + return;
  119 + }
  120 + String platformId = SipUtils.getUserIdFromFromHeader(serverTransaction.getRequest());
128 String deviceId = XmlUtil.getText(rootElement, "DeviceID"); 121 String deviceId = XmlUtil.getText(rootElement, "DeviceID");
129 ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId); 122 ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);
130 - SubscribeInfo subscribeInfo = new SubscribeInfo(evt, platformId); 123 + SubscribeInfo subscribeInfo = new SubscribeInfo(serverTransaction, platformId);
131 if (platform == null) { 124 if (platform == null) {
132 return; 125 return;
133 } 126 }
134 - if (evt.getServerTransaction() == null) {  
135 - ServerTransaction serverTransaction = "TCP".equalsIgnoreCase(platform.getTransport()) ? tcpSipProvider.getNewServerTransaction(evt.getRequest())  
136 - : udpSipProvider.getNewServerTransaction(evt.getRequest());  
137 - subscribeInfo.setTransaction(serverTransaction);  
138 - Dialog dialog = serverTransaction.getDialog();  
139 - dialog.terminateOnBye(false);  
140 - subscribeInfo.setDialog(dialog);  
141 - } 127 +
142 String sn = XmlUtil.getText(rootElement, "SN"); 128 String sn = XmlUtil.getText(rootElement, "SN");
143 - logger.info("[回复 移动位置订阅]: {}", platformId); 129 + logger.info("[回复上级的移动位置订阅请求]: {}", platformId);
144 StringBuilder resultXml = new StringBuilder(200); 130 StringBuilder resultXml = new StringBuilder(200);
145 resultXml.append("<?xml version=\"1.0\" ?>\r\n") 131 resultXml.append("<?xml version=\"1.0\" ?>\r\n")
146 .append("<Response>\r\n") 132 .append("<Response>\r\n")
@@ -158,17 +144,19 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme @@ -158,17 +144,19 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
158 }else { 144 }else {
159 subscribeInfo.setGpsInterval(Integer.parseInt(interval)); 145 subscribeInfo.setGpsInterval(Integer.parseInt(interval));
160 } 146 }
161 -  
162 subscribeInfo.setSn(sn); 147 subscribeInfo.setSn(sn);
163 - subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo);  
164 -  
165 - }else if (subscribeInfo.getExpires() == 0) {  
166 - subscribeHolder.removeMobilePositionSubscribe(platformId);  
167 } 148 }
168 149
169 try { 150 try {
170 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId); 151 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId);
171 - responseXmlAck(evt, resultXml.toString(), parentPlatform); 152 + SIPResponse response = responseXmlAck(serverTransaction, resultXml.toString(), parentPlatform, subscribeInfo.getExpires());
  153 + if (subscribeInfo.getExpires() == 0) {
  154 + subscribeHolder.removeMobilePositionSubscribe(platformId);
  155 + }else {
  156 + subscribeInfo.setResponse(response);
  157 + subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo);
  158 + }
  159 +
172 } catch (SipException | InvalidArgumentException | ParseException e) { 160 } catch (SipException | InvalidArgumentException | ParseException e) {
173 e.printStackTrace(); 161 e.printStackTrace();
174 } 162 }
@@ -178,25 +166,20 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme @@ -178,25 +166,20 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
178 166
179 } 167 }
180 168
181 - private void processNotifyCatalogList(RequestEvent evt, Element rootElement) throws SipException {  
182 -  
183 - String platformId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); 169 + private void processNotifyCatalogList(ServerTransaction serverTransaction, Element rootElement) throws SipException {
  170 + if (serverTransaction == null) {
  171 + return;
  172 + }
  173 + String platformId = SipUtils.getUserIdFromFromHeader(serverTransaction.getRequest());
184 String deviceId = XmlUtil.getText(rootElement, "DeviceID"); 174 String deviceId = XmlUtil.getText(rootElement, "DeviceID");
185 ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId); 175 ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);
186 if (platform == null){ 176 if (platform == null){
187 return; 177 return;
188 } 178 }
189 - SubscribeInfo subscribeInfo = new SubscribeInfo(evt, platformId);  
190 - if (evt.getServerTransaction() == null) {  
191 - ServerTransaction serverTransaction = "TCP".equalsIgnoreCase(platform.getTransport()) ? tcpSipProvider.getNewServerTransaction(evt.getRequest())  
192 - : udpSipProvider.getNewServerTransaction(evt.getRequest());  
193 - subscribeInfo.setTransaction(serverTransaction);  
194 - Dialog dialog = serverTransaction.getDialog();  
195 - dialog.terminateOnBye(false);  
196 - subscribeInfo.setDialog(dialog);  
197 - } 179 + SubscribeInfo subscribeInfo = new SubscribeInfo(serverTransaction, platformId);
  180 +
198 String sn = XmlUtil.getText(rootElement, "SN"); 181 String sn = XmlUtil.getText(rootElement, "SN");
199 - logger.info("[回复 目录订阅]: {}/{}", platformId, deviceId); 182 + logger.info("[回复上级的目录订阅请求]: {}/{}", platformId, deviceId);
200 StringBuilder resultXml = new StringBuilder(200); 183 StringBuilder resultXml = new StringBuilder(200);
201 resultXml.append("<?xml version=\"1.0\" ?>\r\n") 184 resultXml.append("<?xml version=\"1.0\" ?>\r\n")
202 .append("<Response>\r\n") 185 .append("<Response>\r\n")
@@ -213,7 +196,13 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme @@ -213,7 +196,13 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
213 } 196 }
214 try { 197 try {
215 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId); 198 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId);
216 - responseXmlAck(evt, resultXml.toString(), parentPlatform); 199 + SIPResponse response = responseXmlAck(serverTransaction, resultXml.toString(), parentPlatform, subscribeInfo.getExpires());
  200 + if (subscribeInfo.getExpires() == 0) {
  201 + subscribeHolder.removeCatalogSubscribe(platformId);
  202 + }else {
  203 + subscribeInfo.setResponse(response);
  204 + subscribeHolder.putCatalogSubscribe(platformId, subscribeInfo);
  205 + }
217 } catch (SipException | InvalidArgumentException | ParseException e) { 206 } catch (SipException | InvalidArgumentException | ParseException e) {
218 e.printStackTrace(); 207 e.printStackTrace();
219 } 208 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/info/InfoRequestProcessor.java
@@ -19,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired; @@ -19,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
19 import org.springframework.stereotype.Component; 19 import org.springframework.stereotype.Component;
20 import javax.sip.InvalidArgumentException; 20 import javax.sip.InvalidArgumentException;
21 import javax.sip.RequestEvent; 21 import javax.sip.RequestEvent;
  22 +import javax.sip.ServerTransaction;
22 import javax.sip.SipException; 23 import javax.sip.SipException;
23 import javax.sip.header.*; 24 import javax.sip.header.*;
24 import javax.sip.message.Response; 25 import javax.sip.message.Response;
@@ -65,9 +66,12 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I @@ -65,9 +66,12 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I
65 CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME); 66 CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
66 // 先从会话内查找 67 // 先从会话内查找
67 SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransaction(null, null, callIdHeader.getCallId(), null); 68 SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransaction(null, null, callIdHeader.getCallId(), null);
68 - if (ssrcTransaction != null) { // 兼容海康 媒体通知 消息from字段不是设备ID的问题 69 +
  70 + // 兼容海康 媒体通知 消息from字段不是设备ID的问题
  71 + if (ssrcTransaction != null) {
69 deviceId = ssrcTransaction.getDeviceId(); 72 deviceId = ssrcTransaction.getDeviceId();
70 } 73 }
  74 + ServerTransaction serverTransaction = getServerTransaction(evt);
71 // 查询设备是否存在 75 // 查询设备是否存在
72 Device device = redisCatchStorage.getDevice(deviceId); 76 Device device = redisCatchStorage.getDevice(deviceId);
73 // 查询上级平台是否存在 77 // 查询上级平台是否存在
@@ -86,7 +90,7 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I @@ -86,7 +90,7 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I
86 } 90 }
87 if (device == null && parentPlatform == null) { 91 if (device == null && parentPlatform == null) {
88 // 不存在则回复404 92 // 不存在则回复404
89 - responseAck(evt, Response.NOT_FOUND, "device "+ deviceId +" not found"); 93 + responseAck(serverTransaction, Response.NOT_FOUND, "device "+ deviceId +" not found");
90 logger.warn("[设备未找到 ]: {}", deviceId); 94 logger.warn("[设备未找到 ]: {}", deviceId);
91 if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){ 95 if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){
92 SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new DeviceNotFoundEvent(evt.getDialog())); 96 SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new DeviceNotFoundEvent(evt.getDialog()));
@@ -101,14 +105,14 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I @@ -101,14 +105,14 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I
101 String streamId = sendRtpItem.getStreamId(); 105 String streamId = sendRtpItem.getStreamId();
102 StreamInfo streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null); 106 StreamInfo streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null);
103 if (null == streamInfo) { 107 if (null == streamInfo) {
104 - responseAck(evt, Response.NOT_FOUND, "stream " + streamId + " not found"); 108 + responseAck(serverTransaction, Response.NOT_FOUND, "stream " + streamId + " not found");
105 return; 109 return;
106 } 110 }
107 Device device1 = storager.queryVideoDevice(streamInfo.getDeviceID()); 111 Device device1 = storager.queryVideoDevice(streamInfo.getDeviceID());
108 cmder.playbackControlCmd(device1,streamInfo,new String(evt.getRequest().getRawContent()),eventResult -> { 112 cmder.playbackControlCmd(device1,streamInfo,new String(evt.getRequest().getRawContent()),eventResult -> {
109 // 失败的回复 113 // 失败的回复
110 try { 114 try {
111 - responseAck(evt, eventResult.statusCode, eventResult.msg); 115 + responseAck(serverTransaction, eventResult.statusCode, eventResult.msg);
112 } catch (SipException e) { 116 } catch (SipException e) {
113 e.printStackTrace(); 117 e.printStackTrace();
114 } catch (InvalidArgumentException e) { 118 } catch (InvalidArgumentException e) {
@@ -119,7 +123,7 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I @@ -119,7 +123,7 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I
119 }, eventResult -> { 123 }, eventResult -> {
120 // 成功的回复 124 // 成功的回复
121 try { 125 try {
122 - responseAck(evt, eventResult.statusCode); 126 + responseAck(serverTransaction, eventResult.statusCode);
123 } catch (SipException e) { 127 } catch (SipException e) {
124 e.printStackTrace(); 128 e.printStackTrace();
125 } catch (InvalidArgumentException e) { 129 } catch (InvalidArgumentException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java
@@ -23,6 +23,7 @@ import org.springframework.stereotype.Component; @@ -23,6 +23,7 @@ import org.springframework.stereotype.Component;
23 23
24 import javax.sip.InvalidArgumentException; 24 import javax.sip.InvalidArgumentException;
25 import javax.sip.RequestEvent; 25 import javax.sip.RequestEvent;
  26 +import javax.sip.ServerTransaction;
26 import javax.sip.SipException; 27 import javax.sip.SipException;
27 import javax.sip.address.SipURI; 28 import javax.sip.address.SipURI;
28 import javax.sip.header.CSeqHeader; 29 import javax.sip.header.CSeqHeader;
@@ -79,6 +80,9 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement @@ -79,6 +80,9 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
79 if (ssrcTransaction != null) { 80 if (ssrcTransaction != null) {
80 deviceId = ssrcTransaction.getDeviceId(); 81 deviceId = ssrcTransaction.getDeviceId();
81 } 82 }
  83 +
  84 + ServerTransaction serverTransaction = getServerTransaction(evt);
  85 +
82 // 查询设备是否存在 86 // 查询设备是否存在
83 Device device = redisCatchStorage.getDevice(deviceId); 87 Device device = redisCatchStorage.getDevice(deviceId);
84 // 查询上级平台是否存在 88 // 查询上级平台是否存在
@@ -98,7 +102,7 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement @@ -98,7 +102,7 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
98 } 102 }
99 if (device == null && parentPlatform == null) { 103 if (device == null && parentPlatform == null) {
100 // 不存在则回复404 104 // 不存在则回复404
101 - responseAck(evt, Response.NOT_FOUND, "device "+ deviceId +" not found"); 105 + responseAck(serverTransaction, Response.NOT_FOUND, "device "+ deviceId +" not found");
102 logger.warn("[设备未找到 ]: {}", deviceId); 106 logger.warn("[设备未找到 ]: {}", deviceId);
103 if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){ 107 if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){
104 SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new DeviceNotFoundEvent(evt.getDialog())); 108 SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new DeviceNotFoundEvent(evt.getDialog()));
@@ -110,13 +114,13 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement @@ -110,13 +114,13 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
110 rootElement = getRootElement(evt); 114 rootElement = getRootElement(evt);
111 if (rootElement == null) { 115 if (rootElement == null) {
112 logger.error("处理MESSAGE请求 未获取到消息体{}", evt.getRequest()); 116 logger.error("处理MESSAGE请求 未获取到消息体{}", evt.getRequest());
113 - responseAck(evt, Response.BAD_REQUEST, "content is null"); 117 + responseAck(serverTransaction, Response.BAD_REQUEST, "content is null");
114 return; 118 return;
115 } 119 }
116 } catch (DocumentException e) { 120 } catch (DocumentException e) {
117 logger.warn("解析XML消息内容异常", e); 121 logger.warn("解析XML消息内容异常", e);
118 // 不存在则回复404 122 // 不存在则回复404
119 - responseAck(evt, Response.BAD_REQUEST, e.getMessage()); 123 + responseAck(serverTransaction, Response.BAD_REQUEST, e.getMessage());
120 } 124 }
121 String name = rootElement.getName(); 125 String name = rootElement.getName();
122 IMessageHandler messageHandler = messageHandlerMap.get(name); 126 IMessageHandler messageHandler = messageHandlerMap.get(name);
@@ -129,7 +133,7 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement @@ -129,7 +133,7 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
129 }else { 133 }else {
130 // 不支持的message 134 // 不支持的message
131 // 不存在则回复415 135 // 不存在则回复415
132 - responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE, "Unsupported message type, must Control/Notify/Query/Response"); 136 + responseAck(serverTransaction, Response.UNSUPPORTED_MEDIA_TYPE, "Unsupported message type, must Control/Notify/Query/Response");
133 } 137 }
134 } 138 }
135 } catch (SipException e) { 139 } catch (SipException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/control/cmd/DeviceControlQueryMessageHandler.java
@@ -61,6 +61,8 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent @@ -61,6 +61,8 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
61 @Override 61 @Override
62 public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) { 62 public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
63 63
  64 + ServerTransaction serverTransaction = getServerTransaction(evt);
  65 +
64 // 此处是上级发出的DeviceControl指令 66 // 此处是上级发出的DeviceControl指令
65 String targetGBId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); 67 String targetGBId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
66 String channelId = getText(rootElement, "DeviceID"); 68 String channelId = getText(rootElement, "DeviceID");
@@ -107,7 +109,7 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent @@ -107,7 +109,7 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
107 Device deviceForPlatform = storager.queryVideoDeviceByPlatformIdAndChannelId(parentPlatform.getServerGBId(), channelId); 109 Device deviceForPlatform = storager.queryVideoDeviceByPlatformIdAndChannelId(parentPlatform.getServerGBId(), channelId);
108 if (deviceForPlatform == null) { 110 if (deviceForPlatform == null) {
109 try { 111 try {
110 - responseAck(evt, Response.NOT_FOUND); 112 + responseAck(serverTransaction, Response.NOT_FOUND);
111 return; 113 return;
112 } catch (SipException e) { 114 } catch (SipException e) {
113 e.printStackTrace(); 115 e.printStackTrace();
@@ -120,7 +122,7 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent @@ -120,7 +122,7 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
120 cmder.fronEndCmd(deviceForPlatform, channelId, cmdString, eventResult -> { 122 cmder.fronEndCmd(deviceForPlatform, channelId, cmdString, eventResult -> {
121 // 失败的回复 123 // 失败的回复
122 try { 124 try {
123 - responseAck(evt, eventResult.statusCode, eventResult.msg); 125 + responseAck(serverTransaction, eventResult.statusCode, eventResult.msg);
124 } catch (SipException e) { 126 } catch (SipException e) {
125 e.printStackTrace(); 127 e.printStackTrace();
126 } catch (InvalidArgumentException e) { 128 } catch (InvalidArgumentException e) {
@@ -131,7 +133,7 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent @@ -131,7 +133,7 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
131 }, eventResult -> { 133 }, eventResult -> {
132 // 成功的回复 134 // 成功的回复
133 try { 135 try {
134 - responseAck(evt, eventResult.statusCode); 136 + responseAck(serverTransaction, eventResult.statusCode);
135 } catch (SipException e) { 137 } catch (SipException e) {
136 e.printStackTrace(); 138 e.printStackTrace();
137 } catch (InvalidArgumentException e) { 139 } catch (InvalidArgumentException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java
@@ -21,6 +21,8 @@ import org.slf4j.Logger; @@ -21,6 +21,8 @@ import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory; 21 import org.slf4j.LoggerFactory;
22 import org.springframework.beans.factory.InitializingBean; 22 import org.springframework.beans.factory.InitializingBean;
23 import org.springframework.beans.factory.annotation.Autowired; 23 import org.springframework.beans.factory.annotation.Autowired;
  24 +import org.springframework.beans.factory.annotation.Qualifier;
  25 +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
24 import org.springframework.stereotype.Component; 26 import org.springframework.stereotype.Component;
25 import org.springframework.util.ObjectUtils; 27 import org.springframework.util.ObjectUtils;
26 import org.springframework.util.StringUtils; 28 import org.springframework.util.StringUtils;
@@ -31,6 +33,7 @@ import javax.sip.SipException; @@ -31,6 +33,7 @@ import javax.sip.SipException;
31 import javax.sip.message.Response; 33 import javax.sip.message.Response;
32 34
33 import java.text.ParseException; 35 import java.text.ParseException;
  36 +import java.util.concurrent.ConcurrentLinkedQueue;
34 37
35 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.*; 38 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.*;
36 39
@@ -67,6 +70,15 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme @@ -67,6 +70,15 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
67 @Autowired 70 @Autowired
68 private IDeviceChannelService deviceChannelService; 71 private IDeviceChannelService deviceChannelService;
69 72
  73 + private boolean taskQueueHandlerRun = false;
  74 +
  75 + private ConcurrentLinkedQueue<SipMsgInfo> taskQueue = new ConcurrentLinkedQueue<>();
  76 +
  77 + @Qualifier("taskExecutor")
  78 + @Autowired
  79 + private ThreadPoolTaskExecutor taskExecutor;
  80 +
  81 +
70 @Override 82 @Override
71 public void afterPropertiesSet() throws Exception { 83 public void afterPropertiesSet() throws Exception {
72 notifyMessageHandler.addHandler(cmdType, this); 84 notifyMessageHandler.addHandler(cmdType, this);
@@ -75,114 +87,128 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme @@ -75,114 +87,128 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
75 @Override 87 @Override
76 public void handForDevice(RequestEvent evt, Device device, Element rootElement) { 88 public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
77 logger.info("[收到报警通知]设备:{}", device.getDeviceId()); 89 logger.info("[收到报警通知]设备:{}", device.getDeviceId());
78 - // 回复200 OK  
79 - try {  
80 - responseAck(evt, Response.OK);  
81 - } catch (SipException | InvalidArgumentException | ParseException e) {  
82 - logger.error("[收到报警通知], 回复200OK失败", e);  
83 - }  
84 90
85 - Element deviceIdElement = rootElement.element("DeviceID");  
86 - String channelId = deviceIdElement.getText().toString();  
87 -  
88 - DeviceAlarm deviceAlarm = new DeviceAlarm();  
89 - deviceAlarm.setCreateTime(DateUtil.getNow());  
90 - deviceAlarm.setDeviceId(device.getDeviceId());  
91 - deviceAlarm.setChannelId(channelId);  
92 - deviceAlarm.setAlarmPriority(getText(rootElement, "AlarmPriority"));  
93 - deviceAlarm.setAlarmMethod(getText(rootElement, "AlarmMethod"));  
94 - String alarmTime = XmlUtil.getText(rootElement, "AlarmTime");  
95 - if (alarmTime == null) {  
96 - return;  
97 - }  
98 - deviceAlarm.setAlarmTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(alarmTime));  
99 - String alarmDescription = getText(rootElement, "AlarmDescription");  
100 - if (alarmDescription == null) {  
101 - deviceAlarm.setAlarmDescription("");  
102 - } else {  
103 - deviceAlarm.setAlarmDescription(alarmDescription);  
104 - }  
105 - String longitude = getText(rootElement, "Longitude");  
106 - if (longitude != null && NumericUtil.isDouble(longitude)) {  
107 - deviceAlarm.setLongitude(Double.parseDouble(longitude));  
108 - } else {  
109 - deviceAlarm.setLongitude(0.00);  
110 - }  
111 - String latitude = getText(rootElement, "Latitude");  
112 - if (latitude != null && NumericUtil.isDouble(latitude)) {  
113 - deviceAlarm.setLatitude(Double.parseDouble(latitude));  
114 - } else {  
115 - deviceAlarm.setLatitude(0.00);  
116 - }  
117 -  
118 - if (!ObjectUtils.isEmpty(deviceAlarm.getAlarmMethod())) {  
119 - if ( deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.GPS.getVal() + "")) {  
120 - MobilePosition mobilePosition = new MobilePosition();  
121 - mobilePosition.setCreateTime(DateUtil.getNow());  
122 - mobilePosition.setDeviceId(deviceAlarm.getDeviceId());  
123 - mobilePosition.setTime(deviceAlarm.getAlarmTime());  
124 - mobilePosition.setLongitude(deviceAlarm.getLongitude());  
125 - mobilePosition.setLatitude(deviceAlarm.getLatitude());  
126 - mobilePosition.setReportSource("GPS Alarm");  
127 -  
128 - // 更新device channel 的经纬度  
129 - DeviceChannel deviceChannel = new DeviceChannel();  
130 - deviceChannel.setDeviceId(device.getDeviceId());  
131 - deviceChannel.setChannelId(channelId);  
132 - deviceChannel.setLongitude(mobilePosition.getLongitude());  
133 - deviceChannel.setLatitude(mobilePosition.getLatitude());  
134 - deviceChannel.setGpsTime(mobilePosition.getTime());  
135 -  
136 - deviceChannel = deviceChannelService.updateGps(deviceChannel, device);  
137 -  
138 - mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84());  
139 - mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84());  
140 - mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02());  
141 - mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02());  
142 -  
143 - if (userSetting.getSavePositionHistory()) {  
144 - storager.insertMobilePosition(mobilePosition); 91 + taskQueue.offer(new SipMsgInfo(evt, device, rootElement));
  92 + if (!taskQueueHandlerRun) {
  93 + taskQueueHandlerRun = true;
  94 + taskExecutor.execute(() -> {
  95 + logger.info("[处理报警通知]待处理数量:{}", taskQueue.size() );
  96 + while (!taskQueue.isEmpty()) {
  97 + SipMsgInfo sipMsgInfo = taskQueue.poll();
  98 + // 回复200 OK
  99 + try {
  100 + responseAck(getServerTransaction(sipMsgInfo.getEvt()), Response.OK);
  101 + } catch (SipException | InvalidArgumentException | ParseException e) {
  102 + logger.error("[处理报警通知], 回复200OK失败", e);
  103 + }
  104 +
  105 + Element deviceIdElement = sipMsgInfo.getRootElement().element("DeviceID");
  106 + String channelId = deviceIdElement.getText().toString();
  107 +
  108 + DeviceAlarm deviceAlarm = new DeviceAlarm();
  109 + deviceAlarm.setCreateTime(DateUtil.getNow());
  110 + deviceAlarm.setDeviceId(sipMsgInfo.getDevice().getDeviceId());
  111 + deviceAlarm.setChannelId(channelId);
  112 + deviceAlarm.setAlarmPriority(getText(sipMsgInfo.getRootElement(), "AlarmPriority"));
  113 + deviceAlarm.setAlarmMethod(getText(sipMsgInfo.getRootElement(), "AlarmMethod"));
  114 + String alarmTime = XmlUtil.getText(sipMsgInfo.getRootElement(), "AlarmTime");
  115 + if (alarmTime == null) {
  116 + continue;
  117 + }
  118 + deviceAlarm.setAlarmTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(alarmTime));
  119 + String alarmDescription = getText(sipMsgInfo.getRootElement(), "AlarmDescription");
  120 + if (alarmDescription == null) {
  121 + deviceAlarm.setAlarmDescription("");
  122 + } else {
  123 + deviceAlarm.setAlarmDescription(alarmDescription);
  124 + }
  125 + String longitude = getText(sipMsgInfo.getRootElement(), "Longitude");
  126 + if (longitude != null && NumericUtil.isDouble(longitude)) {
  127 + deviceAlarm.setLongitude(Double.parseDouble(longitude));
  128 + } else {
  129 + deviceAlarm.setLongitude(0.00);
  130 + }
  131 + String latitude = getText(sipMsgInfo.getRootElement(), "Latitude");
  132 + if (latitude != null && NumericUtil.isDouble(latitude)) {
  133 + deviceAlarm.setLatitude(Double.parseDouble(latitude));
  134 + } else {
  135 + deviceAlarm.setLatitude(0.00);
  136 + }
  137 +
  138 + if (!ObjectUtils.isEmpty(deviceAlarm.getAlarmMethod())) {
  139 + if ( deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.GPS.getVal() + "")) {
  140 + MobilePosition mobilePosition = new MobilePosition();
  141 + mobilePosition.setCreateTime(DateUtil.getNow());
  142 + mobilePosition.setDeviceId(deviceAlarm.getDeviceId());
  143 + mobilePosition.setTime(deviceAlarm.getAlarmTime());
  144 + mobilePosition.setLongitude(deviceAlarm.getLongitude());
  145 + mobilePosition.setLatitude(deviceAlarm.getLatitude());
  146 + mobilePosition.setReportSource("GPS Alarm");
  147 +
  148 + // 更新device channel 的经纬度
  149 + DeviceChannel deviceChannel = new DeviceChannel();
  150 + deviceChannel.setDeviceId(sipMsgInfo.getDevice().getDeviceId());
  151 + deviceChannel.setChannelId(channelId);
  152 + deviceChannel.setLongitude(mobilePosition.getLongitude());
  153 + deviceChannel.setLatitude(mobilePosition.getLatitude());
  154 + deviceChannel.setGpsTime(mobilePosition.getTime());
  155 +
  156 + deviceChannel = deviceChannelService.updateGps(deviceChannel, sipMsgInfo.getDevice());
  157 +
  158 + mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84());
  159 + mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84());
  160 + mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02());
  161 + mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02());
  162 +
  163 + if (userSetting.getSavePositionHistory()) {
  164 + storager.insertMobilePosition(mobilePosition);
  165 + }
  166 + storager.updateChannelPosition(deviceChannel);
  167 +
  168 + // 发送redis消息。 通知位置信息的变化
  169 + JSONObject jsonObject = new JSONObject();
  170 + jsonObject.put("time", mobilePosition.getTime());
  171 + jsonObject.put("serial", deviceChannel.getDeviceId());
  172 + jsonObject.put("code", deviceChannel.getChannelId());
  173 + jsonObject.put("longitude", mobilePosition.getLongitude());
  174 + jsonObject.put("latitude", mobilePosition.getLatitude());
  175 + jsonObject.put("altitude", mobilePosition.getAltitude());
  176 + jsonObject.put("direction", mobilePosition.getDirection());
  177 + jsonObject.put("speed", mobilePosition.getSpeed());
  178 + redisCatchStorage.sendMobilePositionMsg(jsonObject);
  179 + }
  180 + }
  181 + if (!ObjectUtils.isEmpty(deviceAlarm.getDeviceId())) {
  182 + if (deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.Video.getVal() + "")) {
  183 + deviceAlarm.setAlarmType(getText(sipMsgInfo.getRootElement().element("Info"), "AlarmType"));
  184 + }
  185 + }
  186 + logger.info("[收到报警通知]内容:{}", JSONObject.toJSON(deviceAlarm));
  187 + if ("7".equals(deviceAlarm.getAlarmMethod()) ) {
  188 + // 发送给平台的报警信息。 发送redis通知
  189 + AlarmChannelMessage alarmChannelMessage = new AlarmChannelMessage();
  190 + alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod()));
  191 + alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription());
  192 + alarmChannelMessage.setGbId(channelId);
  193 + redisCatchStorage.sendAlarmMsg(alarmChannelMessage);
  194 + continue;
  195 + }
  196 +
  197 + logger.debug("存储报警信息、报警分类");
  198 + // 存储报警信息、报警分类
  199 + if (sipConfig.isAlarm()) {
  200 + deviceAlarmService.add(deviceAlarm);
  201 + }
  202 +
  203 + if (redisCatchStorage.deviceIsOnline(sipMsgInfo.getDevice().getDeviceId())) {
  204 + publisher.deviceAlarmEventPublish(deviceAlarm);
  205 + }
145 } 206 }
146 - storager.updateChannelPosition(deviceChannel);  
147 -  
148 - // 发送redis消息。 通知位置信息的变化  
149 - JSONObject jsonObject = new JSONObject();  
150 - jsonObject.put("time", mobilePosition.getTime());  
151 - jsonObject.put("serial", deviceChannel.getDeviceId());  
152 - jsonObject.put("code", deviceChannel.getChannelId());  
153 - jsonObject.put("longitude", mobilePosition.getLongitude());  
154 - jsonObject.put("latitude", mobilePosition.getLatitude());  
155 - jsonObject.put("altitude", mobilePosition.getAltitude());  
156 - jsonObject.put("direction", mobilePosition.getDirection());  
157 - jsonObject.put("speed", mobilePosition.getSpeed());  
158 - redisCatchStorage.sendMobilePositionMsg(jsonObject);  
159 - }  
160 - }  
161 - if (!ObjectUtils.isEmpty(deviceAlarm.getDeviceId())) {  
162 - if (deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.Video.getVal() + "")) {  
163 - deviceAlarm.setAlarmType(getText(rootElement.element("Info"), "AlarmType"));  
164 - }  
165 - }  
166 -  
167 - if ("7".equals(deviceAlarm.getAlarmMethod()) ) {  
168 - // 发送给平台的报警信息。 发送redis通知  
169 - AlarmChannelMessage alarmChannelMessage = new AlarmChannelMessage();  
170 - alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod()));  
171 - alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription());  
172 - alarmChannelMessage.setGbId(channelId);  
173 - redisCatchStorage.sendAlarmMsg(alarmChannelMessage);  
174 - return; 207 + taskQueueHandlerRun = false;
  208 + });
175 } 209 }
176 210
177 - logger.debug("存储报警信息、报警分类");  
178 - // 存储报警信息、报警分类  
179 - if (sipConfig.isAlarm()) {  
180 - deviceAlarmService.add(deviceAlarm);  
181 - }  
182 211
183 - if (redisCatchStorage.deviceIsOnline(device.getDeviceId())) {  
184 - publisher.deviceAlarmEventPublish(deviceAlarm);  
185 - }  
186 } 212 }
187 213
188 @Override 214 @Override
@@ -190,7 +216,7 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme @@ -190,7 +216,7 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
190 logger.info("收到来自平台[{}]的报警通知", parentPlatform.getServerGBId()); 216 logger.info("收到来自平台[{}]的报警通知", parentPlatform.getServerGBId());
191 // 回复200 OK 217 // 回复200 OK
192 try { 218 try {
193 - responseAck(evt, Response.OK); 219 + responseAck(getServerTransaction(evt), Response.OK);
194 } catch (SipException e) { 220 } catch (SipException e) {
195 throw new RuntimeException(e); 221 throw new RuntimeException(e);
196 } catch (InvalidArgumentException e) { 222 } catch (InvalidArgumentException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
@@ -69,7 +69,7 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp @@ -69,7 +69,7 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
69 } 69 }
70 device.setKeepaliveTime(DateUtil.getNow()); 70 device.setKeepaliveTime(DateUtil.getNow());
71 // 回复200 OK 71 // 回复200 OK
72 - responseAck(evt, Response.OK); 72 + responseAck(getServerTransaction(evt), Response.OK);
73 if (device.getOnline() == 1) { 73 if (device.getOnline() == 1) {
74 deviceService.updateDevice(device); 74 deviceService.updateDevice(device);
75 }else { 75 }else {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java
@@ -66,7 +66,7 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i @@ -66,7 +66,7 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i
66 66
67 // 回复200 OK 67 // 回复200 OK
68 try { 68 try {
69 - responseAck(evt, Response.OK); 69 + responseAck(getServerTransaction(evt), Response.OK);
70 } catch (SipException e) { 70 } catch (SipException e) {
71 e.printStackTrace(); 71 e.printStackTrace();
72 } catch (InvalidArgumentException e) { 72 } catch (InvalidArgumentException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java
@@ -17,6 +17,8 @@ import org.slf4j.Logger; @@ -17,6 +17,8 @@ import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory; 17 import org.slf4j.LoggerFactory;
18 import org.springframework.beans.factory.InitializingBean; 18 import org.springframework.beans.factory.InitializingBean;
19 import org.springframework.beans.factory.annotation.Autowired; 19 import org.springframework.beans.factory.annotation.Autowired;
  20 +import org.springframework.beans.factory.annotation.Qualifier;
  21 +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
20 import org.springframework.stereotype.Component; 22 import org.springframework.stereotype.Component;
21 import org.springframework.util.ObjectUtils; 23 import org.springframework.util.ObjectUtils;
22 import org.springframework.util.StringUtils; 24 import org.springframework.util.StringUtils;
@@ -26,6 +28,7 @@ import javax.sip.RequestEvent; @@ -26,6 +28,7 @@ import javax.sip.RequestEvent;
26 import javax.sip.SipException; 28 import javax.sip.SipException;
27 import javax.sip.message.Response; 29 import javax.sip.message.Response;
28 import java.text.ParseException; 30 import java.text.ParseException;
  31 +import java.util.concurrent.ConcurrentLinkedQueue;
29 32
30 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText; 33 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
31 34
@@ -53,6 +56,14 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen @@ -53,6 +56,14 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen
53 @Autowired 56 @Autowired
54 private IDeviceChannelService deviceChannelService; 57 private IDeviceChannelService deviceChannelService;
55 58
  59 + private boolean taskQueueHandlerRun = false;
  60 +
  61 + private ConcurrentLinkedQueue<SipMsgInfo> taskQueue = new ConcurrentLinkedQueue<>();
  62 +
  63 + @Qualifier("taskExecutor")
  64 + @Autowired
  65 + private ThreadPoolTaskExecutor taskExecutor;
  66 +
56 @Override 67 @Override
57 public void afterPropertiesSet() throws Exception { 68 public void afterPropertiesSet() throws Exception {
58 notifyMessageHandler.addHandler(cmdType, this); 69 notifyMessageHandler.addHandler(cmdType, this);
@@ -61,78 +72,91 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen @@ -61,78 +72,91 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen
61 @Override 72 @Override
62 public void handForDevice(RequestEvent evt, Device device, Element rootElement) { 73 public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
63 74
64 - try {  
65 - rootElement = getRootElement(evt, device.getCharset());  
66 - if (rootElement == null) {  
67 - logger.warn("[ 移动设备位置数据通知 ] content cannot be null, {}", evt.getRequest());  
68 - responseAck(evt, Response.BAD_REQUEST);  
69 - return;  
70 - }  
71 - MobilePosition mobilePosition = new MobilePosition();  
72 - mobilePosition.setCreateTime(DateUtil.getNow());  
73 - if (!ObjectUtils.isEmpty(device.getName())) {  
74 - mobilePosition.setDeviceName(device.getName());  
75 - }  
76 - mobilePosition.setDeviceId(device.getDeviceId());  
77 - mobilePosition.setChannelId(getText(rootElement, "DeviceID"));  
78 - mobilePosition.setTime(getText(rootElement, "Time"));  
79 - mobilePosition.setLongitude(Double.parseDouble(getText(rootElement, "Longitude")));  
80 - mobilePosition.setLatitude(Double.parseDouble(getText(rootElement, "Latitude")));  
81 - if (NumericUtil.isDouble(getText(rootElement, "Speed"))) {  
82 - mobilePosition.setSpeed(Double.parseDouble(getText(rootElement, "Speed")));  
83 - } else {  
84 - mobilePosition.setSpeed(0.0);  
85 - }  
86 - if (NumericUtil.isDouble(getText(rootElement, "Direction"))) {  
87 - mobilePosition.setDirection(Double.parseDouble(getText(rootElement, "Direction")));  
88 - } else {  
89 - mobilePosition.setDirection(0.0);  
90 - }  
91 - if (NumericUtil.isDouble(getText(rootElement, "Altitude"))) {  
92 - mobilePosition.setAltitude(Double.parseDouble(getText(rootElement, "Altitude")));  
93 - } else {  
94 - mobilePosition.setAltitude(0.0);  
95 - }  
96 - mobilePosition.setReportSource("Mobile Position");  
97 -  
98 -  
99 - // 更新device channel 的经纬度  
100 - DeviceChannel deviceChannel = new DeviceChannel();  
101 - deviceChannel.setDeviceId(device.getDeviceId());  
102 - deviceChannel.setChannelId(mobilePosition.getChannelId());  
103 - deviceChannel.setLongitude(mobilePosition.getLongitude());  
104 - deviceChannel.setLatitude(mobilePosition.getLatitude());  
105 - deviceChannel.setGpsTime(mobilePosition.getTime());  
106 -  
107 - deviceChannel = deviceChannelService.updateGps(deviceChannel, device);  
108 -  
109 - mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84());  
110 - mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84());  
111 - mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02());  
112 - mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02());  
113 -  
114 - if (userSetting.getSavePositionHistory()) {  
115 - storager.insertMobilePosition(mobilePosition);  
116 - }  
117 - storager.updateChannelPosition(deviceChannel);  
118 - //回复 200 OK  
119 - responseAck(evt, Response.OK);  
120 -  
121 - // 发送redis消息。 通知位置信息的变化  
122 - JSONObject jsonObject = new JSONObject();  
123 - jsonObject.put("time", mobilePosition.getTime());  
124 - jsonObject.put("serial", deviceChannel.getDeviceId());  
125 - jsonObject.put("code", deviceChannel.getChannelId());  
126 - jsonObject.put("longitude", mobilePosition.getLongitude());  
127 - jsonObject.put("latitude", mobilePosition.getLatitude());  
128 - jsonObject.put("altitude", mobilePosition.getAltitude());  
129 - jsonObject.put("direction", mobilePosition.getDirection());  
130 - jsonObject.put("speed", mobilePosition.getSpeed());  
131 - redisCatchStorage.sendMobilePositionMsg(jsonObject);  
132 -  
133 - } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {  
134 - e.printStackTrace(); 75 + taskQueue.offer(new SipMsgInfo(evt, device, rootElement));
  76 + if (!taskQueueHandlerRun) {
  77 + taskQueueHandlerRun = true;
  78 + taskExecutor.execute(() -> {
  79 + while (!taskQueue.isEmpty()) {
  80 + SipMsgInfo sipMsgInfo = taskQueue.poll();
  81 + try {
  82 + Element rootElementAfterCharset = getRootElement(sipMsgInfo.getEvt(), sipMsgInfo.getDevice().getCharset());
  83 + if (rootElementAfterCharset == null) {
  84 + logger.warn("[ 移动设备位置数据通知 ] content cannot be null, {}", sipMsgInfo.getEvt().getRequest());
  85 + responseAck(getServerTransaction(sipMsgInfo.getEvt()), Response.BAD_REQUEST);
  86 + continue;
  87 + }
  88 + MobilePosition mobilePosition = new MobilePosition();
  89 + mobilePosition.setCreateTime(DateUtil.getNow());
  90 + if (!ObjectUtils.isEmpty(sipMsgInfo.getDevice().getName())) {
  91 + mobilePosition.setDeviceName(sipMsgInfo.getDevice().getName());
  92 + }
  93 + mobilePosition.setDeviceId(sipMsgInfo.getDevice().getDeviceId());
  94 + mobilePosition.setChannelId(getText(rootElementAfterCharset, "DeviceID"));
  95 + mobilePosition.setTime(getText(rootElementAfterCharset, "Time"));
  96 + mobilePosition.setLongitude(Double.parseDouble(getText(rootElementAfterCharset, "Longitude")));
  97 + mobilePosition.setLatitude(Double.parseDouble(getText(rootElementAfterCharset, "Latitude")));
  98 + if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Speed"))) {
  99 + mobilePosition.setSpeed(Double.parseDouble(getText(rootElementAfterCharset, "Speed")));
  100 + } else {
  101 + mobilePosition.setSpeed(0.0);
  102 + }
  103 + if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Direction"))) {
  104 + mobilePosition.setDirection(Double.parseDouble(getText(rootElementAfterCharset, "Direction")));
  105 + } else {
  106 + mobilePosition.setDirection(0.0);
  107 + }
  108 + if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Altitude"))) {
  109 + mobilePosition.setAltitude(Double.parseDouble(getText(rootElementAfterCharset, "Altitude")));
  110 + } else {
  111 + mobilePosition.setAltitude(0.0);
  112 + }
  113 + mobilePosition.setReportSource("Mobile Position");
  114 +
  115 +
  116 + // 更新device channel 的经纬度
  117 + DeviceChannel deviceChannel = new DeviceChannel();
  118 + deviceChannel.setDeviceId(sipMsgInfo.getDevice().getDeviceId());
  119 + deviceChannel.setChannelId(mobilePosition.getChannelId());
  120 + deviceChannel.setLongitude(mobilePosition.getLongitude());
  121 + deviceChannel.setLatitude(mobilePosition.getLatitude());
  122 + deviceChannel.setGpsTime(mobilePosition.getTime());
  123 +
  124 + deviceChannel = deviceChannelService.updateGps(deviceChannel, sipMsgInfo.getDevice());
  125 +
  126 + mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84());
  127 + mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84());
  128 + mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02());
  129 + mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02());
  130 +
  131 + if (userSetting.getSavePositionHistory()) {
  132 + storager.insertMobilePosition(mobilePosition);
  133 + }
  134 + storager.updateChannelPosition(deviceChannel);
  135 + //回复 200 OK
  136 + responseAck(getServerTransaction(sipMsgInfo.getEvt()), Response.OK);
  137 +
  138 + // 发送redis消息。 通知位置信息的变化
  139 + JSONObject jsonObject = new JSONObject();
  140 + jsonObject.put("time", mobilePosition.getTime());
  141 + jsonObject.put("serial", deviceChannel.getDeviceId());
  142 + jsonObject.put("code", deviceChannel.getChannelId());
  143 + jsonObject.put("longitude", mobilePosition.getLongitude());
  144 + jsonObject.put("latitude", mobilePosition.getLatitude());
  145 + jsonObject.put("altitude", mobilePosition.getAltitude());
  146 + jsonObject.put("direction", mobilePosition.getDirection());
  147 + jsonObject.put("speed", mobilePosition.getSpeed());
  148 + redisCatchStorage.sendMobilePositionMsg(jsonObject);
  149 +
  150 + } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
  151 + e.printStackTrace();
  152 + }
  153 +
  154 + }
  155 + taskQueueHandlerRun = false;
  156 + });
135 } 157 }
  158 +
  159 +
136 } 160 }
137 161
138 @Override 162 @Override
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/AlarmQueryMessageHandler.java
@@ -58,7 +58,7 @@ public class AlarmQueryMessageHandler extends SIPRequestProcessorParent implemen @@ -58,7 +58,7 @@ public class AlarmQueryMessageHandler extends SIPRequestProcessorParent implemen
58 58
59 logger.info("不支持alarm查询"); 59 logger.info("不支持alarm查询");
60 try { 60 try {
61 - responseAck(evt, Response.NOT_FOUND, "not support alarm query"); 61 + responseAck(getServerTransaction(evt), Response.NOT_FOUND, "not support alarm query");
62 } catch (SipException e) { 62 } catch (SipException e) {
63 e.printStackTrace(); 63 e.printStackTrace();
64 } catch (InvalidArgumentException e) { 64 } catch (InvalidArgumentException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/CatalogQueryMessageHandler.java
@@ -66,7 +66,7 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem @@ -66,7 +66,7 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
66 FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); 66 FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
67 try { 67 try {
68 // 回复200 OK 68 // 回复200 OK
69 - responseAck(evt, Response.OK); 69 + responseAck(getServerTransaction(evt), Response.OK);
70 Element snElement = rootElement.element("SN"); 70 Element snElement = rootElement.element("SN");
71 String sn = snElement.getText(); 71 String sn = snElement.getText();
72 // 准备回复通道信息 72 // 准备回复通道信息
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceInfoQueryMessageHandler.java
@@ -48,7 +48,7 @@ public class DeviceInfoQueryMessageHandler extends SIPRequestProcessorParent imp @@ -48,7 +48,7 @@ public class DeviceInfoQueryMessageHandler extends SIPRequestProcessorParent imp
48 FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); 48 FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
49 try { 49 try {
50 // 回复200 OK 50 // 回复200 OK
51 - responseAck(evt, Response.OK); 51 + responseAck(getServerTransaction(evt), Response.OK);
52 } catch (SipException e) { 52 } catch (SipException e) {
53 e.printStackTrace(); 53 e.printStackTrace();
54 } catch (InvalidArgumentException e) { 54 } catch (InvalidArgumentException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceStatusQueryMessageHandler.java
@@ -61,7 +61,7 @@ public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent i @@ -61,7 +61,7 @@ public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent i
61 FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); 61 FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
62 // 回复200 OK 62 // 回复200 OK
63 try { 63 try {
64 - responseAck(evt, Response.OK); 64 + responseAck(getServerTransaction(evt), Response.OK);
65 } catch (SipException e) { 65 } catch (SipException e) {
66 e.printStackTrace(); 66 e.printStackTrace();
67 } catch (InvalidArgumentException e) { 67 } catch (InvalidArgumentException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/RecordInfoQueryMessageHandler.java
@@ -21,6 +21,7 @@ import org.springframework.stereotype.Component; @@ -21,6 +21,7 @@ import org.springframework.stereotype.Component;
21 21
22 import javax.sip.InvalidArgumentException; 22 import javax.sip.InvalidArgumentException;
23 import javax.sip.RequestEvent; 23 import javax.sip.RequestEvent;
  24 +import javax.sip.ServerTransaction;
24 import javax.sip.SipException; 25 import javax.sip.SipException;
25 import javax.sip.header.FromHeader; 26 import javax.sip.header.FromHeader;
26 import javax.sip.message.Response; 27 import javax.sip.message.Response;
@@ -68,7 +69,7 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp @@ -68,7 +69,7 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp
68 public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) { 69 public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
69 70
70 FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); 71 FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
71 - 72 + ServerTransaction serverTransaction = getServerTransaction(evt);
72 Element snElement = rootElement.element("SN"); 73 Element snElement = rootElement.element("SN");
73 int sn = Integer.parseInt(snElement.getText()); 74 int sn = Integer.parseInt(snElement.getText());
74 Element deviceIDElement = rootElement.element("DeviceID"); 75 Element deviceIDElement = rootElement.element("DeviceID");
@@ -108,7 +109,7 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp @@ -108,7 +109,7 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp
108 DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(endTime), sn, secrecy, type, (eventResult -> { 109 DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(endTime), sn, secrecy, type, (eventResult -> {
109 // 回复200 OK 110 // 回复200 OK
110 try { 111 try {
111 - responseAck(evt, Response.OK); 112 + responseAck(serverTransaction, Response.OK);
112 } catch (SipException e) { 113 } catch (SipException e) {
113 e.printStackTrace(); 114 e.printStackTrace();
114 } catch (InvalidArgumentException e) { 115 } catch (InvalidArgumentException e) {
@@ -119,7 +120,7 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp @@ -119,7 +120,7 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp
119 }),(eventResult -> { 120 }),(eventResult -> {
120 // 查询失败 121 // 查询失败
121 try { 122 try {
122 - responseAck(evt, eventResult.statusCode, eventResult.msg); 123 + responseAck(serverTransaction, eventResult.statusCode, eventResult.msg);
123 } catch (SipException e) { 124 } catch (SipException e) {
124 e.printStackTrace(); 125 e.printStackTrace();
125 } catch (InvalidArgumentException e) { 126 } catch (InvalidArgumentException e) {
@@ -132,7 +133,7 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp @@ -132,7 +133,7 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp
132 }else if (channelSources.get(1).getCount() > 0) { // 直播流 133 }else if (channelSources.get(1).getCount() > 0) { // 直播流
133 // TODO 134 // TODO
134 try { 135 try {
135 - responseAck(evt, Response.NOT_IMPLEMENTED); // 回复未实现 136 + responseAck(serverTransaction, Response.NOT_IMPLEMENTED); // 回复未实现
136 } catch (SipException e) { 137 } catch (SipException e) {
137 e.printStackTrace(); 138 e.printStackTrace();
138 } catch (InvalidArgumentException e) { 139 } catch (InvalidArgumentException e) {
@@ -142,7 +143,7 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp @@ -142,7 +143,7 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp
142 } 143 }
143 }else { // 错误的请求 144 }else { // 错误的请求
144 try { 145 try {
145 - responseAck(evt, Response.BAD_REQUEST); 146 + responseAck(serverTransaction, Response.BAD_REQUEST);
146 } catch (SipException e) { 147 } catch (SipException e) {
147 e.printStackTrace(); 148 e.printStackTrace();
148 } catch (InvalidArgumentException e) { 149 } catch (InvalidArgumentException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java
@@ -21,6 +21,7 @@ import org.springframework.stereotype.Component; @@ -21,6 +21,7 @@ import org.springframework.stereotype.Component;
21 21
22 import javax.sip.InvalidArgumentException; 22 import javax.sip.InvalidArgumentException;
23 import javax.sip.RequestEvent; 23 import javax.sip.RequestEvent;
  24 +import javax.sip.ServerTransaction;
24 import javax.sip.SipException; 25 import javax.sip.SipException;
25 import javax.sip.message.Response; 26 import javax.sip.message.Response;
26 import java.text.ParseException; 27 import java.text.ParseException;
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
@@ -27,6 +27,7 @@ import org.springframework.util.StringUtils; @@ -27,6 +27,7 @@ import org.springframework.util.StringUtils;
27 27
28 import javax.sip.InvalidArgumentException; 28 import javax.sip.InvalidArgumentException;
29 import javax.sip.RequestEvent; 29 import javax.sip.RequestEvent;
  30 +import javax.sip.ServerTransaction;
30 import javax.sip.SipException; 31 import javax.sip.SipException;
31 import javax.sip.message.Response; 32 import javax.sip.message.Response;
32 import java.text.ParseException; 33 import java.text.ParseException;
@@ -87,7 +88,8 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp @@ -87,7 +88,8 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
87 taskQueue.offer(new HandlerCatchData(evt, device, element)); 88 taskQueue.offer(new HandlerCatchData(evt, device, element));
88 // 回复200 OK 89 // 回复200 OK
89 try { 90 try {
90 - responseAck(evt, Response.OK); 91 + ServerTransaction serverTransaction = getServerTransaction(evt);
  92 + responseAck(serverTransaction, Response.OK);
91 if (!taskQueueHandlerRun) { 93 if (!taskQueueHandlerRun) {
92 taskQueueHandlerRun = true; 94 taskQueueHandlerRun = true;
93 taskExecutor.execute(()-> { 95 taskExecutor.execute(()-> {
@@ -103,7 +105,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp @@ -103,7 +105,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
103 Element sumNumElement = rootElement.element("SumNum"); 105 Element sumNumElement = rootElement.element("SumNum");
104 Element snElement = rootElement.element("SN"); 106 Element snElement = rootElement.element("SN");
105 if (snElement == null || sumNumElement == null || deviceListElement == null) { 107 if (snElement == null || sumNumElement == null || deviceListElement == null) {
106 - responseAck(take.getEvt(), Response.BAD_REQUEST, "xml error"); 108 + responseAck(serverTransaction, Response.BAD_REQUEST, "xml error");
107 continue; 109 continue;
108 } 110 }
109 int sumNum = Integer.parseInt(sumNumElement.getText()); 111 int sumNum = Integer.parseInt(sumNumElement.getText());
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/ConfigDownloadResponseMessageHandler.java
@@ -52,7 +52,7 @@ public class ConfigDownloadResponseMessageHandler extends SIPRequestProcessorPar @@ -52,7 +52,7 @@ public class ConfigDownloadResponseMessageHandler extends SIPRequestProcessorPar
52 String key = DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + device.getDeviceId() + channelId; 52 String key = DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + device.getDeviceId() + channelId;
53 try { 53 try {
54 // 回复200 OK 54 // 回复200 OK
55 - responseAck(evt, Response.OK); 55 + responseAck(getServerTransaction(evt), Response.OK);
56 // 此处是对本平台发出DeviceControl指令的应答 56 // 此处是对本平台发出DeviceControl指令的应答
57 JSONObject json = new JSONObject(); 57 JSONObject json = new JSONObject();
58 XmlUtil.node2Json(element, json); 58 XmlUtil.node2Json(element, json);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceControlResponseMessageHandler.java
@@ -46,7 +46,7 @@ public class DeviceControlResponseMessageHandler extends SIPRequestProcessorPare @@ -46,7 +46,7 @@ public class DeviceControlResponseMessageHandler extends SIPRequestProcessorPare
46 public void handForDevice(RequestEvent evt, Device device, Element element) { 46 public void handForDevice(RequestEvent evt, Device device, Element element) {
47 // 此处是对本平台发出DeviceControl指令的应答 47 // 此处是对本平台发出DeviceControl指令的应答
48 try { 48 try {
49 - responseAck(evt, Response.OK); 49 + responseAck(getServerTransaction(evt), Response.OK);
50 JSONObject json = new JSONObject(); 50 JSONObject json = new JSONObject();
51 String channelId = getText(element, "DeviceID"); 51 String channelId = getText(element, "DeviceID");
52 XmlUtil.node2Json(element, json); 52 XmlUtil.node2Json(element, json);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceInfoResponseMessageHandler.java
@@ -25,6 +25,7 @@ import org.springframework.util.StringUtils; @@ -25,6 +25,7 @@ import org.springframework.util.StringUtils;
25 25
26 import javax.sip.InvalidArgumentException; 26 import javax.sip.InvalidArgumentException;
27 import javax.sip.RequestEvent; 27 import javax.sip.RequestEvent;
  28 +import javax.sip.ServerTransaction;
28 import javax.sip.SipException; 29 import javax.sip.SipException;
29 import javax.sip.message.Response; 30 import javax.sip.message.Response;
30 import java.text.ParseException; 31 import java.text.ParseException;
@@ -74,11 +75,12 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent @@ -74,11 +75,12 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent
74 logger.warn("[接收到DeviceInfo应答消息,但是设备已经离线]:" + (device != null ? device.getDeviceId():"" )); 75 logger.warn("[接收到DeviceInfo应答消息,但是设备已经离线]:" + (device != null ? device.getDeviceId():"" ));
75 return; 76 return;
76 } 77 }
  78 + ServerTransaction serverTransaction = getServerTransaction(evt);
77 try { 79 try {
78 rootElement = getRootElement(evt, device.getCharset()); 80 rootElement = getRootElement(evt, device.getCharset());
79 if (rootElement == null) { 81 if (rootElement == null) {
80 logger.warn("[ 接收到DeviceInfo应答消息 ] content cannot be null, {}", evt.getRequest()); 82 logger.warn("[ 接收到DeviceInfo应答消息 ] content cannot be null, {}", evt.getRequest());
81 - responseAck(evt, Response.BAD_REQUEST); 83 + responseAck(serverTransaction, Response.BAD_REQUEST);
82 return; 84 return;
83 } 85 }
84 Element deviceIdElement = rootElement.element("DeviceID"); 86 Element deviceIdElement = rootElement.element("DeviceID");
@@ -99,7 +101,7 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent @@ -99,7 +101,7 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent
99 msg.setData(device); 101 msg.setData(device);
100 deferredResultHolder.invokeAllResult(msg); 102 deferredResultHolder.invokeAllResult(msg);
101 // 回复200 OK 103 // 回复200 OK
102 - responseAck(evt, Response.OK); 104 + responseAck(serverTransaction, Response.OK);
103 } catch (DocumentException e) { 105 } catch (DocumentException e) {
104 e.printStackTrace(); 106 e.printStackTrace();
105 } catch (InvalidArgumentException e) { 107 } catch (InvalidArgumentException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceStatusResponseMessageHandler.java
@@ -59,7 +59,7 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen @@ -59,7 +59,7 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen
59 } 59 }
60 // 回复200 OK 60 // 回复200 OK
61 try { 61 try {
62 - responseAck(evt, Response.OK); 62 + responseAck(getServerTransaction(evt), Response.OK);
63 } catch (SipException e) { 63 } catch (SipException e) {
64 e.printStackTrace(); 64 e.printStackTrace();
65 } catch (InvalidArgumentException e) { 65 } catch (InvalidArgumentException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java
@@ -25,6 +25,7 @@ import org.springframework.util.StringUtils; @@ -25,6 +25,7 @@ import org.springframework.util.StringUtils;
25 25
26 import javax.sip.InvalidArgumentException; 26 import javax.sip.InvalidArgumentException;
27 import javax.sip.RequestEvent; 27 import javax.sip.RequestEvent;
  28 +import javax.sip.ServerTransaction;
28 import javax.sip.SipException; 29 import javax.sip.SipException;
29 import javax.sip.message.Response; 30 import javax.sip.message.Response;
30 import java.text.ParseException; 31 import java.text.ParseException;
@@ -64,11 +65,13 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar @@ -64,11 +65,13 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar
64 @Override 65 @Override
65 public void handForDevice(RequestEvent evt, Device device, Element rootElement) { 66 public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
66 67
  68 + ServerTransaction serverTransaction = getServerTransaction(evt);
  69 +
67 try { 70 try {
68 rootElement = getRootElement(evt, device.getCharset()); 71 rootElement = getRootElement(evt, device.getCharset());
69 if (rootElement == null) { 72 if (rootElement == null) {
70 logger.warn("[ 移动设备位置数据查询回复 ] content cannot be null, {}", evt.getRequest()); 73 logger.warn("[ 移动设备位置数据查询回复 ] content cannot be null, {}", evt.getRequest());
71 - responseAck(evt, Response.BAD_REQUEST); 74 + responseAck(serverTransaction, Response.BAD_REQUEST);
72 return; 75 return;
73 } 76 }
74 MobilePosition mobilePosition = new MobilePosition(); 77 MobilePosition mobilePosition = new MobilePosition();
@@ -130,7 +133,7 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar @@ -130,7 +133,7 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar
130 jsonObject.put("speed", mobilePosition.getSpeed()); 133 jsonObject.put("speed", mobilePosition.getSpeed());
131 redisCatchStorage.sendMobilePositionMsg(jsonObject); 134 redisCatchStorage.sendMobilePositionMsg(jsonObject);
132 //回复 200 OK 135 //回复 200 OK
133 - responseAck(evt, Response.OK); 136 + responseAck(serverTransaction, Response.OK);
134 } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { 137 } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
135 e.printStackTrace(); 138 e.printStackTrace();
136 } 139 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java
@@ -17,6 +17,7 @@ import org.springframework.stereotype.Component; @@ -17,6 +17,7 @@ import org.springframework.stereotype.Component;
17 17
18 import javax.sip.InvalidArgumentException; 18 import javax.sip.InvalidArgumentException;
19 import javax.sip.RequestEvent; 19 import javax.sip.RequestEvent;
  20 +import javax.sip.ServerTransaction;
20 import javax.sip.SipException; 21 import javax.sip.SipException;
21 import javax.sip.message.Response; 22 import javax.sip.message.Response;
22 import java.text.ParseException; 23 import java.text.ParseException;
@@ -51,10 +52,13 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent @@ -51,10 +52,13 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent
51 public void handForDevice(RequestEvent evt, Device device, Element element) { 52 public void handForDevice(RequestEvent evt, Device device, Element element) {
52 Element rootElement = null; 53 Element rootElement = null;
53 try { 54 try {
  55 +
  56 + ServerTransaction serverTransaction = getServerTransaction(evt);
  57 +
54 rootElement = getRootElement(evt, device.getCharset()); 58 rootElement = getRootElement(evt, device.getCharset());
55 if (rootElement == null) { 59 if (rootElement == null) {
56 logger.warn("[ 设备预置位查询应答 ] content cannot be null, {}", evt.getRequest()); 60 logger.warn("[ 设备预置位查询应答 ] content cannot be null, {}", evt.getRequest());
57 - responseAck(evt, Response.BAD_REQUEST); 61 + responseAck(serverTransaction, Response.BAD_REQUEST);
58 return; 62 return;
59 } 63 }
60 Element presetListNumElement = rootElement.element("PresetList"); 64 Element presetListNumElement = rootElement.element("PresetList");
@@ -63,7 +67,7 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent @@ -63,7 +67,7 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent
63 String deviceId = getText(rootElement, "DeviceID"); 67 String deviceId = getText(rootElement, "DeviceID");
64 String key = DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + deviceId; 68 String key = DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + deviceId;
65 if (snElement == null || presetListNumElement == null) { 69 if (snElement == null || presetListNumElement == null) {
66 - responseAck(evt, Response.BAD_REQUEST, "xml error"); 70 + responseAck(serverTransaction, Response.BAD_REQUEST, "xml error");
67 return; 71 return;
68 } 72 }
69 int sumNum = Integer.parseInt(presetListNumElement.attributeValue("Num")); 73 int sumNum = Integer.parseInt(presetListNumElement.attributeValue("Num"));
@@ -93,7 +97,7 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent @@ -93,7 +97,7 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent
93 requestMessage.setKey(key); 97 requestMessage.setKey(key);
94 requestMessage.setData(presetQuerySipReqList); 98 requestMessage.setData(presetQuerySipReqList);
95 deferredResultHolder.invokeAllResult(requestMessage); 99 deferredResultHolder.invokeAllResult(requestMessage);
96 - responseAck(evt, Response.OK); 100 + responseAck(serverTransaction, Response.OK);
97 } catch (DocumentException e) { 101 } catch (DocumentException e) {
98 e.printStackTrace(); 102 e.printStackTrace();
99 } catch (InvalidArgumentException e) { 103 } catch (InvalidArgumentException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java
@@ -72,7 +72,7 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent @@ -72,7 +72,7 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
72 72
73 // 回复200 OK 73 // 回复200 OK
74 try { 74 try {
75 - responseAck(evt, Response.OK); 75 + responseAck(getServerTransaction(evt), Response.OK);
76 taskQueue.offer(new HandlerCatchData(evt, device, rootElement)); 76 taskQueue.offer(new HandlerCatchData(evt, device, rootElement));
77 if (!taskQueueHandlerRun) { 77 if (!taskQueueHandlerRun) {
78 taskQueueHandlerRun = true; 78 taskQueueHandlerRun = true;
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java
@@ -7,6 +7,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcesso @@ -7,6 +7,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcesso
7 import com.genersoft.iot.vmp.gb28181.utils.SipUtils; 7 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
8 import com.genersoft.iot.vmp.utils.GitUtil; 8 import com.genersoft.iot.vmp.utils.GitUtil;
9 import gov.nist.javax.sip.ResponseEventExt; 9 import gov.nist.javax.sip.ResponseEventExt;
  10 +import gov.nist.javax.sip.message.SIPResponse;
  11 +import gov.nist.javax.sip.stack.SIPClientTransaction;
10 import gov.nist.javax.sip.stack.SIPDialog; 12 import gov.nist.javax.sip.stack.SIPDialog;
11 import org.slf4j.Logger; 13 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory; 14 import org.slf4j.LoggerFactory;
@@ -78,7 +80,7 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract { @@ -78,7 +80,7 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract {
78 // 下发ack 80 // 下发ack
79 if (statusCode == Response.OK) { 81 if (statusCode == Response.OK) {
80 ResponseEventExt event = (ResponseEventExt)evt; 82 ResponseEventExt event = (ResponseEventExt)evt;
81 - SIPDialog dialog = (SIPDialog)evt.getDialog(); 83 + SIPDialog dialog = new SIPDialog((SIPClientTransaction) event.getClientTransaction(), (SIPResponse) event.getResponse());
82 CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); 84 CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
83 Request reqAck = dialog.createAck(cseq.getSeqNumber()); 85 Request reqAck = dialog.createAck(cseq.getSeqNumber());
84 SipURI requestURI = (SipURI) reqAck.getRequestURI(); 86 SipURI requestURI = (SipURI) reqAck.getRequestURI();
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -103,7 +103,7 @@ public class ZLMHttpHookListener { @@ -103,7 +103,7 @@ public class ZLMHttpHookListener {
103 @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") 103 @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8")
104 public JSONObject onServerKeepalive(@RequestBody JSONObject json){ 104 public JSONObject onServerKeepalive(@RequestBody JSONObject json){
105 105
106 - logger.info("[ ZLM HOOK ] on_server_keepalive API调用,参数:" + json.toString()); 106 + logger.info("[ ZLM HOOK ]on_server_keepalive API调用,参数:" + json.toString());
107 String mediaServerId = json.getString("mediaServerId"); 107 String mediaServerId = json.getString("mediaServerId");
108 List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive); 108 List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive);
109 if (subscribes != null && subscribes.size() > 0) { 109 if (subscribes != null && subscribes.size() > 0) {
@@ -417,10 +417,11 @@ public class ZLMHttpHookListener { @@ -417,10 +417,11 @@ public class ZLMHttpHookListener {
417 String schema = item.getSchema(); 417 String schema = item.getSchema();
418 List<MediaItem.MediaTrack> tracks = item.getTracks(); 418 List<MediaItem.MediaTrack> tracks = item.getTracks();
419 boolean regist = item.isRegist(); 419 boolean regist = item.isRegist();
420 - if (item.getOriginType() == OriginType.RTMP_PUSH.ordinal()  
421 - || item.getOriginType() == OriginType.RTSP_PUSH.ordinal()  
422 - || item.getOriginType() == OriginType.RTC_PUSH.ordinal()) {  
423 - if (regist) { 420 + if (regist) {
  421 + if (item.getOriginType() == OriginType.RTMP_PUSH.ordinal()
  422 + || item.getOriginType() == OriginType.RTSP_PUSH.ordinal()
  423 + || item.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
  424 +
424 StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); 425 StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream);
425 if (streamAuthorityInfo == null) { 426 if (streamAuthorityInfo == null) {
426 streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(item); 427 streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(item);
@@ -429,9 +430,9 @@ public class ZLMHttpHookListener { @@ -429,9 +430,9 @@ public class ZLMHttpHookListener {
429 streamAuthorityInfo.setOriginTypeStr(item.getOriginTypeStr()); 430 streamAuthorityInfo.setOriginTypeStr(item.getOriginTypeStr());
430 } 431 }
431 redisCatchStorage.updateStreamAuthorityInfo(app, stream, streamAuthorityInfo); 432 redisCatchStorage.updateStreamAuthorityInfo(app, stream, streamAuthorityInfo);
432 - }else {  
433 - redisCatchStorage.removeStreamAuthorityInfo(app, stream);  
434 } 433 }
  434 + }else {
  435 + redisCatchStorage.removeStreamAuthorityInfo(app, stream);
435 } 436 }
436 437
437 if ("rtsp".equals(schema)){ 438 if ("rtsp".equals(schema)){
@@ -451,15 +452,12 @@ public class ZLMHttpHookListener { @@ -451,15 +452,12 @@ public class ZLMHttpHookListener {
451 if (streamInfo!=null){ 452 if (streamInfo!=null){
452 redisCatchStorage.stopPlay(streamInfo); 453 redisCatchStorage.stopPlay(streamInfo);
453 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); 454 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
454 - // 如果正在给上级推送,则发送bye  
455 -  
456 }else{ 455 }else{
457 streamInfo = redisCatchStorage.queryPlayback(null, null, stream, null); 456 streamInfo = redisCatchStorage.queryPlayback(null, null, stream, null);
458 if (streamInfo != null) { 457 if (streamInfo != null) {
459 redisCatchStorage.stopPlayback(streamInfo.getDeviceID(), streamInfo.getChannelId(), 458 redisCatchStorage.stopPlayback(streamInfo.getDeviceID(), streamInfo.getChannelId(),
460 streamInfo.getStream(), null); 459 streamInfo.getStream(), null);
461 } 460 }
462 - // 如果正在给上级推送,则发送bye  
463 } 461 }
464 }else { 462 }else {
465 if (!"rtp".equals(app)){ 463 if (!"rtp".equals(app)){
@@ -509,6 +507,19 @@ public class ZLMHttpHookListener { @@ -509,6 +507,19 @@ public class ZLMHttpHookListener {
509 } 507 }
510 } 508 }
511 } 509 }
  510 + if (!regist) {
  511 + List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(stream);
  512 + if (sendRtpItems.size() > 0) {
  513 + for (SendRtpItem sendRtpItem : sendRtpItems) {
  514 + if (sendRtpItem.getApp().equals(app)) {
  515 + String platformId = sendRtpItem.getPlatformId();
  516 + ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);
  517 +
  518 + commanderFroPlatform.streamByeCmd(platform, sendRtpItem);
  519 + }
  520 + }
  521 + }
  522 + }
512 } 523 }
513 524
514 JSONObject ret = new JSONObject(); 525 JSONObject ret = new JSONObject();
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
@@ -17,6 +17,7 @@ import org.slf4j.LoggerFactory; @@ -17,6 +17,7 @@ import org.slf4j.LoggerFactory;
17 import org.springframework.beans.factory.annotation.Autowired; 17 import org.springframework.beans.factory.annotation.Autowired;
18 import org.springframework.stereotype.Component; 18 import org.springframework.stereotype.Component;
19 19
  20 +import java.text.ParseException;
20 import java.util.*; 21 import java.util.*;
21 import java.util.concurrent.ConcurrentHashMap; 22 import java.util.concurrent.ConcurrentHashMap;
22 23
@@ -83,7 +84,11 @@ public class ZLMMediaListManager { @@ -83,7 +84,11 @@ public class ZLMMediaListManager {
83 } 84 }
84 if (transform != null) { 85 if (transform != null) {
85 if (getChannelOnlineEventLister(transform.getApp(), transform.getStream()) != null) { 86 if (getChannelOnlineEventLister(transform.getApp(), transform.getStream()) != null) {
86 - getChannelOnlineEventLister(transform.getApp(), transform.getStream()).run(transform.getApp(), transform.getStream(), transform.getServerId()); 87 + try {
  88 + getChannelOnlineEventLister(transform.getApp(), transform.getStream()).run(transform.getApp(), transform.getStream(), transform.getServerId());
  89 + } catch (ParseException e) {
  90 + throw new RuntimeException(e);
  91 + }
87 removedChannelOnlineEventLister(transform.getApp(), transform.getStream()); 92 removedChannelOnlineEventLister(transform.getApp(), transform.getStream());
88 } 93 }
89 } 94 }
@@ -95,7 +100,11 @@ public class ZLMMediaListManager { @@ -95,7 +100,11 @@ public class ZLMMediaListManager {
95 // 查看推流状态 100 // 查看推流状态
96 if (zlmrtpServerFactory.isStreamReady(mediaServerItem, app, stream)) { 101 if (zlmrtpServerFactory.isStreamReady(mediaServerItem, app, stream)) {
97 if (getChannelOnlineEventLister(app, stream) != null) { 102 if (getChannelOnlineEventLister(app, stream) != null) {
98 - getChannelOnlineEventLister(app, stream).run(app, stream, mediaServerId); 103 + try {
  104 + getChannelOnlineEventLister(app, stream).run(app, stream, mediaServerId);
  105 + } catch (ParseException e) {
  106 + throw new RuntimeException(e);
  107 + }
99 removedChannelOnlineEventLister(app, stream); 108 removedChannelOnlineEventLister(app, stream);
100 } 109 }
101 } 110 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
@@ -98,7 +98,18 @@ public class ZLMRTPServerFactory { @@ -98,7 +98,18 @@ public class ZLMRTPServerFactory {
98 result = rtpInfo.getInteger("local_port"); 98 result = rtpInfo.getInteger("local_port");
99 if (result == 0) { 99 if (result == 0) {
100 // 此时说明rtpServer已经创建但是流还没有推上来 100 // 此时说明rtpServer已经创建但是流还没有推上来
101 - 101 + // 此时重新打开rtpServer
  102 + Map<String, Object> param = new HashMap<>();
  103 + param.put("stream_id", streamId);
  104 + JSONObject jsonObject = zlmresTfulUtils.closeRtpServer(mediaServerItem, param);
  105 + if (jsonObject != null ) {
  106 + System.out.println(jsonObject);
  107 + if (jsonObject.getInteger("code") == 0) {
  108 + return createRTPServer(mediaServerItem, streamId, ssrc, port);
  109 + }else {
  110 + logger.warn("[开启rtpServer], 重启RtpServer错误");
  111 + }
  112 + }
102 } 113 }
103 return result; 114 return result;
104 } 115 }
@@ -326,12 +337,12 @@ public class ZLMRTPServerFactory { @@ -326,12 +337,12 @@ public class ZLMRTPServerFactory {
326 Boolean result = false; 337 Boolean result = false;
327 JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaServerItem, param); 338 JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaServerItem, param);
328 if (jsonObject == null) { 339 if (jsonObject == null) {
329 - logger.error("停止RTP推流失败: 请检查ZLM服务"); 340 + logger.error("[停止RTP推流] 失败: 请检查ZLM服务");
330 } else if (jsonObject.getInteger("code") == 0) { 341 } else if (jsonObject.getInteger("code") == 0) {
331 result= true; 342 result= true;
332 - logger.info("停止RTP推流成功"); 343 + logger.info("[停止RTP推流] 成功");
333 } else { 344 } else {
334 - logger.error("停止RTP推流失败: {}, 参数:{}",jsonObject.getString("msg"),JSONObject.toJSON(param)); 345 + logger.error("[停止RTP推流] 失败: {}, 参数:{}->\r\n{}",jsonObject.getString("msg"),JSONObject.toJSON(param), jsonObject);
335 } 346 }
336 return result; 347 return result;
337 } 348 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
@@ -104,7 +104,7 @@ public class ZLMRunner implements CommandLineRunner { @@ -104,7 +104,7 @@ public class ZLMRunner implements CommandLineRunner {
104 }, 60 * 1000 ); 104 }, 60 * 1000 );
105 } 105 }
106 106
107 - @Async 107 + @Async("taskExecutor")
108 public void connectZlmServer(MediaServerItem mediaServerItem){ 108 public void connectZlmServer(MediaServerItem mediaServerItem){
109 String connectZlmServerTaskKey = "connect-zlm-" + mediaServerItem.getId(); 109 String connectZlmServerTaskKey = "connect-zlm-" + mediaServerItem.getId();
110 ZLMServerConfig zlmServerConfigFirst = getMediaServerConfig(mediaServerItem); 110 ZLMServerConfig zlmServerConfigFirst = getMediaServerConfig(mediaServerItem);
src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java
@@ -137,8 +137,6 @@ public class ZlmHttpHookSubscribe { @@ -137,8 +137,6 @@ public class ZlmHttpHookSubscribe {
137 @Scheduled(cron="0 0/5 * * * ?") //每5分钟执行一次 137 @Scheduled(cron="0 0/5 * * * ?") //每5分钟执行一次
138 public void execute(){ 138 public void execute(){
139 139
140 - logger.info("[hook订阅] 清理");  
141 -  
142 Instant instant = Instant.now().minusMillis(TimeUnit.MINUTES.toMillis(5)); 140 Instant instant = Instant.now().minusMillis(TimeUnit.MINUTES.toMillis(5));
143 int total = 0; 141 int total = 0;
144 for (HookType hookType : allSubscribes.keySet()) { 142 for (HookType hookType : allSubscribes.keySet()) {
@@ -153,6 +151,5 @@ public class ZlmHttpHookSubscribe { @@ -153,6 +151,5 @@ public class ZlmHttpHookSubscribe {
153 } 151 }
154 } 152 }
155 } 153 }
156 - logger.info("[hook订阅] 清理结束,共清理{}条过期数据", total);  
157 } 154 }
158 } 155 }
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ChannelOnlineEvent.java
1 package com.genersoft.iot.vmp.media.zlm.dto; 1 package com.genersoft.iot.vmp.media.zlm.dto;
2 2
  3 +import java.text.ParseException;
  4 +
3 /** 5 /**
4 * @author lin 6 * @author lin
5 */ 7 */
6 public interface ChannelOnlineEvent { 8 public interface ChannelOnlineEvent {
7 9
8 - void run(String app, String stream, String serverId); 10 + void run(String app, String stream, String serverId) throws ParseException;
9 } 11 }
src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMStatusEventListener.java
@@ -36,7 +36,7 @@ public class ZLMStatusEventListener { @@ -36,7 +36,7 @@ public class ZLMStatusEventListener {
36 @Autowired 36 @Autowired
37 private IPlayService playService; 37 private IPlayService playService;
38 38
39 - @Async 39 + @Async("taskExecutor")
40 @EventListener 40 @EventListener
41 public void onApplicationEvent(ZLMOnlineEvent event) { 41 public void onApplicationEvent(ZLMOnlineEvent event) {
42 logger.info("[ZLM] 上线 ID:" + event.getMediaServerId()); 42 logger.info("[ZLM] 上线 ID:" + event.getMediaServerId());
@@ -45,7 +45,7 @@ public class ZLMStatusEventListener { @@ -45,7 +45,7 @@ public class ZLMStatusEventListener {
45 playService.zlmServerOnline(event.getMediaServerId()); 45 playService.zlmServerOnline(event.getMediaServerId());
46 } 46 }
47 47
48 - @Async 48 + @Async("taskExecutor")
49 @EventListener 49 @EventListener
50 public void onApplicationEvent(ZLMOfflineEvent event) { 50 public void onApplicationEvent(ZLMOfflineEvent event) {
51 51
src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java
1 package com.genersoft.iot.vmp.service; 1 package com.genersoft.iot.vmp.service;
2 2
  3 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
3 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  5 +import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo;
  6 +import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
4 import com.github.pagehelper.PageInfo; 7 import com.github.pagehelper.PageInfo;
5 8
  9 +import java.util.List;
  10 +
6 /** 11 /**
7 * 国标平台的业务类 12 * 国标平台的业务类
8 * @author lin 13 * @author lin
@@ -42,4 +47,10 @@ public interface IPlatformService { @@ -42,4 +47,10 @@ public interface IPlatformService {
42 * @param parentPlatform 47 * @param parentPlatform
43 */ 48 */
44 void login(ParentPlatform parentPlatform); 49 void login(ParentPlatform parentPlatform);
  50 +
  51 + /**
  52 + * 向上级平台发送位置订阅
  53 + * @param platformId 平台
  54 + */
  55 + void sendNotifyMobilePosition(String platformId);
45 } 56 }
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java
@@ -73,7 +73,9 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService { @@ -73,7 +73,9 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
73 result = platformChannelMapper.addChannels(platformId, channelReducesToAdd); 73 result = platformChannelMapper.addChannels(platformId, channelReducesToAdd);
74 // TODO 后续给平台增加控制开关以控制是否响应目录订阅 74 // TODO 后续给平台增加控制开关以控制是否响应目录订阅
75 List<DeviceChannel> deviceChannelList = getDeviceChannelListByChannelReduceList(channelReducesToAdd, catalogId, platform); 75 List<DeviceChannel> deviceChannelList = getDeviceChannelListByChannelReduceList(channelReducesToAdd, catalogId, platform);
76 - eventPublisher.catalogEventPublish(platformId, deviceChannelList, CatalogEvent.ADD); 76 + if (deviceChannelList != null) {
  77 + eventPublisher.catalogEventPublish(platformId, deviceChannelList, CatalogEvent.ADD);
  78 + }
77 } 79 }
78 80
79 return result; 81 return result;
@@ -83,7 +85,7 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService { @@ -83,7 +85,7 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
83 List<DeviceChannel> deviceChannelList = new ArrayList<>(); 85 List<DeviceChannel> deviceChannelList = new ArrayList<>();
84 if (channelReduces.size() > 0){ 86 if (channelReduces.size() > 0){
85 PlatformCatalog catalog = catalogManager.select(catalogId); 87 PlatformCatalog catalog = catalogManager.select(catalogId);
86 - if (catalog == null && !catalogId.equals(platform.getServerGBId())) { 88 + if (catalog == null && !catalogId.equals(platform.getDeviceGBId())) {
87 logger.warn("未查询到目录{}的信息", catalogId); 89 logger.warn("未查询到目录{}的信息", catalogId);
88 return null; 90 return null;
89 } 91 }
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
1 package com.genersoft.iot.vmp.service.impl; 1 package com.genersoft.iot.vmp.service.impl;
2 2
3 import com.genersoft.iot.vmp.conf.DynamicTask; 3 import com.genersoft.iot.vmp.conf.DynamicTask;
4 -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;  
5 -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;  
6 -import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;  
7 -import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; 4 +import com.genersoft.iot.vmp.conf.UserSetting;
  5 +import com.genersoft.iot.vmp.gb28181.bean.*;
8 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 6 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
9 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; 7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
10 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 8 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
11 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 9 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
12 import com.genersoft.iot.vmp.service.IMediaServerService; 10 import com.genersoft.iot.vmp.service.IMediaServerService;
13 import com.genersoft.iot.vmp.service.IPlatformService; 11 import com.genersoft.iot.vmp.service.IPlatformService;
  12 +import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
14 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 13 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  14 +import com.genersoft.iot.vmp.storager.dao.GbStreamMapper;
15 import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; 15 import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper;
16 import com.github.pagehelper.PageHelper; 16 import com.github.pagehelper.PageHelper;
17 import com.github.pagehelper.PageInfo; 17 import com.github.pagehelper.PageInfo;
@@ -57,6 +57,12 @@ public class PlatformServiceImpl implements IPlatformService { @@ -57,6 +57,12 @@ public class PlatformServiceImpl implements IPlatformService {
57 @Autowired 57 @Autowired
58 private SubscribeHolder subscribeHolder; 58 private SubscribeHolder subscribeHolder;
59 59
  60 + @Autowired
  61 + private GbStreamMapper gbStreamMapper;
  62 +
  63 + @Autowired
  64 + private UserSetting userSetting;
  65 +
60 66
61 67
62 @Override 68 @Override
@@ -228,4 +234,34 @@ public class PlatformServiceImpl implements IPlatformService { @@ -228,4 +234,34 @@ public class PlatformServiceImpl implements IPlatformService {
228 60*1000); 234 60*1000);
229 }, null); 235 }, null);
230 } 236 }
  237 +
  238 + @Override
  239 + public void sendNotifyMobilePosition(String platformId) {
  240 + ParentPlatform platform = platformMapper.getParentPlatByServerGBId(platformId);
  241 + if (platform == null) {
  242 + return;
  243 + }
  244 + SubscribeInfo subscribe = subscribeHolder.getMobilePositionSubscribe(platform.getServerGBId());
  245 + if (subscribe != null) {
  246 +
  247 + // TODO 暂时只处理视频流的回复,后续增加对国标设备的支持
  248 + List<DeviceChannel> gbStreams = gbStreamMapper.queryGbStreamListInPlatform(platform.getServerGBId(), userSetting.isUsePushingAsStatus());
  249 + if (gbStreams.size() == 0) {
  250 + return;
  251 + }
  252 + for (DeviceChannel deviceChannel : gbStreams) {
  253 + String gbId = deviceChannel.getChannelId();
  254 + GPSMsgInfo gpsMsgInfo = redisCatchStorage.getGpsMsgInfo(gbId);
  255 + // 无最新位置不发送
  256 + if (gpsMsgInfo != null) {
  257 + // 经纬度都为0不发送
  258 + if (gpsMsgInfo.getLng() == 0 && gpsMsgInfo.getLat() == 0) {
  259 + continue;
  260 + }
  261 + // 发送GPS消息
  262 + commanderForPlatform.sendNotifyMobilePosition(platform, gpsMsgInfo, subscribe);
  263 + }
  264 + }
  265 + }
  266 + }
231 } 267 }
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -177,6 +177,7 @@ public class PlayServiceImpl implements IPlayService { @@ -177,6 +177,7 @@ public class PlayServiceImpl implements IPlayService {
177 } 177 }
178 }); 178 });
179 }); 179 });
  180 +
180 if (streamInfo != null) { 181 if (streamInfo != null) {
181 String streamId = streamInfo.getStream(); 182 String streamId = streamInfo.getStream();
182 if (streamId == null) { 183 if (streamId == null) {
@@ -281,7 +282,7 @@ public class PlayServiceImpl implements IPlayService { @@ -281,7 +282,7 @@ public class PlayServiceImpl implements IPlayService {
281 if (ssrcInfo == null) { 282 if (ssrcInfo == null) {
282 ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, device.isSsrcCheck(), false); 283 ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, device.isSsrcCheck(), false);
283 } 284 }
284 - logger.info("[点播开始] deviceId: {}, channelId: {}, SSRC: {}", device.getDeviceId(), channelId, ssrcInfo.getSsrc() ); 285 + logger.info("[点播开始] deviceId: {}, channelId: {},收流端口: {}, 收流模式:{}, SSRC: {}, SSRC校验:{}", device.getDeviceId(), channelId, ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck() );
285 // 超时处理 286 // 超时处理
286 String timeOutTaskKey = UUID.randomUUID().toString(); 287 String timeOutTaskKey = UUID.randomUUID().toString();
287 SSRCInfo finalSsrcInfo = ssrcInfo; 288 SSRCInfo finalSsrcInfo = ssrcInfo;
@@ -290,12 +291,12 @@ public class PlayServiceImpl implements IPlayService { @@ -290,12 +291,12 @@ public class PlayServiceImpl implements IPlayService {
290 291
291 SIPDialog dialog = streamSession.getDialogByStream(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); 292 SIPDialog dialog = streamSession.getDialogByStream(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
292 if (dialog != null) { 293 if (dialog != null) {
293 - logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {}", device.getDeviceId(), channelId); 294 + logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},端口:{}, SSRC: {}", device.getDeviceId(), channelId, finalSsrcInfo.getPort(), finalSsrcInfo.getSsrc());
294 timeoutCallback.run(1, "收流超时"); 295 timeoutCallback.run(1, "收流超时");
295 // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 296 // 点播超时回复BYE 同时释放ssrc以及此次点播的资源
296 cmder.streamByeCmd(device.getDeviceId(), channelId, finalSsrcInfo.getStream(), null); 297 cmder.streamByeCmd(device.getDeviceId(), channelId, finalSsrcInfo.getStream(), null);
297 }else { 298 }else {
298 - logger.info("[点播超时] 消息未响应 deviceId: {}, channelId: {}", device.getDeviceId(), channelId); 299 + logger.info("[点播超时] 消息未响应 deviceId: {}, channelId: {},端口:{}, SSRC: {}", device.getDeviceId(), channelId, finalSsrcInfo.getPort(), finalSsrcInfo.getSsrc());
299 timeoutCallback.run(0, "点播超时"); 300 timeoutCallback.run(0, "点播超时");
300 mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc()); 301 mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
301 mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream()); 302 mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java renamed to src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java
1 -package com.genersoft.iot.vmp.service.impl; 1 +package com.genersoft.iot.vmp.service.redisMsg;
2 2
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 import com.genersoft.iot.vmp.gb28181.bean.*; 4 import com.genersoft.iot.vmp.gb28181.bean.*;
5 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; 5 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; 6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
7 -import com.genersoft.iot.vmp.service.IPlatformChannelService;  
8 -import com.genersoft.iot.vmp.storager.IRedisCatchStorage;  
9 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 7 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
10 import com.genersoft.iot.vmp.utils.DateUtil; 8 import com.genersoft.iot.vmp.utils.DateUtil;
11 import org.slf4j.Logger; 9 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory; 10 import org.slf4j.LoggerFactory;
13 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.beans.factory.annotation.Autowired;
  12 +import org.springframework.beans.factory.annotation.Qualifier;
14 import org.springframework.data.redis.connection.Message; 13 import org.springframework.data.redis.connection.Message;
15 import org.springframework.data.redis.connection.MessageListener; 14 import org.springframework.data.redis.connection.MessageListener;
  15 +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
16 import org.springframework.stereotype.Component; 16 import org.springframework.stereotype.Component;
17 import org.springframework.util.ObjectUtils; 17 import org.springframework.util.ObjectUtils;
18 18
  19 +import javax.validation.constraints.NotNull;
19 import java.util.List; 20 import java.util.List;
  21 +import java.util.concurrent.ConcurrentLinkedQueue;
20 22
21 23
22 @Component 24 @Component
@@ -33,45 +35,68 @@ public class RedisAlarmMsgListener implements MessageListener { @@ -33,45 +35,68 @@ public class RedisAlarmMsgListener implements MessageListener {
33 @Autowired 35 @Autowired
34 private IVideoManagerStorage storage; 36 private IVideoManagerStorage storage;
35 37
  38 + private boolean taskQueueHandlerRun = false;
  39 +
  40 + private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
  41 +
  42 + @Qualifier("taskExecutor")
  43 + @Autowired
  44 + private ThreadPoolTaskExecutor taskExecutor;
  45 +
36 @Override 46 @Override
37 - public void onMessage(Message message, byte[] bytes) { 47 + public void onMessage(@NotNull Message message, byte[] bytes) {
38 logger.info("收到来自REDIS的ALARM通知: {}", new String(message.getBody())); 48 logger.info("收到来自REDIS的ALARM通知: {}", new String(message.getBody()));
39 - AlarmChannelMessage alarmChannelMessage = JSON.parseObject(message.getBody(), AlarmChannelMessage.class);  
40 - if (alarmChannelMessage == null) {  
41 - logger.warn("[REDIS的ALARM通知]消息解析失败");  
42 - return;  
43 - }  
44 - String gbId = alarmChannelMessage.getGbId();  
45 -  
46 - DeviceAlarm deviceAlarm = new DeviceAlarm();  
47 - deviceAlarm.setCreateTime(DateUtil.getNow());  
48 - deviceAlarm.setChannelId(gbId);  
49 - deviceAlarm.setAlarmDescription(alarmChannelMessage.getAlarmDescription());  
50 - deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn());  
51 - deviceAlarm.setAlarmPriority("1");  
52 - deviceAlarm.setAlarmTime(DateUtil.getNowForISO8601());  
53 - deviceAlarm.setAlarmType("1");  
54 - deviceAlarm.setLongitude(0);  
55 - deviceAlarm.setLatitude(0);  
56 -  
57 - if (ObjectUtils.isEmpty(gbId)) {  
58 - // 发送给所有的上级  
59 - List<ParentPlatform> parentPlatforms = storage.queryEnableParentPlatformList(true);  
60 - if (parentPlatforms.size() > 0) {  
61 - for (ParentPlatform parentPlatform : parentPlatforms) {  
62 - commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm); 49 +
  50 + taskQueue.offer(message);
  51 + if (!taskQueueHandlerRun) {
  52 + taskQueueHandlerRun = true;
  53 + logger.info("[线程池信息]活动线程数:{}, 最大线程数: {}", taskExecutor.getActiveCount(), taskExecutor.getMaxPoolSize());
  54 + taskExecutor.execute(() -> {
  55 + while (!taskQueue.isEmpty()) {
  56 + Message msg = taskQueue.poll();
  57 +
  58 + AlarmChannelMessage alarmChannelMessage = JSON.parseObject(msg.getBody(), AlarmChannelMessage.class);
  59 + if (alarmChannelMessage == null) {
  60 + logger.warn("[REDIS的ALARM通知]消息解析失败");
  61 + continue;
  62 + }
  63 + String gbId = alarmChannelMessage.getGbId();
  64 +
  65 + DeviceAlarm deviceAlarm = new DeviceAlarm();
  66 + deviceAlarm.setCreateTime(DateUtil.getNow());
  67 + deviceAlarm.setChannelId(gbId);
  68 + deviceAlarm.setAlarmDescription(alarmChannelMessage.getAlarmDescription());
  69 + deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn());
  70 + deviceAlarm.setAlarmPriority("1");
  71 + deviceAlarm.setAlarmTime(DateUtil.getNowForISO8601());
  72 + deviceAlarm.setAlarmType("1");
  73 + deviceAlarm.setLongitude(0);
  74 + deviceAlarm.setLatitude(0);
  75 +
  76 + if (ObjectUtils.isEmpty(gbId)) {
  77 + // 发送给所有的上级
  78 + List<ParentPlatform> parentPlatforms = storage.queryEnableParentPlatformList(true);
  79 + if (parentPlatforms.size() > 0) {
  80 + for (ParentPlatform parentPlatform : parentPlatforms) {
  81 + commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm);
  82 + }
  83 + }
  84 + }else {
  85 + Device device = storage.queryVideoDevice(gbId);
  86 + ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId);
  87 + if (device != null && platform == null) {
  88 + commander.sendAlarmMessage(device, deviceAlarm);
  89 + }else if (device == null && platform != null){
  90 + commanderForPlatform.sendAlarmMessage(platform, deviceAlarm);
  91 + }else {
  92 + logger.warn("无法确定" + gbId + "是平台还是设备");
  93 + }
  94 + }
63 } 95 }
64 - }  
65 - }else {  
66 - Device device = storage.queryVideoDevice(gbId);  
67 - ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId);  
68 - if (device != null && platform == null) {  
69 - commander.sendAlarmMessage(device, deviceAlarm);  
70 - }else if (device == null && platform != null){  
71 - commanderForPlatform.sendAlarmMessage(platform, deviceAlarm);  
72 - }else {  
73 - logger.warn("无法确定" + gbId + "是平台还是设备");  
74 - } 96 + taskQueueHandlerRun = false;
  97 + });
75 } 98 }
  99 +
  100 +
76 } 101 }
77 } 102 }
src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java renamed to src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java
1 -package com.genersoft.iot.vmp.service.impl; 1 +package com.genersoft.iot.vmp.service.redisMsg;
2 2
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
@@ -19,14 +19,18 @@ import com.genersoft.iot.vmp.vmanager.bean.WVPResult; @@ -19,14 +19,18 @@ import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
19 import org.slf4j.Logger; 19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory; 20 import org.slf4j.LoggerFactory;
21 import org.springframework.beans.factory.annotation.Autowired; 21 import org.springframework.beans.factory.annotation.Autowired;
  22 +import org.springframework.beans.factory.annotation.Qualifier;
22 import org.springframework.data.redis.connection.Message; 23 import org.springframework.data.redis.connection.Message;
23 import org.springframework.data.redis.connection.MessageListener; 24 import org.springframework.data.redis.connection.MessageListener;
  25 +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
24 import org.springframework.stereotype.Component; 26 import org.springframework.stereotype.Component;
25 27
  28 +import java.text.ParseException;
26 import java.util.HashMap; 29 import java.util.HashMap;
27 import java.util.Map; 30 import java.util.Map;
28 import java.util.UUID; 31 import java.util.UUID;
29 import java.util.concurrent.ConcurrentHashMap; 32 import java.util.concurrent.ConcurrentHashMap;
  33 +import java.util.concurrent.ConcurrentLinkedQueue;
30 34
31 35
32 /** 36 /**
@@ -84,9 +88,17 @@ public class RedisGbPlayMsgListener implements MessageListener { @@ -84,9 +88,17 @@ public class RedisGbPlayMsgListener implements MessageListener {
84 @Autowired 88 @Autowired
85 private ZlmHttpHookSubscribe subscribe; 89 private ZlmHttpHookSubscribe subscribe;
86 90
  91 + private boolean taskQueueHandlerRun = false;
  92 +
  93 + private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
  94 +
  95 + @Qualifier("taskExecutor")
  96 + @Autowired
  97 + private ThreadPoolTaskExecutor taskExecutor;
  98 +
87 99
88 public interface PlayMsgCallback{ 100 public interface PlayMsgCallback{
89 - void handler(ResponseSendItemMsg responseSendItemMsg); 101 + void handler(ResponseSendItemMsg responseSendItemMsg) throws ParseException;
90 } 102 }
91 103
92 public interface PlayMsgCallbackForStartSendRtpStream{ 104 public interface PlayMsgCallbackForStartSendRtpStream{
@@ -99,90 +111,107 @@ public class RedisGbPlayMsgListener implements MessageListener { @@ -99,90 +111,107 @@ public class RedisGbPlayMsgListener implements MessageListener {
99 111
100 @Override 112 @Override
101 public void onMessage(Message message, byte[] bytes) { 113 public void onMessage(Message message, byte[] bytes) {
102 - JSONObject msgJSON = JSON.parseObject(message.getBody(), JSONObject.class);  
103 - WvpRedisMsg wvpRedisMsg = JSON.toJavaObject(msgJSON, WvpRedisMsg.class);  
104 - if (!userSetting.getServerId().equals(wvpRedisMsg.getToId())) {  
105 - return;  
106 - }  
107 - if (WvpRedisMsg.isRequest(wvpRedisMsg)) {  
108 - logger.info("[收到REDIS通知] 请求: {}", new String(message.getBody()));  
109 -  
110 - switch (wvpRedisMsg.getCmd()){  
111 - case WvpRedisMsgCmd.GET_SEND_ITEM:  
112 - RequestSendItemMsg content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestSendItemMsg.class);  
113 - requestSendItemMsgHand(content, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial());  
114 - break;  
115 - case WvpRedisMsgCmd.REQUEST_PUSH_STREAM:  
116 - RequestPushStreamMsg param = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestPushStreamMsg.class);;  
117 - requestPushStreamMsgHand(param, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial());  
118 - break;  
119 - default:  
120 - break;  
121 - }  
122 114
123 - }else {  
124 - logger.info("[收到REDIS通知] 回复: {}", new String(message.getBody()));  
125 - switch (wvpRedisMsg.getCmd()){  
126 - case WvpRedisMsgCmd.GET_SEND_ITEM:  
127 -  
128 - WVPResult content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class);  
129 -  
130 - String key = wvpRedisMsg.getSerial();  
131 - switch (content.getCode()) {  
132 - case 0:  
133 - ResponseSendItemMsg responseSendItemMsg =JSON.toJavaObject((JSONObject)content.getData(), ResponseSendItemMsg.class);  
134 - PlayMsgCallback playMsgCallback = callbacks.get(key);  
135 - if (playMsgCallback != null) {  
136 - callbacksForError.remove(key);  
137 - playMsgCallback.handler(responseSendItemMsg);  
138 - }  
139 - break;  
140 - case ERROR_CODE_MEDIA_SERVER_NOT_FOUND:  
141 - case ERROR_CODE_OFFLINE:  
142 - case ERROR_CODE_TIMEOUT:  
143 - PlayMsgErrorCallback errorCallback = callbacksForError.get(key);  
144 - if (errorCallback != null) {  
145 - callbacks.remove(key);  
146 - errorCallback.handler(content);  
147 - }  
148 - break;  
149 - default:  
150 - break; 115 + taskQueue.offer(message);
  116 + if (!taskQueueHandlerRun) {
  117 + taskQueueHandlerRun = true;
  118 + taskExecutor.execute(() -> {
  119 + while (!taskQueue.isEmpty()) {
  120 + Message msg = taskQueue.poll();
  121 + JSONObject msgJSON = JSON.parseObject(msg.getBody(), JSONObject.class);
  122 + WvpRedisMsg wvpRedisMsg = JSON.toJavaObject(msgJSON, WvpRedisMsg.class);
  123 + if (!userSetting.getServerId().equals(wvpRedisMsg.getToId())) {
  124 + continue;
151 } 125 }
152 - break;  
153 - case WvpRedisMsgCmd.REQUEST_PUSH_STREAM:  
154 - WVPResult wvpResult = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class);  
155 - String serial = wvpRedisMsg.getSerial();  
156 - switch (wvpResult.getCode()) {  
157 - case 0:  
158 - JSONObject jsonObject = (JSONObject)wvpResult.getData();  
159 - PlayMsgCallbackForStartSendRtpStream playMsgCallback = callbacksForStartSendRtpStream.get(serial);  
160 - if (playMsgCallback != null) {  
161 - callbacksForError.remove(serial);  
162 - playMsgCallback.handler(jsonObject);  
163 - }  
164 - break;  
165 - case ERROR_CODE_MEDIA_SERVER_NOT_FOUND:  
166 - case ERROR_CODE_OFFLINE:  
167 - case ERROR_CODE_TIMEOUT:  
168 - PlayMsgErrorCallback errorCallback = callbacksForError.get(serial);  
169 - if (errorCallback != null) {  
170 - callbacks.remove(serial);  
171 - errorCallback.handler(wvpResult);  
172 - }  
173 - break;  
174 - default:  
175 - break; 126 + if (WvpRedisMsg.isRequest(wvpRedisMsg)) {
  127 + logger.info("[收到REDIS通知] 请求: {}", new String(msg.getBody()));
  128 +
  129 + switch (wvpRedisMsg.getCmd()){
  130 + case WvpRedisMsgCmd.GET_SEND_ITEM:
  131 + RequestSendItemMsg content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestSendItemMsg.class);
  132 + requestSendItemMsgHand(content, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial());
  133 + break;
  134 + case WvpRedisMsgCmd.REQUEST_PUSH_STREAM:
  135 + RequestPushStreamMsg param = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestPushStreamMsg.class);;
  136 + requestPushStreamMsgHand(param, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial());
  137 + break;
  138 + default:
  139 + break;
  140 + }
  141 +
  142 + }else {
  143 + logger.info("[收到REDIS通知] 回复: {}", new String(msg.getBody()));
  144 + switch (wvpRedisMsg.getCmd()){
  145 + case WvpRedisMsgCmd.GET_SEND_ITEM:
  146 +
  147 + WVPResult content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class);
  148 +
  149 + String key = wvpRedisMsg.getSerial();
  150 + switch (content.getCode()) {
  151 + case 0:
  152 + ResponseSendItemMsg responseSendItemMsg =JSON.toJavaObject((JSONObject)content.getData(), ResponseSendItemMsg.class);
  153 + PlayMsgCallback playMsgCallback = callbacks.get(key);
  154 + if (playMsgCallback != null) {
  155 + callbacksForError.remove(key);
  156 + try {
  157 + playMsgCallback.handler(responseSendItemMsg);
  158 + } catch (ParseException e) {
  159 + throw new RuntimeException(e);
  160 + }
  161 + }
  162 + break;
  163 + case ERROR_CODE_MEDIA_SERVER_NOT_FOUND:
  164 + case ERROR_CODE_OFFLINE:
  165 + case ERROR_CODE_TIMEOUT:
  166 + PlayMsgErrorCallback errorCallback = callbacksForError.get(key);
  167 + if (errorCallback != null) {
  168 + callbacks.remove(key);
  169 + errorCallback.handler(content);
  170 + }
  171 + break;
  172 + default:
  173 + break;
  174 + }
  175 + break;
  176 + case WvpRedisMsgCmd.REQUEST_PUSH_STREAM:
  177 + WVPResult wvpResult = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class);
  178 + String serial = wvpRedisMsg.getSerial();
  179 + switch (wvpResult.getCode()) {
  180 + case 0:
  181 + JSONObject jsonObject = (JSONObject)wvpResult.getData();
  182 + PlayMsgCallbackForStartSendRtpStream playMsgCallback = callbacksForStartSendRtpStream.get(serial);
  183 + if (playMsgCallback != null) {
  184 + callbacksForError.remove(serial);
  185 + playMsgCallback.handler(jsonObject);
  186 + }
  187 + break;
  188 + case ERROR_CODE_MEDIA_SERVER_NOT_FOUND:
  189 + case ERROR_CODE_OFFLINE:
  190 + case ERROR_CODE_TIMEOUT:
  191 + PlayMsgErrorCallback errorCallback = callbacksForError.get(serial);
  192 + if (errorCallback != null) {
  193 + callbacks.remove(serial);
  194 + errorCallback.handler(wvpResult);
  195 + }
  196 + break;
  197 + default:
  198 + break;
  199 + }
  200 + break;
  201 + default:
  202 + break;
  203 + }
176 } 204 }
177 - break;  
178 - default:  
179 - break;  
180 - } 205 + }
  206 + taskQueueHandlerRun = false;
  207 + });
181 } 208 }
182 209
183 210
184 211
185 212
  213 +
  214 +
186 } 215 }
187 216
188 /** 217 /**
src/main/java/com/genersoft/iot/vmp/service/impl/RedisGpsMsgListener.java renamed to src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGpsMsgListener.java
1 -package com.genersoft.iot.vmp.service.impl; 1 +package com.genersoft.iot.vmp.service.redisMsg;
2 2
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 -import com.genersoft.iot.vmp.gb28181.bean.HandlerCatchData;  
5 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; 4 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
6 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 5 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
7 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 6 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
@@ -36,7 +35,7 @@ public class RedisGpsMsgListener implements MessageListener { @@ -36,7 +35,7 @@ public class RedisGpsMsgListener implements MessageListener {
36 @Autowired 35 @Autowired
37 private IVideoManagerStorage storager; 36 private IVideoManagerStorage storager;
38 37
39 - private final ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>(); 38 + private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
40 39
41 @Qualifier("taskExecutor") 40 @Qualifier("taskExecutor")
42 @Autowired 41 @Autowired
src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamResponseListener.java renamed to src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamResponseListener.java
1 -package com.genersoft.iot.vmp.service.impl; 1 +package com.genersoft.iot.vmp.service.redisMsg;
2 2
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 -import com.alibaba.fastjson.JSONObject;  
5 -import com.genersoft.iot.vmp.media.zlm.dto.ChannelOnlineEvent;  
6 -import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;  
7 -import com.genersoft.iot.vmp.service.IGbStreamService;  
8 -import com.genersoft.iot.vmp.service.IMediaServerService;  
9 -import com.genersoft.iot.vmp.service.IStreamPushService; 4 +import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
10 import com.genersoft.iot.vmp.service.bean.MessageForPushChannelResponse; 5 import com.genersoft.iot.vmp.service.bean.MessageForPushChannelResponse;
11 -import com.genersoft.iot.vmp.utils.DateUtil;  
12 import org.slf4j.Logger; 6 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory; 7 import org.slf4j.LoggerFactory;
  8 +import org.springframework.beans.factory.annotation.Autowired;
  9 +import org.springframework.beans.factory.annotation.Qualifier;
14 import org.springframework.data.redis.connection.Message; 10 import org.springframework.data.redis.connection.Message;
15 import org.springframework.data.redis.connection.MessageListener; 11 import org.springframework.data.redis.connection.MessageListener;
  12 +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
16 import org.springframework.stereotype.Component; 13 import org.springframework.stereotype.Component;
17 import org.springframework.util.ObjectUtils; 14 import org.springframework.util.ObjectUtils;
18 15
19 -import javax.annotation.Resource;  
20 -import java.util.ArrayList;  
21 -import java.util.List;  
22 import java.util.Map; 16 import java.util.Map;
23 import java.util.concurrent.ConcurrentHashMap; 17 import java.util.concurrent.ConcurrentHashMap;
  18 +import java.util.concurrent.ConcurrentLinkedQueue;
24 19
25 /** 20 /**
26 * 接收redis返回的推流结果 21 * 接收redis返回的推流结果
@@ -31,6 +26,15 @@ public class RedisPushStreamResponseListener implements MessageListener { @@ -31,6 +26,15 @@ public class RedisPushStreamResponseListener implements MessageListener {
31 26
32 private final static Logger logger = LoggerFactory.getLogger(RedisPushStreamResponseListener.class); 27 private final static Logger logger = LoggerFactory.getLogger(RedisPushStreamResponseListener.class);
33 28
  29 + private boolean taskQueueHandlerRun = false;
  30 +
  31 + private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
  32 +
  33 + @Qualifier("taskExecutor")
  34 + @Autowired
  35 + private ThreadPoolTaskExecutor taskExecutor;
  36 +
  37 +
34 private Map<String, PushStreamResponseEvent> responseEvents = new ConcurrentHashMap<>(); 38 private Map<String, PushStreamResponseEvent> responseEvents = new ConcurrentHashMap<>();
35 39
36 public interface PushStreamResponseEvent{ 40 public interface PushStreamResponseEvent{
@@ -39,16 +43,25 @@ public class RedisPushStreamResponseListener implements MessageListener { @@ -39,16 +43,25 @@ public class RedisPushStreamResponseListener implements MessageListener {
39 43
40 @Override 44 @Override
41 public void onMessage(Message message, byte[] bytes) { 45 public void onMessage(Message message, byte[] bytes) {
42 - //  
43 logger.warn("[REDIS消息-请求推流结果]: {}", new String(message.getBody())); 46 logger.warn("[REDIS消息-请求推流结果]: {}", new String(message.getBody()));
44 - MessageForPushChannelResponse response = JSON.parseObject(new String(message.getBody()), MessageForPushChannelResponse.class);  
45 - if (response == null || ObjectUtils.isEmpty(response.getApp()) || ObjectUtils.isEmpty(response.getStream())){  
46 - logger.info("[REDIS消息-请求推流结果]:参数不全");  
47 - return;  
48 - }  
49 - // 查看正在等待的invite消息  
50 - if (responseEvents.get(response.getApp() + response.getStream()) != null) {  
51 - responseEvents.get(response.getApp() + response.getStream()).run(response); 47 + taskQueue.offer(message);
  48 + if (!taskQueueHandlerRun) {
  49 + taskQueueHandlerRun = true;
  50 + taskExecutor.execute(() -> {
  51 + while (!taskQueue.isEmpty()) {
  52 + Message msg = taskQueue.poll();
  53 + MessageForPushChannelResponse response = JSON.parseObject(new String(msg.getBody()), MessageForPushChannelResponse.class);
  54 + if (response == null || ObjectUtils.isEmpty(response.getApp()) || ObjectUtils.isEmpty(response.getStream())){
  55 + logger.info("[REDIS消息-请求推流结果]:参数不全");
  56 + continue;
  57 + }
  58 + // 查看正在等待的invite消息
  59 + if (responseEvents.get(response.getApp() + response.getStream()) != null) {
  60 + responseEvents.get(response.getApp() + response.getStream()).run(response);
  61 + }
  62 + }
  63 + taskQueueHandlerRun = false;
  64 + });
52 } 65 }
53 } 66 }
54 67
src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamStatusListMsgListener.java renamed to src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java
1 -package com.genersoft.iot.vmp.service.impl; 1 +package com.genersoft.iot.vmp.service.redisMsg;
2 2
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
@@ -6,15 +6,20 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; @@ -6,15 +6,20 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
6 import com.genersoft.iot.vmp.service.IGbStreamService; 6 import com.genersoft.iot.vmp.service.IGbStreamService;
7 import com.genersoft.iot.vmp.service.IMediaServerService; 7 import com.genersoft.iot.vmp.service.IMediaServerService;
8 import com.genersoft.iot.vmp.service.IStreamPushService; 8 import com.genersoft.iot.vmp.service.IStreamPushService;
  9 +import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
9 import com.genersoft.iot.vmp.utils.DateUtil; 10 import com.genersoft.iot.vmp.utils.DateUtil;
10 import org.slf4j.Logger; 11 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 12 import org.slf4j.LoggerFactory;
  13 +import org.springframework.beans.factory.annotation.Autowired;
  14 +import org.springframework.beans.factory.annotation.Qualifier;
12 import org.springframework.data.redis.connection.Message; 15 import org.springframework.data.redis.connection.Message;
13 import org.springframework.data.redis.connection.MessageListener; 16 import org.springframework.data.redis.connection.MessageListener;
  17 +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
14 import org.springframework.stereotype.Component; 18 import org.springframework.stereotype.Component;
15 19
16 import javax.annotation.Resource; 20 import javax.annotation.Resource;
17 import java.util.*; 21 import java.util.*;
  22 +import java.util.concurrent.ConcurrentLinkedQueue;
18 23
19 /** 24 /**
20 * @Auther: JiangFeng 25 * @Auther: JiangFeng
@@ -33,49 +38,66 @@ public class RedisPushStreamStatusListMsgListener implements MessageListener { @@ -33,49 +38,66 @@ public class RedisPushStreamStatusListMsgListener implements MessageListener {
33 @Resource 38 @Resource
34 private IGbStreamService gbStreamService; 39 private IGbStreamService gbStreamService;
35 40
  41 + private boolean taskQueueHandlerRun = false;
  42 +
  43 + private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
  44 +
  45 + @Qualifier("taskExecutor")
  46 + @Autowired
  47 + private ThreadPoolTaskExecutor taskExecutor;
  48 +
36 @Override 49 @Override
37 public void onMessage(Message message, byte[] bytes) { 50 public void onMessage(Message message, byte[] bytes) {
38 - //  
39 - logger.warn("[REDIS消息-推流设备列表更新]: {}", new String(message.getBody()));  
40 - List<StreamPushItem> streamPushItems = JSON.parseArray(new String(message.getBody()), StreamPushItem.class);  
41 - //查询全部的app+stream 用于判断是添加还是修改  
42 - List<String> allAppAndStream = streamPushService.getAllAppAndStream(); 51 + logger.info("[REDIS消息-推流设备列表更新]: {}", new String(message.getBody()));
43 52
44 - /**  
45 - * 用于存储更具APP+Stream过滤后的数据,可以直接存入stream_push表与gb_stream表  
46 - */  
47 - List<StreamPushItem> streamPushItemForSave = new ArrayList<>();  
48 - List<StreamPushItem> streamPushItemForUpdate = new ArrayList<>();  
49 - for (StreamPushItem streamPushItem : streamPushItems) {  
50 - String app = streamPushItem.getApp();  
51 - String stream = streamPushItem.getStream();  
52 - boolean contains = allAppAndStream.contains(app + stream);  
53 - //不存在就添加  
54 - if (!contains) {  
55 - streamPushItem.setStreamType("push");  
56 - streamPushItem.setCreateTime(DateUtil.getNow());  
57 - streamPushItem.setMediaServerId(mediaServerService.getDefaultMediaServer().getId());  
58 - streamPushItem.setOriginType(2);  
59 - streamPushItem.setOriginTypeStr("rtsp_push");  
60 - streamPushItem.setTotalReaderCount("0");  
61 - streamPushItemForSave.add(streamPushItem);  
62 - } else {  
63 - //存在就只修改 name和gbId  
64 - streamPushItemForUpdate.add(streamPushItem);  
65 - }  
66 - }  
67 - if (streamPushItemForSave.size() > 0) { 53 + taskQueue.offer(message);
  54 + if (!taskQueueHandlerRun) {
  55 + taskQueueHandlerRun = true;
  56 + taskExecutor.execute(() -> {
  57 + while (!taskQueue.isEmpty()) {
  58 + Message msg = taskQueue.poll();
  59 + List<StreamPushItem> streamPushItems = JSON.parseArray(new String(msg.getBody()), StreamPushItem.class);
  60 + //查询全部的app+stream 用于判断是添加还是修改
  61 + List<String> allAppAndStream = streamPushService.getAllAppAndStream();
68 62
69 - logger.info("添加{}条",streamPushItemForSave.size());  
70 - logger.info(JSONObject.toJSONString(streamPushItemForSave));  
71 - streamPushService.batchAdd(streamPushItemForSave); 63 + /**
  64 + * 用于存储更具APP+Stream过滤后的数据,可以直接存入stream_push表与gb_stream表
  65 + */
  66 + List<StreamPushItem> streamPushItemForSave = new ArrayList<>();
  67 + List<StreamPushItem> streamPushItemForUpdate = new ArrayList<>();
  68 + for (StreamPushItem streamPushItem : streamPushItems) {
  69 + String app = streamPushItem.getApp();
  70 + String stream = streamPushItem.getStream();
  71 + boolean contains = allAppAndStream.contains(app + stream);
  72 + //不存在就添加
  73 + if (!contains) {
  74 + streamPushItem.setStreamType("push");
  75 + streamPushItem.setCreateTime(DateUtil.getNow());
  76 + streamPushItem.setMediaServerId(mediaServerService.getDefaultMediaServer().getId());
  77 + streamPushItem.setOriginType(2);
  78 + streamPushItem.setOriginTypeStr("rtsp_push");
  79 + streamPushItem.setTotalReaderCount("0");
  80 + streamPushItemForSave.add(streamPushItem);
  81 + } else {
  82 + //存在就只修改 name和gbId
  83 + streamPushItemForUpdate.add(streamPushItem);
  84 + }
  85 + }
  86 + if (streamPushItemForSave.size() > 0) {
72 87
73 - }  
74 - if(streamPushItemForUpdate.size()>0){  
75 - logger.info("修改{}条",streamPushItemForUpdate.size());  
76 - logger.info(JSONObject.toJSONString(streamPushItemForUpdate));  
77 - gbStreamService.updateGbIdOrName(streamPushItemForUpdate);  
78 - } 88 + logger.info("添加{}条",streamPushItemForSave.size());
  89 + logger.info(JSONObject.toJSONString(streamPushItemForSave));
  90 + streamPushService.batchAdd(streamPushItemForSave);
79 91
  92 + }
  93 + if(streamPushItemForUpdate.size()>0){
  94 + logger.info("修改{}条",streamPushItemForUpdate.size());
  95 + logger.info(JSONObject.toJSONString(streamPushItemForUpdate));
  96 + gbStreamService.updateGbIdOrName(streamPushItemForUpdate);
  97 + }
  98 + }
  99 + taskQueueHandlerRun = false;
  100 + });
  101 + }
80 } 102 }
81 } 103 }