Commit 91bfbc36f10382434a9e8c79eeeaf07a531b08b5
1 parent
58d1f0ea
优化设备注册,支持到期续订,优化国标级联到期续订。
Showing
19 changed files
with
205 additions
and
90 deletions
pom.xml
| @@ -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()); |