Commit 91bfbc36f10382434a9e8c79eeeaf07a531b08b5

Authored by 648540858
1 parent 58d1f0ea

优化设备注册,支持到期续订,优化国标级联到期续订。

Showing 19 changed files with 205 additions and 90 deletions
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 11
12 <groupId>com.genersoft</groupId> 12 <groupId>com.genersoft</groupId>
13 <artifactId>wvp-pro</artifactId> 13 <artifactId>wvp-pro</artifactId>
14 - <version>2.6.7</version> 14 + <version>2.6.8</version>
15 <name>web video platform</name> 15 <name>web video platform</name>
16 <description>国标28181视频平台</description> 16 <description>国标28181视频平台</description>
17 <packaging>${project.packaging}</packaging> 17 <packaging>${project.packaging}</packaging>
src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
@@ -40,17 +40,20 @@ public class SipPlatformRunner implements CommandLineRunner { @@ -40,17 +40,20 @@ public class SipPlatformRunner implements CommandLineRunner {
40 List<ParentPlatform> parentPlatforms = storager.queryEnableParentPlatformList(true); 40 List<ParentPlatform> parentPlatforms = storager.queryEnableParentPlatformList(true);
41 41
42 for (ParentPlatform parentPlatform : parentPlatforms) { 42 for (ParentPlatform parentPlatform : parentPlatforms) {
  43 +
  44 + ParentPlatformCatch parentPlatformCatchOld = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId());
  45 +
43 // 更新缓存 46 // 更新缓存
44 ParentPlatformCatch parentPlatformCatch = new ParentPlatformCatch(); 47 ParentPlatformCatch parentPlatformCatch = new ParentPlatformCatch();
45 parentPlatformCatch.setParentPlatform(parentPlatform); 48 parentPlatformCatch.setParentPlatform(parentPlatform);
46 parentPlatformCatch.setId(parentPlatform.getServerGBId()); 49 parentPlatformCatch.setId(parentPlatform.getServerGBId());
47 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); 50 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
48 - // 设置所有平台离线  
49 - platformService.offline(parentPlatform, true);  
50 // 取消订阅 51 // 取消订阅
51 - sipCommanderForPlatform.unregister(parentPlatform, null, (eventResult)->{ 52 + sipCommanderForPlatform.unregister(parentPlatform, parentPlatformCatchOld.getSipTransactionInfo(), null, (eventResult)->{
52 platformService.login(parentPlatform); 53 platformService.login(parentPlatform);
53 }); 54 });
  55 + // 设置所有平台离线
  56 + platformService.offline(parentPlatform, true);
54 } 57 }
55 } 58 }
56 } 59 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
@@ -191,6 +191,9 @@ public class Device { @@ -191,6 +191,9 @@ public class Device {
191 @Schema(description = "是否作为消息通道") 191 @Schema(description = "是否作为消息通道")
192 private boolean asMessageChannel; 192 private boolean asMessageChannel;
193 193
  194 + @Schema(description = "设备注册的事务信息")
  195 + private SipTransactionInfo sipTransactionInfo;
  196 +
194 197
195 public String getDeviceId() { 198 public String getDeviceId() {
196 return deviceId; 199 return deviceId;
@@ -439,4 +442,12 @@ public class Device { @@ -439,4 +442,12 @@ public class Device {
439 public void setAsMessageChannel(boolean asMessageChannel) { 442 public void setAsMessageChannel(boolean asMessageChannel) {
440 this.asMessageChannel = asMessageChannel; 443 this.asMessageChannel = asMessageChannel;
441 } 444 }
  445 +
  446 + public SipTransactionInfo getSipTransactionInfo() {
  447 + return sipTransactionInfo;
  448 + }
  449 +
  450 + public void setSipTransactionInfo(SipTransactionInfo sipTransactionInfo) {
  451 + this.sipTransactionInfo = sipTransactionInfo;
  452 + }
442 } 453 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java
@@ -16,6 +16,8 @@ public class ParentPlatformCatch { @@ -16,6 +16,8 @@ public class ParentPlatformCatch {
16 16
17 private ParentPlatform parentPlatform; 17 private ParentPlatform parentPlatform;
18 18
  19 + private SipTransactionInfo sipTransactionInfo;
  20 +
19 public String getId() { 21 public String getId() {
20 return id; 22 return id;
21 } 23 }
@@ -55,4 +57,12 @@ public class ParentPlatformCatch { @@ -55,4 +57,12 @@ public class ParentPlatformCatch {
55 public void setCallId(String callId) { 57 public void setCallId(String callId) {
56 this.callId = callId; 58 this.callId = callId;
57 } 59 }
  60 +
  61 + public SipTransactionInfo getSipTransactionInfo() {
  62 + return sipTransactionInfo;
  63 + }
  64 +
  65 + public void setSipTransactionInfo(SipTransactionInfo sipTransactionInfo) {
  66 + this.sipTransactionInfo = sipTransactionInfo;
  67 + }
58 } 68 }
src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java
@@ -63,7 +63,7 @@ public class SipRunner implements CommandLineRunner { @@ -63,7 +63,7 @@ public class SipRunner implements CommandLineRunner {
63 if (deviceService.expire(device)){ 63 if (deviceService.expire(device)){
64 deviceService.offline(device.getDeviceId(), "注册已过期"); 64 deviceService.offline(device.getDeviceId(), "注册已过期");
65 }else { 65 }else {
66 - deviceService.online(device); 66 + deviceService.online(device, null);
67 } 67 }
68 } 68 }
69 // 重置cseq计数 69 // 重置cseq计数
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
@@ -18,14 +18,16 @@ public interface ISIPCommanderForPlatform { @@ -18,14 +18,16 @@ public interface ISIPCommanderForPlatform {
18 * @return 18 * @return
19 */ 19 */
20 void register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException; 20 void register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException;
21 - void register(ParentPlatform parentPlatform, String callId, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) throws SipException, InvalidArgumentException, ParseException; 21 +
  22 + void register(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException;
  23 + void register(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) throws SipException, InvalidArgumentException, ParseException;
22 24
23 /** 25 /**
24 * 向上级平台注销 26 * 向上级平台注销
25 * @param parentPlatform 27 * @param parentPlatform
26 * @return 28 * @return
27 */ 29 */
28 - void unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException; 30 + void unregister(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException;
29 31
30 32
31 /** 33 /**
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
@@ -14,7 +14,8 @@ import org.springframework.beans.factory.annotation.Autowired; @@ -14,7 +14,8 @@ import org.springframework.beans.factory.annotation.Autowired;
14 import org.springframework.stereotype.Component; 14 import org.springframework.stereotype.Component;
15 import org.springframework.util.DigestUtils; 15 import org.springframework.util.DigestUtils;
16 16
17 -import javax.sip.*; 17 +import javax.sip.InvalidArgumentException;
  18 +import javax.sip.PeerUnavailableException;
18 import javax.sip.address.Address; 19 import javax.sip.address.Address;
19 import javax.sip.address.SipURI; 20 import javax.sip.address.SipURI;
20 import javax.sip.header.*; 21 import javax.sip.header.*;
@@ -22,7 +23,6 @@ import javax.sip.message.Request; @@ -22,7 +23,6 @@ import javax.sip.message.Request;
22 import javax.validation.constraints.NotNull; 23 import javax.validation.constraints.NotNull;
23 import java.text.ParseException; 24 import java.text.ParseException;
24 import java.util.ArrayList; 25 import java.util.ArrayList;
25 -import java.util.List;  
26 import java.util.UUID; 26 import java.util.UUID;
27 27
28 /** 28 /**
@@ -45,7 +45,7 @@ public class SIPRequestHeaderPlarformProvider { @@ -45,7 +45,7 @@ public class SIPRequestHeaderPlarformProvider {
45 @Autowired 45 @Autowired
46 private IRedisCatchStorage redisCatchStorage; 46 private IRedisCatchStorage redisCatchStorage;
47 47
48 - public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, long CSeq, String fromTag, String viaTag, CallIdHeader callIdHeader, boolean isRegister) throws ParseException, InvalidArgumentException, PeerUnavailableException { 48 + public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, long CSeq, String fromTag, String toTag, CallIdHeader callIdHeader, boolean isRegister) throws ParseException, InvalidArgumentException, PeerUnavailableException {
49 Request request = null; 49 Request request = null;
50 String sipAddress = parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort(); 50 String sipAddress = parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort();
51 //请求行 51 //请求行
@@ -53,7 +53,8 @@ public class SIPRequestHeaderPlarformProvider { @@ -53,7 +53,8 @@ public class SIPRequestHeaderPlarformProvider {
53 parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); 53 parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());
54 //via 54 //via
55 ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); 55 ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
56 - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(parentPlatform.getServerIP(), parentPlatform.getServerPort(), parentPlatform.getTransport(), viaTag); 56 + ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(parentPlatform.getServerIP(),
  57 + parentPlatform.getServerPort(), parentPlatform.getTransport(), SipUtils.getNewViaTag());
57 viaHeader.setRPort(); 58 viaHeader.setRPort();
58 viaHeaders.add(viaHeader); 59 viaHeaders.add(viaHeader);
59 //from 60 //from
@@ -63,7 +64,7 @@ public class SIPRequestHeaderPlarformProvider { @@ -63,7 +64,7 @@ public class SIPRequestHeaderPlarformProvider {
63 //to 64 //to
64 SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), sipConfig.getDomain()); 65 SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), sipConfig.getDomain());
65 Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); 66 Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI);
66 - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress,null); 67 + ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress,toTag);
67 68
68 //Forwards 69 //Forwards
69 MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); 70 MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70);
@@ -85,11 +86,11 @@ public class SIPRequestHeaderPlarformProvider { @@ -85,11 +86,11 @@ public class SIPRequestHeaderPlarformProvider {
85 return request; 86 return request;
86 } 87 }
87 88
88 - public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, String fromTag, String viaTag,  
89 - String callId, WWWAuthenticateHeader www , CallIdHeader callIdHeader, boolean isRegister) throws ParseException, PeerUnavailableException, InvalidArgumentException { 89 + public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, String fromTag, String toTag,
  90 + WWWAuthenticateHeader www , CallIdHeader callIdHeader, boolean isRegister) throws ParseException, PeerUnavailableException, InvalidArgumentException {
90 91
91 92
92 - Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(), fromTag, viaTag, callIdHeader, isRegister); 93 + Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(), fromTag, toTag, callIdHeader, isRegister);
93 SipURI requestURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); 94 SipURI requestURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());
94 if (www == null) { 95 if (www == null) {
95 AuthorizationHeader authorizationHeader = sipLayer.getSipFactory().createHeaderFactory().createAuthorizationHeader("Digest"); 96 AuthorizationHeader authorizationHeader = sipLayer.getSipFactory().createHeaderFactory().createAuthorizationHeader("Digest");
@@ -107,8 +108,6 @@ public class SIPRequestHeaderPlarformProvider { @@ -107,8 +108,6 @@ public class SIPRequestHeaderPlarformProvider {
107 // qop 保护质量 包含auth(默认的)和auth-int(增加了报文完整性检测)两种策略 108 // qop 保护质量 包含auth(默认的)和auth-int(增加了报文完整性检测)两种策略
108 String qop = www.getQop(); 109 String qop = www.getQop();
109 110
110 - callIdHeader.setCallId(callId);  
111 -  
112 String cNonce = null; 111 String cNonce = null;
113 String nc = "00000001"; 112 String nc = "00000001";
114 if (qop != null) { 113 if (qop != null) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
@@ -75,20 +75,40 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -75,20 +75,40 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
75 } 75 }
76 76
77 @Override 77 @Override
78 - public void unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException {  
79 - register(parentPlatform, null, null, errorEvent, okEvent, false, false); 78 + public void register(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException {
  79 +
  80 + register(parentPlatform, sipTransactionInfo, null, errorEvent, okEvent, false, true);
  81 + }
  82 +
  83 + @Override
  84 + public void unregister(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException {
  85 + register(parentPlatform, sipTransactionInfo, null, errorEvent, okEvent, false, false);
80 } 86 }
81 87
82 @Override 88 @Override
83 - public void register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable WWWAuthenticateHeader www, 89 + public void register(ParentPlatform parentPlatform, @Nullable SipTransactionInfo sipTransactionInfo, @Nullable WWWAuthenticateHeader www,
84 SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) throws SipException, InvalidArgumentException, ParseException { 90 SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) throws SipException, InvalidArgumentException, ParseException {
85 Request request; 91 Request request;
86 - if (!registerAgain ) {  
87 - CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());  
88 92
  93 + CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());
  94 + String fromTag = SipUtils.getNewFromTag();
  95 + String toTag = null;
  96 + if (sipTransactionInfo != null ) {
  97 + if (sipTransactionInfo.getCallId() != null) {
  98 + callIdHeader.setCallId(sipTransactionInfo.getCallId());
  99 + }
  100 + if (sipTransactionInfo.getFromTag() != null) {
  101 + fromTag = sipTransactionInfo.getFromTag();
  102 + }
  103 + if (sipTransactionInfo.getToTag() != null) {
  104 + toTag = sipTransactionInfo.getToTag();
  105 + }
  106 + }
  107 +
  108 + if (!registerAgain ) {
89 request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform, 109 request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform,
90 - redisCatchStorage.getCSEQ(), SipUtils.getNewFromTag(),  
91 - SipUtils.getNewViaTag(), callIdHeader, isRegister); 110 + redisCatchStorage.getCSEQ(), fromTag,
  111 + toTag, callIdHeader, isRegister);
92 // 将 callid 写入缓存, 等注册成功可以更新状态 112 // 将 callid 写入缓存, 等注册成功可以更新状态
93 String callIdFromHeader = callIdHeader.getCallId(); 113 String callIdFromHeader = callIdHeader.getCallId();
94 redisCatchStorage.updatePlatformRegisterInfo(callIdFromHeader, PlatformRegisterInfo.getInstance(parentPlatform.getServerGBId(), isRegister)); 114 redisCatchStorage.updatePlatformRegisterInfo(callIdFromHeader, PlatformRegisterInfo.getInstance(parentPlatform.getServerGBId(), isRegister));
@@ -106,8 +126,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -106,8 +126,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
106 }); 126 });
107 127
108 }else { 128 }else {
109 - CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());  
110 - request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform, SipUtils.getNewFromTag(), null, callId, www, callIdHeader, isRegister); 129 + request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform, fromTag, toTag, www, callIdHeader, isRegister);
111 } 130 }
112 131
113 sipSender.transmitRequest(parentPlatform.getDeviceIp(), request, null, okEvent); 132 sipSender.transmitRequest(parentPlatform.getDeviceIp(), request, null, okEvent);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
@@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.conf.UserSetting; @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.conf.UserSetting;
5 import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper; 5 import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
6 import com.genersoft.iot.vmp.gb28181.bean.Device; 6 import com.genersoft.iot.vmp.gb28181.bean.Device;
7 import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; 7 import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo;
  8 +import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
8 import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate; 9 import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate;
9 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; 10 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
10 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; 11 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
@@ -18,6 +19,7 @@ import gov.nist.javax.sip.address.AddressImpl; @@ -18,6 +19,7 @@ import gov.nist.javax.sip.address.AddressImpl;
18 import gov.nist.javax.sip.address.SipUri; 19 import gov.nist.javax.sip.address.SipUri;
19 import gov.nist.javax.sip.header.SIPDateHeader; 20 import gov.nist.javax.sip.header.SIPDateHeader;
20 import gov.nist.javax.sip.message.SIPRequest; 21 import gov.nist.javax.sip.message.SIPRequest;
  22 +import gov.nist.javax.sip.message.SIPResponse;
21 import org.slf4j.Logger; 23 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory; 24 import org.slf4j.LoggerFactory;
23 import org.springframework.beans.factory.InitializingBean; 25 import org.springframework.beans.factory.InitializingBean;
@@ -31,6 +33,7 @@ import javax.sip.header.AuthorizationHeader; @@ -31,6 +33,7 @@ import javax.sip.header.AuthorizationHeader;
31 import javax.sip.header.ContactHeader; 33 import javax.sip.header.ContactHeader;
32 import javax.sip.header.FromHeader; 34 import javax.sip.header.FromHeader;
33 import javax.sip.header.ViaHeader; 35 import javax.sip.header.ViaHeader;
  36 +import javax.sip.message.Request;
34 import javax.sip.message.Response; 37 import javax.sip.message.Response;
35 import java.security.NoSuchAlgorithmException; 38 import java.security.NoSuchAlgorithmException;
36 import java.text.ParseException; 39 import java.text.ParseException;
@@ -102,6 +105,30 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @@ -102,6 +105,30 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
102 SipUri uri = (SipUri) address.getURI(); 105 SipUri uri = (SipUri) address.getURI();
103 String deviceId = uri.getUser(); 106 String deviceId = uri.getUser();
104 Device device = deviceService.getDevice(deviceId); 107 Device device = deviceService.getDevice(deviceId);
  108 +
  109 + RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request,
  110 + userSetting.getSipUseSourceIpAsRemoteAddress());
  111 +
  112 + if (device != null &&
  113 + device.getSipTransactionInfo() != null &&
  114 + request.getCallIdHeader().getCallId().equals(device.getSipTransactionInfo().getCallId())) {
  115 + logger.info("[注册请求] 注册续订: {}", device.getDeviceId());
  116 + device.setExpires(request.getExpires().getExpires());
  117 + device.setIp(remoteAddressInfo.getIp());
  118 + device.setPort(remoteAddressInfo.getPort());
  119 + device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort())));
  120 + device.setLocalIp(request.getLocalAddress().getHostAddress());
  121 + Response registerOkResponse = getRegisterOkResponse(request);
  122 + // 判断TCP还是UDP
  123 + ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
  124 + String transport = reqViaHeader.getTransport();
  125 + device.setTransport("TCP".equalsIgnoreCase(transport) ? "TCP" : "UDP");
  126 + sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), registerOkResponse);
  127 + device.setRegisterTime(DateUtil.getNow());
  128 + SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)registerOkResponse);
  129 + deviceService.online(device, sipTransactionInfo);
  130 + return;
  131 + }
105 String password = (device != null && !ObjectUtils.isEmpty(device.getPassword()))? device.getPassword() : sipConfig.getPassword(); 132 String password = (device != null && !ObjectUtils.isEmpty(device.getPassword()))? device.getPassword() : sipConfig.getPassword();
106 AuthorizationHeader authHead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); 133 AuthorizationHeader authHead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME);
107 if (authHead == null && !ObjectUtils.isEmpty(password)) { 134 if (authHead == null && !ObjectUtils.isEmpty(password)) {
@@ -144,9 +171,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @@ -144,9 +171,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
144 // 添加Expires头 171 // 添加Expires头
145 response.addHeader(request.getExpires()); 172 response.addHeader(request.getExpires());
146 173
147 - RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request,  
148 - userSetting.getSipUseSourceIpAsRemoteAddress());  
149 -  
150 if (device == null) { 174 if (device == null) {
151 device = new Device(); 175 device = new Device();
152 device.setStreamMode("UDP"); 176 device.setStreamMode("UDP");
@@ -179,7 +203,8 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @@ -179,7 +203,8 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
179 if (registerFlag) { 203 if (registerFlag) {
180 logger.info("[注册成功] deviceId: {}->{}", deviceId, requestAddress); 204 logger.info("[注册成功] deviceId: {}->{}", deviceId, requestAddress);
181 device.setRegisterTime(DateUtil.getNow()); 205 device.setRegisterTime(DateUtil.getNow());
182 - deviceService.online(device); 206 + SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response);
  207 + deviceService.online(device, sipTransactionInfo);
183 } else { 208 } else {
184 logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); 209 logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress);
185 deviceService.offline(deviceId, "主动注销"); 210 deviceService.offline(deviceId, "主动注销");
@@ -188,4 +213,23 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @@ -188,4 +213,23 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
188 logger.error("未处理的异常 ", e); 213 logger.error("未处理的异常 ", e);
189 } 214 }
190 } 215 }
  216 +
  217 + private Response getRegisterOkResponse(Request request) throws ParseException {
  218 + // 携带授权头并且密码正确
  219 + Response response = getMessageFactory().createResponse(Response.OK, request);
  220 + // 添加date头
  221 + SIPDateHeader dateHeader = new SIPDateHeader();
  222 + // 使用自己修改的
  223 + WvpSipDate wvpSipDate = new WvpSipDate(Calendar.getInstance(Locale.ENGLISH).getTimeInMillis());
  224 + dateHeader.setDate(wvpSipDate);
  225 + response.addHeader(dateHeader);
  226 +
  227 + // 添加Contact头
  228 + response.addHeader(request.getHeader(ContactHeader.NAME));
  229 + // 添加Expires头
  230 + response.addHeader(request.getExpires());
  231 +
  232 + return response;
  233 +
  234 + }
191 } 235 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/control/cmd/DeviceControlQueryMessageHandler.java
@@ -73,35 +73,38 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent @@ -73,35 +73,38 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
73 String channelId = getText(rootElement, "DeviceID"); 73 String channelId = getText(rootElement, "DeviceID");
74 // 远程启动功能 74 // 远程启动功能
75 if (!ObjectUtils.isEmpty(getText(rootElement, "TeleBoot"))) { 75 if (!ObjectUtils.isEmpty(getText(rootElement, "TeleBoot"))) {
76 - if (parentPlatform.getServerGBId().equals(targetGBId)) {  
77 - // 远程启动本平台:需要在重新启动程序后先对SipStack解绑  
78 - logger.info("执行远程启动本平台命令");  
79 - try {  
80 - cmderFroPlatform.unregister(parentPlatform, null, null);  
81 - } catch (InvalidArgumentException | ParseException | SipException e) {  
82 - logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage());  
83 - }  
84 - taskExecutor.execute(() -> {  
85 - // 远程启动  
86 -// try {  
87 -// Thread.sleep(3000);  
88 -// SipProvider up = (SipProvider) SpringBeanFactory.getBean("udpSipProvider");  
89 -// SipStackImpl stack = (SipStackImpl)up.getSipStack();  
90 -// stack.stop();  
91 -// Iterator listener = stack.getListeningPoints();  
92 -// while (listener.hasNext()) {  
93 -// stack.deleteListeningPoint((ListeningPoint) listener.next());  
94 -// }  
95 -// Iterator providers = stack.getSipProviders();  
96 -// while (providers.hasNext()) {  
97 -// stack.deleteSipProvider((SipProvider) providers.next());  
98 -// }  
99 -// VManageBootstrap.restart();  
100 -// } catch (InterruptedException | ObjectInUseException e) {  
101 -// logger.error("[任务执行失败] 服务重启: {}", e.getMessage());  
102 -// }  
103 - });  
104 - } 76 + // TODO 拒绝远程启动命令
  77 + logger.warn("[国标级联]收到平台的远程启动命令, 不处理");
  78 +
  79 +// if (parentPlatform.getServerGBId().equals(targetGBId)) {
  80 +// // 远程启动本平台:需要在重新启动程序后先对SipStack解绑
  81 +// logger.info("执行远程启动本平台命令");
  82 +// try {
  83 +// cmderFroPlatform.unregister(parentPlatform, null, null);
  84 +// } catch (InvalidArgumentException | ParseException | SipException e) {
  85 +// logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage());
  86 +// }
  87 +// taskExecutor.execute(() -> {
  88 +// // 远程启动
  89 +//// try {
  90 +//// Thread.sleep(3000);
  91 +//// SipProvider up = (SipProvider) SpringBeanFactory.getBean("udpSipProvider");
  92 +//// SipStackImpl stack = (SipStackImpl)up.getSipStack();
  93 +//// stack.stop();
  94 +//// Iterator listener = stack.getListeningPoints();
  95 +//// while (listener.hasNext()) {
  96 +//// stack.deleteListeningPoint((ListeningPoint) listener.next());
  97 +//// }
  98 +//// Iterator providers = stack.getSipProviders();
  99 +//// while (providers.hasNext()) {
  100 +//// stack.deleteSipProvider((SipProvider) providers.next());
  101 +//// }
  102 +//// VManageBootstrap.restart();
  103 +//// } catch (InterruptedException | ObjectInUseException e) {
  104 +//// logger.error("[任务执行失败] 服务重启: {}", e.getMessage());
  105 +//// }
  106 +// });
  107 +// }
105 } 108 }
106 DeviceControlType deviceControlType = DeviceControlType.typeOf(rootElement); 109 DeviceControlType deviceControlType = DeviceControlType.typeOf(rootElement);
107 logger.info("[接受deviceControl命令] 命令: {}", deviceControlType); 110 logger.info("[接受deviceControl命令] 命令: {}", deviceControlType);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
@@ -88,7 +88,7 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp @@ -88,7 +88,7 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
88 // 对于已经离线的设备判断他的注册是否已经过期 88 // 对于已经离线的设备判断他的注册是否已经过期
89 if (!deviceService.expire(device)){ 89 if (!deviceService.expire(device)){
90 device.setOnline(0); 90 device.setOnline(0);
91 - deviceService.online(device); 91 + deviceService.online(device, null);
92 } 92 }
93 } 93 }
94 // 刷新过期任务 94 // 刷新过期任务
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceStatusResponseMessageHandler.java
@@ -71,7 +71,7 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen @@ -71,7 +71,7 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen
71 } 71 }
72 String text = onlineElement.getText(); 72 String text = onlineElement.getText();
73 if ("ONLINE".equalsIgnoreCase(text.trim())) { 73 if ("ONLINE".equalsIgnoreCase(text.trim())) {
74 - deviceService.online(device); 74 + deviceService.online(device, null);
75 }else { 75 }else {
76 deviceService.offline(device.getDeviceId(), "设备状态查询结果:" + text.trim()); 76 deviceService.offline(device.getDeviceId(), "设备状态查询结果:" + text.trim());
77 } 77 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java
@@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl; @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl;
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.bean.ParentPlatformCatch; 4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
  5 +import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
5 import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; 6 import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder;
6 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; 7 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; 8 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
@@ -10,6 +11,7 @@ import com.genersoft.iot.vmp.service.IPlatformService; @@ -10,6 +11,7 @@ import com.genersoft.iot.vmp.service.IPlatformService;
10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 11 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 12 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
12 import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; 13 import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo;
  14 +import gov.nist.javax.sip.message.SIPResponse;
13 import org.slf4j.Logger; 15 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory; 16 import org.slf4j.LoggerFactory;
15 import org.springframework.beans.factory.annotation.Autowired; 17 import org.springframework.beans.factory.annotation.Autowired;
@@ -18,7 +20,6 @@ import org.springframework.stereotype.Component; @@ -18,7 +20,6 @@ import org.springframework.stereotype.Component;
18 import javax.sip.InvalidArgumentException; 20 import javax.sip.InvalidArgumentException;
19 import javax.sip.ResponseEvent; 21 import javax.sip.ResponseEvent;
20 import javax.sip.SipException; 22 import javax.sip.SipException;
21 -import javax.sip.header.CallIdHeader;  
22 import javax.sip.header.WWWAuthenticateHeader; 23 import javax.sip.header.WWWAuthenticateHeader;
23 import javax.sip.message.Response; 24 import javax.sip.message.Response;
24 import java.text.ParseException; 25 import java.text.ParseException;
@@ -65,9 +66,8 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { @@ -65,9 +66,8 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract {
65 */ 66 */
66 @Override 67 @Override
67 public void process(ResponseEvent evt) { 68 public void process(ResponseEvent evt) {
68 - Response response = evt.getResponse();  
69 - CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME);  
70 - String callId = callIdHeader.getCallId(); 69 + SIPResponse response = (SIPResponse)evt.getResponse();
  70 + String callId = response.getCallIdHeader().getCallId();
71 PlatformRegisterInfo platformRegisterInfo = redisCatchStorage.queryPlatformRegisterInfo(callId); 71 PlatformRegisterInfo platformRegisterInfo = redisCatchStorage.queryPlatformRegisterInfo(callId);
72 if (platformRegisterInfo == null) { 72 if (platformRegisterInfo == null) {
73 logger.info(String.format("[国标级联]未找到callId: %s 的注册/注销平台id", callId )); 73 logger.info(String.format("[国标级联]未找到callId: %s 的注册/注销平台id", callId ));
@@ -90,15 +90,17 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { @@ -90,15 +90,17 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract {
90 90
91 if (response.getStatusCode() == Response.UNAUTHORIZED) { 91 if (response.getStatusCode() == Response.UNAUTHORIZED) {
92 WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME); 92 WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME);
  93 + SipTransactionInfo sipTransactionInfo = new SipTransactionInfo(response);
93 try { 94 try {
94 - sipCommanderForPlatform.register(parentPlatform, callId, www, null, null, true, platformRegisterInfo.isRegister()); 95 + sipCommanderForPlatform.register(parentPlatform, sipTransactionInfo, www, null, null, true, platformRegisterInfo.isRegister());
95 } catch (SipException | InvalidArgumentException | ParseException e) { 96 } catch (SipException | InvalidArgumentException | ParseException e) {
96 logger.error("[命令发送失败] 国标级联 再次注册: {}", e.getMessage()); 97 logger.error("[命令发送失败] 国标级联 再次注册: {}", e.getMessage());
97 } 98 }
98 }else if (response.getStatusCode() == Response.OK){ 99 }else if (response.getStatusCode() == Response.OK){
99 100
100 if (platformRegisterInfo.isRegister()) { 101 if (platformRegisterInfo.isRegister()) {
101 - platformService.online(parentPlatform); 102 + SipTransactionInfo sipTransactionInfo = new SipTransactionInfo(response);
  103 + platformService.online(parentPlatform, sipTransactionInfo);
102 }else { 104 }else {
103 platformService.offline(parentPlatform, false); 105 platformService.offline(parentPlatform, false);
104 } 106 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -116,7 +116,7 @@ public class ZLMHttpHookListener { @@ -116,7 +116,7 @@ public class ZLMHttpHookListener {
116 @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") 116 @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8")
117 public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param) { 117 public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param) {
118 118
119 - logger.info("[ZLM HOOK] 收到zlm心跳:" + param.getMediaServerId()); 119 +// logger.info("[ZLM HOOK] 收到zlm心跳:" + param.getMediaServerId());
120 120
121 taskExecutor.execute(() -> { 121 taskExecutor.execute(() -> {
122 List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive); 122 List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive);
src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java
@@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.service; @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.service;
2 2
3 import com.genersoft.iot.vmp.gb28181.bean.Device; 3 import com.genersoft.iot.vmp.gb28181.bean.Device;
4 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 4 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  5 +import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
5 import com.genersoft.iot.vmp.gb28181.bean.SyncStatus; 6 import com.genersoft.iot.vmp.gb28181.bean.SyncStatus;
6 import com.genersoft.iot.vmp.vmanager.bean.BaseTree; 7 import com.genersoft.iot.vmp.vmanager.bean.BaseTree;
7 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; 8 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo;
@@ -18,7 +19,7 @@ public interface IDeviceService { @@ -18,7 +19,7 @@ public interface IDeviceService {
18 * 设备上线 19 * 设备上线
19 * @param device 设备信息 20 * @param device 设备信息
20 */ 21 */
21 - void online(Device device); 22 + void online(Device device, SipTransactionInfo sipTransactionInfo);
22 23
23 /** 24 /**
24 * 设备下线 25 * 设备下线
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.ParentPlatform; 3 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  4 +import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
4 import com.github.pagehelper.PageInfo; 5 import com.github.pagehelper.PageInfo;
5 6
6 /** 7 /**
@@ -35,7 +36,7 @@ public interface IPlatformService { @@ -35,7 +36,7 @@ public interface IPlatformService {
35 * 平台上线 36 * 平台上线
36 * @param parentPlatform 平台信息 37 * @param parentPlatform 平台信息
37 */ 38 */
38 - void online(ParentPlatform parentPlatform); 39 + void online(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo);
39 40
40 /** 41 /**
41 * 平台离线 42 * 平台离线
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
@@ -89,7 +89,7 @@ public class DeviceServiceImpl implements IDeviceService { @@ -89,7 +89,7 @@ public class DeviceServiceImpl implements IDeviceService {
89 private IMediaServerService mediaServerService; 89 private IMediaServerService mediaServerService;
90 90
91 @Override 91 @Override
92 - public void online(Device device) { 92 + public void online(Device device, SipTransactionInfo sipTransactionInfo) {
93 logger.info("[设备上线] deviceId:{}->{}:{}", device.getDeviceId(), device.getIp(), device.getPort()); 93 logger.info("[设备上线] deviceId:{}->{}:{}", device.getDeviceId(), device.getIp(), device.getPort());
94 Device deviceInRedis = redisCatchStorage.getDevice(device.getDeviceId()); 94 Device deviceInRedis = redisCatchStorage.getDevice(device.getDeviceId());
95 Device deviceInDb = deviceMapper.getDeviceByDeviceId(device.getDeviceId()); 95 Device deviceInDb = deviceMapper.getDeviceByDeviceId(device.getDeviceId());
@@ -104,6 +104,14 @@ public class DeviceServiceImpl implements IDeviceService { @@ -104,6 +104,14 @@ public class DeviceServiceImpl implements IDeviceService {
104 // 默认心跳间隔60 104 // 默认心跳间隔60
105 device.setKeepaliveIntervalTime(60); 105 device.setKeepaliveIntervalTime(60);
106 } 106 }
  107 + if (sipTransactionInfo != null) {
  108 + device.setSipTransactionInfo(sipTransactionInfo);
  109 + }else {
  110 + if (deviceInRedis != null) {
  111 + device.setSipTransactionInfo(deviceInRedis.getSipTransactionInfo());
  112 + }
  113 + }
  114 +
107 // 第一次上线 或则设备之前是离线状态--进行通道同步和设备信息查询 115 // 第一次上线 或则设备之前是离线状态--进行通道同步和设备信息查询
108 if (device.getCreateTime() == null) { 116 if (device.getCreateTime() == null) {
109 device.setOnline(1); 117 device.setOnline(1);
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
@@ -123,8 +123,10 @@ public class PlatformServiceImpl implements IPlatformService { @@ -123,8 +123,10 @@ public class PlatformServiceImpl implements IPlatformService {
123 123
124 @Override 124 @Override
125 public boolean update(ParentPlatform parentPlatform) { 125 public boolean update(ParentPlatform parentPlatform) {
  126 + logger.info("[国标级联]更新平台 {}", parentPlatform.getDeviceGBId());
126 parentPlatform.setCharacterSet(parentPlatform.getCharacterSet().toUpperCase()); 127 parentPlatform.setCharacterSet(parentPlatform.getCharacterSet().toUpperCase());
127 ParentPlatform parentPlatformOld = platformMapper.getParentPlatById(parentPlatform.getId()); 128 ParentPlatform parentPlatformOld = platformMapper.getParentPlatById(parentPlatform.getId());
  129 + ParentPlatformCatch parentPlatformCatchOld = redisCatchStorage.queryPlatformCatchInfo(parentPlatformOld.getServerGBId());
128 parentPlatform.setUpdateTime(DateUtil.getNow()); 130 parentPlatform.setUpdateTime(DateUtil.getNow());
129 if (!parentPlatformOld.getTreeType().equals(parentPlatform.getTreeType())) { 131 if (!parentPlatformOld.getTreeType().equals(parentPlatform.getTreeType())) {
130 // 目录结构发生变化,清空之前的关联关系 132 // 目录结构发生变化,清空之前的关联关系
@@ -134,6 +136,7 @@ public class PlatformServiceImpl implements IPlatformService { @@ -134,6 +136,7 @@ public class PlatformServiceImpl implements IPlatformService {
134 platformGbStreamMapper.delByPlatformId(parentPlatformOld.getServerGBId()); 136 platformGbStreamMapper.delByPlatformId(parentPlatformOld.getServerGBId());
135 } 137 }
136 138
  139 +
137 // 停止心跳定时 140 // 停止心跳定时
138 final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatformOld.getServerGBId(); 141 final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatformOld.getServerGBId();
139 dynamicTask.stop(keepaliveTaskKey); 142 dynamicTask.stop(keepaliveTaskKey);
@@ -142,9 +145,13 @@ public class PlatformServiceImpl implements IPlatformService { @@ -142,9 +145,13 @@ public class PlatformServiceImpl implements IPlatformService {
142 dynamicTask.stop(registerTaskKey); 145 dynamicTask.stop(registerTaskKey);
143 // 注销旧的 146 // 注销旧的
144 try { 147 try {
145 - commanderForPlatform.unregister(parentPlatformOld, null, eventResult -> {  
146 - logger.info("[国标级联] 注销成功, 平台:{}", parentPlatformOld.getServerGBId());  
147 - }); 148 + if (parentPlatformOld.isStatus()) {
  149 + logger.info("保存平台{}时发现救平台在线,发送注销命令", parentPlatform.getDeviceGBId());
  150 + commanderForPlatform.unregister(parentPlatformOld, parentPlatformCatchOld.getSipTransactionInfo(), null, eventResult -> {
  151 + logger.info("[国标级联] 注销成功, 平台:{}", parentPlatformOld.getServerGBId());
  152 + });
  153 + }
  154 +
148 } catch (InvalidArgumentException | ParseException | SipException e) { 155 } catch (InvalidArgumentException | ParseException | SipException e) {
149 logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage()); 156 logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage());
150 } 157 }
@@ -185,36 +192,36 @@ public class PlatformServiceImpl implements IPlatformService { @@ -185,36 +192,36 @@ public class PlatformServiceImpl implements IPlatformService {
185 192
186 193
187 @Override 194 @Override
188 - public void online(ParentPlatform parentPlatform) {  
189 - logger.info("[国标级联]:{}, 平台上线/更新注册", parentPlatform.getServerGBId()); 195 + public void online(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo) {
  196 + logger.info("[国标级联]:{}, 平台上线", parentPlatform.getServerGBId());
190 platformMapper.updateParentPlatformStatus(parentPlatform.getServerGBId(), true); 197 platformMapper.updateParentPlatformStatus(parentPlatform.getServerGBId(), true);
191 ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); 198 ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId());
192 - if (parentPlatformCatch != null) {  
193 - parentPlatformCatch.getParentPlatform().setStatus(true);  
194 - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);  
195 - }else { 199 + if (parentPlatformCatch == null) {
196 parentPlatformCatch = new ParentPlatformCatch(); 200 parentPlatformCatch = new ParentPlatformCatch();
197 parentPlatformCatch.setParentPlatform(parentPlatform); 201 parentPlatformCatch.setParentPlatform(parentPlatform);
198 parentPlatformCatch.setId(parentPlatform.getServerGBId()); 202 parentPlatformCatch.setId(parentPlatform.getServerGBId());
199 parentPlatform.setStatus(true); 203 parentPlatform.setStatus(true);
200 parentPlatformCatch.setParentPlatform(parentPlatform); 204 parentPlatformCatch.setParentPlatform(parentPlatform);
201 - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);  
202 } 205 }
203 206
  207 + parentPlatformCatch.getParentPlatform().setStatus(true);
  208 + parentPlatformCatch.setSipTransactionInfo(sipTransactionInfo);
  209 + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
  210 +
204 final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId(); 211 final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId();
205 if (!dynamicTask.isAlive(registerTaskKey)) { 212 if (!dynamicTask.isAlive(registerTaskKey)) {
  213 + logger.info("[国标级联]:{}, 添加定时注册任务", parentPlatform.getServerGBId());
206 // 添加注册任务 214 // 添加注册任务
207 dynamicTask.startCron(registerTaskKey, 215 dynamicTask.startCron(registerTaskKey,
208 // 注册失败(注册成功时由程序直接调用了online方法) 216 // 注册失败(注册成功时由程序直接调用了online方法)
209 - ()-> {  
210 - registerTask(parentPlatform);  
211 - },  
212 - (parentPlatform.getExpires()) *1000); 217 + ()-> registerTask(parentPlatform, sipTransactionInfo),
  218 + parentPlatform.getExpires() * 1000);
213 } 219 }
214 220
215 221
216 final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId(); 222 final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId();
217 if (!dynamicTask.contains(keepaliveTaskKey)) { 223 if (!dynamicTask.contains(keepaliveTaskKey)) {
  224 + logger.info("[国标级联]:{}, 添加定时心跳任务", parentPlatform.getServerGBId());
218 // 添加心跳任务 225 // 添加心跳任务
219 dynamicTask.startCron(keepaliveTaskKey, 226 dynamicTask.startCron(keepaliveTaskKey,
220 ()-> { 227 ()-> {
@@ -259,7 +266,7 @@ public class PlatformServiceImpl implements IPlatformService { @@ -259,7 +266,7 @@ public class PlatformServiceImpl implements IPlatformService {
259 } 266 }
260 } 267 }
261 268
262 - private void registerTask(ParentPlatform parentPlatform){ 269 + private void registerTask(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo){
263 try { 270 try {
264 // 设置超时重发, 后续从底层支持消息重发 271 // 设置超时重发, 后续从底层支持消息重发
265 String key = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId() + "_timeout"; 272 String key = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId() + "_timeout";
@@ -267,10 +274,10 @@ public class PlatformServiceImpl implements IPlatformService { @@ -267,10 +274,10 @@ public class PlatformServiceImpl implements IPlatformService {
267 return; 274 return;
268 } 275 }
269 dynamicTask.startDelay(key, ()->{ 276 dynamicTask.startDelay(key, ()->{
270 - registerTask(parentPlatform); 277 + registerTask(parentPlatform, sipTransactionInfo);
271 }, 1000); 278 }, 1000);
272 - logger.info("[国标级联] 平台:{}注册即将到期,重新注册", parentPlatform.getServerGBId());  
273 - commanderForPlatform.register(parentPlatform, eventResult -> { 279 + logger.info("[国标级联] 平台:{}注册即将到期,开始续订", parentPlatform.getServerGBId());
  280 + commanderForPlatform.register(parentPlatform, sipTransactionInfo, eventResult -> {
274 dynamicTask.stop(key); 281 dynamicTask.stop(key);
275 offline(parentPlatform, false); 282 offline(parentPlatform, false);
276 },eventResult -> { 283 },eventResult -> {
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java
@@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.conf.DynamicTask; @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.conf.DynamicTask;
7 import com.genersoft.iot.vmp.conf.UserSetting; 7 import com.genersoft.iot.vmp.conf.UserSetting;
8 import com.genersoft.iot.vmp.conf.exception.ControllerException; 8 import com.genersoft.iot.vmp.conf.exception.ControllerException;
9 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 9 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  10 +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
10 import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog; 11 import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
11 import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; 12 import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder;
12 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; 13 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
@@ -229,12 +230,16 @@ public class PlatformController { @@ -229,12 +230,16 @@ public class PlatformController {
229 throw new ControllerException(ErrorCode.ERROR400); 230 throw new ControllerException(ErrorCode.ERROR400);
230 } 231 }
231 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(serverGBId); 232 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(serverGBId);
  233 + ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(serverGBId);
232 if (parentPlatform == null) { 234 if (parentPlatform == null) {
233 throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台不存在"); 235 throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台不存在");
234 } 236 }
  237 + if (parentPlatformCatch == null) {
  238 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台不存在");
  239 + }
235 // 发送离线消息,无论是否成功都删除缓存 240 // 发送离线消息,无论是否成功都删除缓存
236 try { 241 try {
237 - commanderForPlatform.unregister(parentPlatform, (event -> { 242 + commanderForPlatform.unregister(parentPlatform, parentPlatformCatch.getSipTransactionInfo(), (event -> {
238 // 清空redis缓存 243 // 清空redis缓存
239 redisCatchStorage.delPlatformCatchInfo(parentPlatform.getServerGBId()); 244 redisCatchStorage.delPlatformCatchInfo(parentPlatform.getServerGBId());
240 redisCatchStorage.delPlatformKeepalive(parentPlatform.getServerGBId()); 245 redisCatchStorage.delPlatformKeepalive(parentPlatform.getServerGBId());