Commit 54d79531795d43bf45fa8d7cb2ed2d072f7f5ccd
1 parent
627a14f3
完成向上级联->删除的时候注销
Showing
11 changed files
with
205 additions
and
141 deletions
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java
| ... | ... | @@ -10,6 +10,8 @@ public class ParentPlatformCatch { |
| 10 | 10 | // 注册未回复次数 |
| 11 | 11 | private int registerAliveReply; |
| 12 | 12 | |
| 13 | + private ParentPlatform parentPlatform; | |
| 14 | + | |
| 13 | 15 | public String getId() { |
| 14 | 16 | return id; |
| 15 | 17 | } |
| ... | ... | @@ -33,4 +35,12 @@ public class ParentPlatformCatch { |
| 33 | 35 | public void setRegisterAliveReply(int registerAliveReply) { |
| 34 | 36 | this.registerAliveReply = registerAliveReply; |
| 35 | 37 | } |
| 38 | + | |
| 39 | + public ParentPlatform getParentPlatform() { | |
| 40 | + return parentPlatform; | |
| 41 | + } | |
| 42 | + | |
| 43 | + public void setParentPlatform(ParentPlatform parentPlatform) { | |
| 44 | + this.parentPlatform = parentPlatform; | |
| 45 | + } | |
| 36 | 46 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEventLister.java
| ... | ... | @@ -52,6 +52,7 @@ public class PlatformKeepaliveExpireEventLister implements ApplicationListener<P |
| 52 | 52 | } |
| 53 | 53 | ParentPlatform parentPlatform = storager.queryParentPlatById(event.getPlatformGbID()); |
| 54 | 54 | ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(event.getPlatformGbID()); |
| 55 | + parentPlatformCatch.setParentPlatform(parentPlatform); | |
| 55 | 56 | if (parentPlatform == null) { |
| 56 | 57 | logger.debug("平台心跳到期事件事件触发,但平台已经删除!!! 平台国标ID:" + event.getPlatformGbID()); |
| 57 | 58 | return; | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.transmit.cmd; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 4 | +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | |
| 5 | + | |
| 6 | +import javax.sip.header.WWWAuthenticateHeader; | |
| 4 | 7 | |
| 5 | 8 | public interface ISIPCommanderForPlatform { |
| 6 | 9 | |
| ... | ... | @@ -11,7 +14,14 @@ public interface ISIPCommanderForPlatform { |
| 11 | 14 | */ |
| 12 | 15 | boolean register(ParentPlatform parentPlatform); |
| 13 | 16 | |
| 14 | - boolean register(ParentPlatform parentPlatform, String callId, String realm, String nonce, String scheme); | |
| 17 | + /** | |
| 18 | + * 向上级平台注销 | |
| 19 | + * @param parentPlatform | |
| 20 | + * @return | |
| 21 | + */ | |
| 22 | + boolean unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent); | |
| 23 | + | |
| 24 | + boolean register(ParentPlatform parentPlatform, String callId, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent); | |
| 15 | 25 | |
| 16 | 26 | /** |
| 17 | 27 | * 向上级平发送心跳信息 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
| ... | ... | @@ -20,10 +20,11 @@ import javax.sip.message.Request; |
| 20 | 20 | import javax.validation.constraints.NotNull; |
| 21 | 21 | import java.text.ParseException; |
| 22 | 22 | import java.util.ArrayList; |
| 23 | +import java.util.UUID; | |
| 23 | 24 | |
| 24 | 25 | /** |
| 25 | - * @Description:摄像头命令request创造器 TODO 冗余代码太多待优化 | |
| 26 | - * @author: swwheihei | |
| 26 | + * @Description: 平台命令request创造器 TODO 冗余代码太多待优化 | |
| 27 | + * @author: panll | |
| 27 | 28 | * @date: 2020年5月6日 上午9:29:02 |
| 28 | 29 | */ |
| 29 | 30 | @Component |
| ... | ... | @@ -79,7 +80,7 @@ public class SIPRequestHeaderPlarformProvider { |
| 79 | 80 | } |
| 80 | 81 | |
| 81 | 82 | |
| 82 | - public Request createRegisterRequest(@NotNull ParentPlatform platform, String fromTag, String viaTag) throws ParseException, InvalidArgumentException, PeerUnavailableException { | |
| 83 | + public Request createRegisterRequest(@NotNull ParentPlatform platform, long CSeq, String fromTag, String viaTag) throws ParseException, InvalidArgumentException, PeerUnavailableException { | |
| 83 | 84 | Request request = null; |
| 84 | 85 | String sipAddress = sipConfig.getSipIp() + ":" + sipConfig.getSipPort(); |
| 85 | 86 | //请求行 |
| ... | ... | @@ -112,7 +113,7 @@ public class SIPRequestHeaderPlarformProvider { |
| 112 | 113 | MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70); |
| 113 | 114 | |
| 114 | 115 | //ceq |
| 115 | - CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(1L, Request.REGISTER); | |
| 116 | + CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(CSeq, Request.REGISTER); | |
| 116 | 117 | request = sipFactory.createMessageFactory().createRequest(requestLine, Request.REGISTER, callIdHeader, |
| 117 | 118 | cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); |
| 118 | 119 | |
| ... | ... | @@ -120,28 +121,73 @@ public class SIPRequestHeaderPlarformProvider { |
| 120 | 121 | .createSipURI(platform.getDeviceGBId(), sipAddress)); |
| 121 | 122 | request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); |
| 122 | 123 | |
| 124 | + ExpiresHeader expires = sipFactory.createHeaderFactory().createExpiresHeader(Integer.parseInt(platform.getExpires())); | |
| 125 | + request.addHeader(expires); | |
| 126 | + | |
| 123 | 127 | return request; |
| 124 | 128 | } |
| 125 | 129 | |
| 126 | 130 | public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, String fromTag, String viaTag, |
| 127 | - String callId, String realm, String nonce, String scheme) throws ParseException, PeerUnavailableException, InvalidArgumentException { | |
| 128 | - Request registerRequest = createRegisterRequest(parentPlatform, fromTag, viaTag); | |
| 131 | + String callId, WWWAuthenticateHeader www ) throws ParseException, PeerUnavailableException, InvalidArgumentException { | |
| 132 | + Request registerRequest = createRegisterRequest(parentPlatform, 2L, fromTag, viaTag); | |
| 133 | + | |
| 134 | + String realm = www.getRealm(); | |
| 135 | + String nonce = www.getNonce(); | |
| 136 | + String scheme = www.getScheme(); | |
| 137 | + | |
| 138 | + // 参考 https://blog.csdn.net/y673533511/article/details/88388138 | |
| 139 | + // qop 保护质量 包含auth(默认的)和auth-int(增加了报文完整性检测)两种策略 | |
| 140 | + String qop = www.getQop(); | |
| 129 | 141 | |
| 130 | 142 | CallIdHeader callIdHeader = (CallIdHeader)registerRequest.getHeader(CallIdHeader.NAME); |
| 131 | 143 | callIdHeader.setCallId(callId); |
| 132 | 144 | |
| 133 | - String uri = "sip:" + parentPlatform.getServerGBId() + | |
| 134 | - "@" + parentPlatform.getServerIP() + | |
| 135 | - ":" + parentPlatform.getServerPort(); | |
| 136 | 145 | |
| 146 | + SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); | |
| 147 | + String cNonce = null; | |
| 148 | + String nc = "00000001"; | |
| 149 | + if (qop != null) { | |
| 150 | + if ("auth".equals(qop)) { | |
| 151 | + // 客户端随机数,这是一个不透明的字符串值,由客户端提供,并且客户端和服务器都会使用,以避免用明文文本。 | |
| 152 | + // 这使得双方都可以查验对方的身份,并对消息的完整性提供一些保护 | |
| 153 | + cNonce = UUID.randomUUID().toString(); | |
| 154 | + | |
| 155 | + }else if ("auth-int".equals(qop)){ | |
| 156 | + // TODO | |
| 157 | + } | |
| 158 | + } | |
| 137 | 159 | String HA1 = DigestUtils.md5DigestAsHex((parentPlatform.getDeviceGBId() + ":" + realm + ":" + parentPlatform.getPassword()).getBytes()); |
| 138 | - String HA2=DigestUtils.md5DigestAsHex((Request.REGISTER + ":" + uri).getBytes()); | |
| 139 | - String RESPONSE = DigestUtils.md5DigestAsHex((HA1 + ":" + nonce + ":" + HA2).getBytes()); | |
| 140 | - | |
| 141 | - String authorizationHeaderContent = scheme + " username=\"" + parentPlatform.getDeviceGBId() + "\", " + "realm=\"" | |
| 142 | - + realm + "\", uri=\"" + uri + "\", response=\"" + RESPONSE + "\", nonce=\"" | |
| 143 | - + nonce + "\""; | |
| 144 | - AuthorizationHeader authorizationHeader = sipFactory.createHeaderFactory().createAuthorizationHeader(authorizationHeaderContent); | |
| 160 | + String HA2=DigestUtils.md5DigestAsHex((Request.REGISTER + ":" + requestURI.toString()).getBytes()); | |
| 161 | + | |
| 162 | + StringBuffer reStr = new StringBuffer(200); | |
| 163 | + reStr.append(HA1); | |
| 164 | + reStr.append(":"); | |
| 165 | + reStr.append(nonce); | |
| 166 | + reStr.append(":"); | |
| 167 | + if (qop != null) { | |
| 168 | + reStr.append(nc); | |
| 169 | + reStr.append(":"); | |
| 170 | + reStr.append(cNonce); | |
| 171 | + reStr.append(":"); | |
| 172 | + reStr.append(qop); | |
| 173 | + reStr.append(":"); | |
| 174 | + } | |
| 175 | + reStr.append(HA2); | |
| 176 | + | |
| 177 | + String RESPONSE = DigestUtils.md5DigestAsHex(reStr.toString().getBytes()); | |
| 178 | + | |
| 179 | + AuthorizationHeader authorizationHeader = sipFactory.createHeaderFactory().createAuthorizationHeader(scheme); | |
| 180 | + authorizationHeader.setUsername(parentPlatform.getDeviceGBId()); | |
| 181 | + authorizationHeader.setRealm(realm); | |
| 182 | + authorizationHeader.setNonce(nonce); | |
| 183 | + authorizationHeader.setURI(requestURI); | |
| 184 | + authorizationHeader.setResponse(RESPONSE); | |
| 185 | + authorizationHeader.setAlgorithm("MD5"); | |
| 186 | + if (qop != null) { | |
| 187 | + authorizationHeader.setQop(qop); | |
| 188 | + authorizationHeader.setCNonce(cNonce); | |
| 189 | + authorizationHeader.setNonceCount(1); | |
| 190 | + } | |
| 145 | 191 | registerRequest.addHeader(authorizationHeader); |
| 146 | 192 | |
| 147 | 193 | return registerRequest; | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
| ... | ... | @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; |
| 2 | 2 | |
| 3 | 3 | import java.text.ParseException; |
| 4 | 4 | import java.util.ArrayList; |
| 5 | +import java.util.UUID; | |
| 5 | 6 | |
| 6 | 7 | import javax.sip.InvalidArgumentException; |
| 7 | 8 | import javax.sip.PeerUnavailableException; |
| ... | ... | @@ -167,109 +168,4 @@ public class SIPRequestHeaderProvider { |
| 167 | 168 | request.setContent(content, contentTypeHeader); |
| 168 | 169 | return request; |
| 169 | 170 | } |
| 170 | - | |
| 171 | - | |
| 172 | - public Request createRegisterRequest(@NotNull ParentPlatform platform, long CSeq, String fromTag, String viaTag) throws ParseException, InvalidArgumentException, PeerUnavailableException { | |
| 173 | - Request request = null; | |
| 174 | - String sipAddress = sipConfig.getSipIp() + ":" + sipConfig.getSipPort(); | |
| 175 | - //请求行 | |
| 176 | - SipURI requestLine = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(), | |
| 177 | - platform.getServerIP() + ":" + platform.getServerPort()); | |
| 178 | - //via | |
| 179 | - ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); | |
| 180 | - ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(platform.getServerIP(), platform.getServerPort(), platform.getTransport(), viaTag); | |
| 181 | - viaHeader.setRPort(); | |
| 182 | - viaHeaders.add(viaHeader); | |
| 183 | - //from | |
| 184 | - SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(),sipAddress); | |
| 185 | - Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI); | |
| 186 | - FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag); | |
| 187 | - //to | |
| 188 | - SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(),sipAddress); | |
| 189 | - Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI); | |
| 190 | - ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress,null); | |
| 191 | - | |
| 192 | - //callid | |
| 193 | - CallIdHeader callIdHeader = null; | |
| 194 | - if(platform.getTransport().equals("TCP")) { | |
| 195 | - callIdHeader = tcpSipProvider.getNewCallId(); | |
| 196 | - } | |
| 197 | - if(platform.getTransport().equals("UDP")) { | |
| 198 | - callIdHeader = udpSipProvider.getNewCallId(); | |
| 199 | - } | |
| 200 | - | |
| 201 | - //Forwards | |
| 202 | - MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70); | |
| 203 | - | |
| 204 | - //ceq | |
| 205 | - CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(CSeq, Request.REGISTER); | |
| 206 | - request = sipFactory.createMessageFactory().createRequest(requestLine, Request.REGISTER, callIdHeader, | |
| 207 | - cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | |
| 208 | - | |
| 209 | - Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory() | |
| 210 | - .createSipURI(platform.getDeviceGBId(), sipAddress)); | |
| 211 | - request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); | |
| 212 | - | |
| 213 | - ExpiresHeader expires = sipFactory.createHeaderFactory().createExpiresHeader(Integer.parseInt(platform.getExpires())); | |
| 214 | - request.addHeader(expires); | |
| 215 | - | |
| 216 | - return request; | |
| 217 | - } | |
| 218 | - | |
| 219 | - public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, String fromTag, String viaTag, | |
| 220 | - String callId, String realm, String nonce, String scheme) throws ParseException, PeerUnavailableException, InvalidArgumentException { | |
| 221 | - Request registerRequest = createRegisterRequest(parentPlatform, 2L, fromTag, viaTag); | |
| 222 | - | |
| 223 | - CallIdHeader callIdHeader = (CallIdHeader)registerRequest.getHeader(CallIdHeader.NAME); | |
| 224 | - callIdHeader.setCallId(callId); | |
| 225 | - | |
| 226 | - String uri = "sip:" + parentPlatform.getServerGBId() + | |
| 227 | - "@" + parentPlatform.getServerIP() + | |
| 228 | - ":" + parentPlatform.getServerPort(); | |
| 229 | - | |
| 230 | - String HA1 = DigestUtils.md5DigestAsHex((parentPlatform.getDeviceGBId() + ":" + realm + ":" + parentPlatform.getPassword()).getBytes()); | |
| 231 | - String HA2=DigestUtils.md5DigestAsHex((Request.REGISTER + ":" + uri).getBytes()); | |
| 232 | - String RESPONSE = DigestUtils.md5DigestAsHex((HA1 + ":" + nonce + ":" + HA2).getBytes()); | |
| 233 | - | |
| 234 | - String authorizationHeaderContent = scheme + " username=\"" + parentPlatform.getDeviceGBId() + "\", " + "realm=\"" | |
| 235 | - + realm + "\", nonce=\"" + nonce + "\", uri=\"" + uri + "\", response=\"" + RESPONSE + "\"" + ", algorithm=MD5"; | |
| 236 | - AuthorizationHeader authorizationHeader = sipFactory.createHeaderFactory().createAuthorizationHeader(authorizationHeaderContent); | |
| 237 | - registerRequest.addHeader(authorizationHeader); | |
| 238 | - | |
| 239 | - return registerRequest; | |
| 240 | - } | |
| 241 | - | |
| 242 | -// public Request createKeetpaliveMessageRequest(ParentPlatform parentPlatform, String content, String fromTag, String toTag, Object o) throws PeerUnavailableException, ParseException, InvalidArgumentException { | |
| 243 | -// Request request = null; | |
| 244 | -// // sipuri | |
| 245 | -// SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); | |
| 246 | -// // via | |
| 247 | -// ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); | |
| 248 | -// ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), | |
| 249 | -// parentPlatform.getTransport(), null); | |
| 250 | -// viaHeader.setRPort(); | |
| 251 | -// viaHeaders.add(viaHeader); | |
| 252 | -// // from | |
| 253 | -// SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), | |
| 254 | -// sipConfig.getSipIp() + ":" + sipConfig.getSipPort()); | |
| 255 | -// Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI); | |
| 256 | -// FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag); | |
| 257 | -// // to | |
| 258 | -// SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerGBDomain()); | |
| 259 | -// Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI); | |
| 260 | -// ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag); | |
| 261 | -// // callid | |
| 262 | -// CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() | |
| 263 | -// : udpSipProvider.getNewCallId(); | |
| 264 | -// // Forwards | |
| 265 | -// MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70); | |
| 266 | -// // ceq | |
| 267 | -// CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(1L, Request.MESSAGE); | |
| 268 | -// | |
| 269 | -// request = sipFactory.createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader, | |
| 270 | -// toHeader, viaHeaders, maxForwards); | |
| 271 | -// ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "MANSCDP+xml"); | |
| 272 | -// request.setContent(content, contentTypeHeader); | |
| 273 | -// return request; | |
| 274 | -// } | |
| 275 | 171 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
| ... | ... | @@ -3,10 +3,13 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; |
| 3 | 3 | import com.genersoft.iot.vmp.conf.SipConfig; |
| 4 | 4 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; | |
| 7 | +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | |
| 6 | 8 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 7 | 9 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 8 | 10 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider; |
| 9 | 11 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; |
| 12 | +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | |
| 10 | 13 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 11 | 14 | import org.springframework.beans.factory.annotation.Autowired; |
| 12 | 15 | import org.springframework.beans.factory.annotation.Qualifier; |
| ... | ... | @@ -16,6 +19,7 @@ import org.springframework.stereotype.Component; |
| 16 | 19 | |
| 17 | 20 | import javax.sip.*; |
| 18 | 21 | import javax.sip.header.CallIdHeader; |
| 22 | +import javax.sip.header.WWWAuthenticateHeader; | |
| 19 | 23 | import javax.sip.message.Request; |
| 20 | 24 | import java.text.ParseException; |
| 21 | 25 | import java.util.UUID; |
| ... | ... | @@ -39,6 +43,12 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 39 | 43 | private IVideoManagerStorager storager; |
| 40 | 44 | |
| 41 | 45 | @Autowired |
| 46 | + private IRedisCatchStorage redisCatchStorage; | |
| 47 | + | |
| 48 | + @Autowired | |
| 49 | + private SipSubscribe sipSubscribe; | |
| 50 | + | |
| 51 | + @Autowired | |
| 42 | 52 | @Qualifier(value="tcpSipProvider") |
| 43 | 53 | private SipProvider tcpSipProvider; |
| 44 | 54 | |
| ... | ... | @@ -55,16 +65,29 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 55 | 65 | } |
| 56 | 66 | |
| 57 | 67 | @Override |
| 58 | - public boolean register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable String realm, @Nullable String nonce, @Nullable String scheme ) { | |
| 68 | + public boolean unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { | |
| 69 | + parentPlatform.setExpires("0"); | |
| 70 | + ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getDeviceGBId()); | |
| 71 | + if (parentPlatformCatch != null) { | |
| 72 | + parentPlatformCatch.setParentPlatform(parentPlatform); | |
| 73 | + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | |
| 74 | + } | |
| 75 | + | |
| 76 | + return register(parentPlatform, null, null, errorEvent, okEvent); | |
| 77 | + } | |
| 78 | + | |
| 79 | + @Override | |
| 80 | + public boolean register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { | |
| 59 | 81 | try { |
| 60 | 82 | Request request = null; |
| 61 | - if (realm == null || nonce == null) { | |
| 62 | - request = headerProvider.createRegisterRequest(parentPlatform, 1L, null, null); | |
| 83 | + | |
| 84 | + if (www == null ) { | |
| 85 | + request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, 1L, null, null); | |
| 63 | 86 | }else { |
| 64 | - request = headerProvider.createRegisterRequest(parentPlatform, null, null, callId, realm, nonce, scheme); | |
| 87 | + request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, null, null, callId, www); | |
| 65 | 88 | } |
| 66 | 89 | |
| 67 | - transmitRequest(parentPlatform, request); | |
| 90 | + transmitRequest(parentPlatform, request, errorEvent, okEvent); | |
| 68 | 91 | return true; |
| 69 | 92 | } catch (ParseException e) { |
| 70 | 93 | e.printStackTrace(); |
| ... | ... | @@ -108,10 +131,29 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 108 | 131 | } |
| 109 | 132 | |
| 110 | 133 | private void transmitRequest(ParentPlatform parentPlatform, Request request) throws SipException { |
| 134 | + transmitRequest(parentPlatform, request, null, null); | |
| 135 | + } | |
| 136 | + | |
| 137 | + private void transmitRequest(ParentPlatform parentPlatform, Request request, SipSubscribe.Event errorEvent) throws SipException { | |
| 138 | + transmitRequest(parentPlatform, request, errorEvent, null); | |
| 139 | + } | |
| 140 | + | |
| 141 | + private void transmitRequest(ParentPlatform parentPlatform, Request request, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws SipException { | |
| 111 | 142 | if("TCP".equals(parentPlatform.getTransport())) { |
| 112 | 143 | tcpSipProvider.sendRequest(request); |
| 113 | 144 | } else if("UDP".equals(parentPlatform.getTransport())) { |
| 114 | 145 | udpSipProvider.sendRequest(request); |
| 115 | 146 | } |
| 147 | + | |
| 148 | + CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME); | |
| 149 | + // 添加错误订阅 | |
| 150 | + if (errorEvent != null) { | |
| 151 | + sipSubscribe.addErrorSubscribe(callIdHeader.getCallId(), errorEvent); | |
| 152 | + } | |
| 153 | + // 添加订阅 | |
| 154 | + if (okEvent != null) { | |
| 155 | + sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), okEvent); | |
| 156 | + } | |
| 157 | + | |
| 116 | 158 | } |
| 117 | 159 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java
| ... | ... | @@ -22,9 +22,11 @@ import javax.sip.ResponseEvent; |
| 22 | 22 | import javax.sip.address.Address; |
| 23 | 23 | import javax.sip.address.URI; |
| 24 | 24 | import javax.sip.header.CallIdHeader; |
| 25 | +import javax.sip.header.ExpiresHeader; | |
| 25 | 26 | import javax.sip.header.ToHeader; |
| 26 | 27 | import javax.sip.header.WWWAuthenticateHeader; |
| 27 | 28 | import javax.sip.message.Response; |
| 29 | +import java.util.UUID; | |
| 28 | 30 | |
| 29 | 31 | /** |
| 30 | 32 | * @Description:Register响应处理器 |
| ... | ... | @@ -62,24 +64,28 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor { |
| 62 | 64 | ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME); |
| 63 | 65 | SipUri uri = (SipUri)toHeader.getAddress().getURI(); |
| 64 | 66 | String platformGBId = uri.getAuthority().getUser(); |
| 65 | - logger.info(String.format("收到 %s 的注册%S请求", platformGBId, response.getStatusCode() )); | |
| 66 | 67 | |
| 67 | - ParentPlatform parentPlatform = storager.queryParentPlatById(platformGBId); | |
| 68 | + logger.info(String.format("收到 %s 的注册/注销%S响应", platformGBId, response.getStatusCode() )); | |
| 69 | + | |
| 70 | + ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(platformGBId); | |
| 71 | + if (parentPlatformCatch == null) { | |
| 72 | + logger.warn(String.format("收到 %s 的注册/注销%S请求, 但是平台缓存信息未查询到!!!", platformGBId, response.getStatusCode())); | |
| 73 | + return; | |
| 74 | + } | |
| 75 | + ParentPlatform parentPlatform = parentPlatformCatch.getParentPlatform(); | |
| 68 | 76 | if (parentPlatform == null) { |
| 69 | - logger.warn(String.format("收到 %s 的注册%S请求, 但是平台信息未查询到!!!", platformGBId, response.getStatusCode())); | |
| 77 | + logger.warn(String.format("收到 %s 的注册/注销%S请求, 但是平台信息未查询到!!!", platformGBId, response.getStatusCode())); | |
| 70 | 78 | return; |
| 71 | 79 | } |
| 72 | 80 | |
| 73 | 81 | if (response.getStatusCode() == 401) { |
| 74 | - | |
| 75 | 82 | WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME); |
| 76 | - String realm = www.getRealm(); | |
| 77 | - String nonce = www.getNonce(); | |
| 78 | - String scheme = www.getScheme(); | |
| 83 | + | |
| 79 | 84 | |
| 80 | 85 | CallIdHeader callIdHeader = (CallIdHeader)response.getHeader(CallIdHeader.NAME); |
| 81 | 86 | String callId = callIdHeader.getCallId(); |
| 82 | - sipCommanderForPlatform.register(parentPlatform, callId, realm, nonce, scheme); | |
| 87 | + | |
| 88 | + sipCommanderForPlatform.register(parentPlatform, callId, www, null, null); | |
| 83 | 89 | }else if (response.getStatusCode() == 200){ |
| 84 | 90 | // 注册成功 |
| 85 | 91 | logger.info(String.format("%s 注册成功", platformGBId )); |
| ... | ... | @@ -90,11 +96,8 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor { |
| 90 | 96 | |
| 91 | 97 | redisCatchStorage.updatePlatformKeepalive(parentPlatform); |
| 92 | 98 | |
| 93 | - ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getDeviceGBId()); | |
| 94 | - if (parentPlatformCatch == null) { | |
| 95 | - parentPlatformCatch = new ParentPlatformCatch(); | |
| 96 | - parentPlatformCatch.setId(parentPlatform.getDeviceGBId()); | |
| 97 | - } | |
| 99 | + parentPlatformCatch.setParentPlatform(parentPlatform); | |
| 100 | + | |
| 98 | 101 | redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); |
| 99 | 102 | } |
| 100 | 103 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
| ... | ... | @@ -63,8 +63,14 @@ public interface IRedisCatchStorage { |
| 63 | 63 | |
| 64 | 64 | ParentPlatformCatch queryPlatformCatchInfo(String platformGbId); |
| 65 | 65 | |
| 66 | + void delPlatformCatchInfo(String platformGbId); | |
| 67 | + | |
| 66 | 68 | void updatePlatformKeepalive(ParentPlatform parentPlatform); |
| 67 | 69 | |
| 70 | + void delPlatformKeepalive(String platformGbId); | |
| 71 | + | |
| 68 | 72 | void updatePlatformRegister(ParentPlatform parentPlatform); |
| 69 | 73 | |
| 74 | + void delPlatformRegister(String platformGbId); | |
| 75 | + | |
| 70 | 76 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
| ... | ... | @@ -189,4 +189,19 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { |
| 189 | 189 | public ParentPlatformCatch queryPlatformCatchInfo(String platformGbId) { |
| 190 | 190 | return (ParentPlatformCatch)redis.get(VideoManagerConstants.PLATFORM_CATCH_PREFIX + platformGbId); |
| 191 | 191 | } |
| 192 | + | |
| 193 | + @Override | |
| 194 | + public void delPlatformCatchInfo(String platformGbId) { | |
| 195 | + redis.del(VideoManagerConstants.PLATFORM_CATCH_PREFIX + platformGbId); | |
| 196 | + } | |
| 197 | + | |
| 198 | + @Override | |
| 199 | + public void delPlatformKeepalive(String platformGbId) { | |
| 200 | + redis.del(VideoManagerConstants.PLATFORM_KEEPLIVEKEY_PREFIX + platformGbId); | |
| 201 | + } | |
| 202 | + | |
| 203 | + @Override | |
| 204 | + public void delPlatformRegister(String platformGbId) { | |
| 205 | + redis.del(VideoManagerConstants.PLATFORM_REGISTER_PREFIX + platformGbId); | |
| 206 | + } | |
| 192 | 207 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
| ... | ... | @@ -4,6 +4,8 @@ import java.util.*; |
| 4 | 4 | |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 6 | 6 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 7 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; | |
| 8 | +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | |
| 7 | 9 | import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; |
| 8 | 10 | import com.genersoft.iot.vmp.storager.dao.DeviceMapper; |
| 9 | 11 | import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; |
| ... | ... | @@ -31,6 +33,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { |
| 31 | 33 | |
| 32 | 34 | @Autowired |
| 33 | 35 | private ParentPlatformMapper platformMapper; |
| 36 | + @Autowired | |
| 37 | + private IRedisCatchStorage redisCatchStorage; | |
| 38 | + | |
| 39 | + | |
| 34 | 40 | |
| 35 | 41 | |
| 36 | 42 | /** |
| ... | ... | @@ -210,11 +216,21 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { |
| 210 | 216 | @Override |
| 211 | 217 | public boolean updateParentPlatform(ParentPlatform parentPlatform) { |
| 212 | 218 | int result = 0; |
| 219 | + ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getDeviceGBId()); | |
| 213 | 220 | if ( platformMapper.getParentPlatById(parentPlatform.getDeviceGBId()) == null) { |
| 214 | 221 | result = platformMapper.addParentPlatform(parentPlatform); |
| 222 | + | |
| 223 | + if (parentPlatformCatch == null) { | |
| 224 | + parentPlatformCatch = new ParentPlatformCatch(); | |
| 225 | + parentPlatformCatch.setParentPlatform(parentPlatform); | |
| 226 | + parentPlatformCatch.setId(parentPlatform.getDeviceGBId()); | |
| 227 | + } | |
| 215 | 228 | }else { |
| 216 | 229 | result = platformMapper.updateParentPlatform(parentPlatform); |
| 217 | 230 | } |
| 231 | + // 更新缓存 | |
| 232 | + parentPlatformCatch.setParentPlatform(parentPlatform); | |
| 233 | + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | |
| 218 | 234 | return result > 0; |
| 219 | 235 | } |
| 220 | 236 | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/platform/PlatformController.java
| ... | ... | @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.vmanager.platform; |
| 3 | 3 | import com.alibaba.fastjson.JSONObject; |
| 4 | 4 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 6 | +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | |
| 6 | 7 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 7 | 8 | import com.github.pagehelper.PageInfo; |
| 8 | 9 | import org.slf4j.Logger; |
| ... | ... | @@ -24,6 +25,8 @@ public class PlatformController { |
| 24 | 25 | |
| 25 | 26 | @Autowired |
| 26 | 27 | private IVideoManagerStorager storager; |
| 28 | + @Autowired | |
| 29 | + private IRedisCatchStorage redisCatchStorage; | |
| 27 | 30 | |
| 28 | 31 | @Autowired |
| 29 | 32 | private ISIPCommanderForPlatform commanderForPlatform; |
| ... | ... | @@ -75,7 +78,7 @@ public class PlatformController { |
| 75 | 78 | boolean updateResult = storager.updateParentPlatform(parentPlatform); |
| 76 | 79 | |
| 77 | 80 | if (updateResult) { |
| 78 | - commanderForPlatform.register(parentPlatform, null, null, null, null); | |
| 81 | + commanderForPlatform.register(parentPlatform); | |
| 79 | 82 | |
| 80 | 83 | return new ResponseEntity<>("success", HttpStatus.OK); |
| 81 | 84 | }else { |
| ... | ... | @@ -94,7 +97,23 @@ public class PlatformController { |
| 94 | 97 | ){ |
| 95 | 98 | return new ResponseEntity<>("missing parameters", HttpStatus.BAD_REQUEST); |
| 96 | 99 | } |
| 100 | + | |
| 101 | + // 发送离线消息, | |
| 102 | + commanderForPlatform.unregister(parentPlatform, (event -> { | |
| 103 | + // 清空redis缓存 | |
| 104 | + redisCatchStorage.delPlatformCatchInfo(parentPlatform.getDeviceGBId()); | |
| 105 | + redisCatchStorage.delPlatformKeepalive(parentPlatform.getDeviceGBId()); | |
| 106 | + redisCatchStorage.delPlatformRegister(parentPlatform.getDeviceGBId()); | |
| 107 | + }), (event -> { | |
| 108 | + // 清空redis缓存 | |
| 109 | + redisCatchStorage.delPlatformCatchInfo(parentPlatform.getDeviceGBId()); | |
| 110 | + redisCatchStorage.delPlatformKeepalive(parentPlatform.getDeviceGBId()); | |
| 111 | + redisCatchStorage.delPlatformRegister(parentPlatform.getDeviceGBId()); | |
| 112 | + })); | |
| 113 | + | |
| 97 | 114 | boolean deleteResult = storager.deleteParentPlatform(parentPlatform); |
| 115 | + | |
| 116 | + | |
| 98 | 117 | if (deleteResult) { |
| 99 | 118 | return new ResponseEntity<>("success", HttpStatus.OK); |
| 100 | 119 | }else { | ... | ... |