Commit bb22908cf7cf698853a06d51593a22eaa64e789d
Committed by
GitHub
Merge pull request #67 from lawrencehj/wvp-28181-2.0
增加上级平台信令功能实现,解决上级点播的一些问题
Showing
19 changed files
with
391 additions
and
98 deletions
README.md
| @@ -60,21 +60,24 @@ https://gitee.com/18010473990/wvp-GB28181.git | @@ -60,21 +60,24 @@ https://gitee.com/18010473990/wvp-GB28181.git | ||
| 60 | 15. 支持订阅与通知方法 | 60 | 15. 支持订阅与通知方法 |
| 61 | - [X] 移动位置订阅 | 61 | - [X] 移动位置订阅 |
| 62 | - [X] 移动位置通知处理 | 62 | - [X] 移动位置通知处理 |
| 63 | - - [ ] 报警事件订阅 | 63 | + - [X] 报警事件订阅 |
| 64 | - [X] 报警事件通知处理 | 64 | - [X] 报警事件通知处理 |
| 65 | - [ ] 设备目录订阅 | 65 | - [ ] 设备目录订阅 |
| 66 | - [X] 设备目录通知处理 | 66 | - [X] 设备目录通知处理 |
| 67 | 16. 移动位置查询和显示,可通过配置文件设置移动位置历史是否存储 | 67 | 16. 移动位置查询和显示,可通过配置文件设置移动位置历史是否存储 |
| 68 | 68 | ||
| 69 | # 2.0 支持特性 | 69 | # 2.0 支持特性 |
| 70 | -- [ ] 国标通道向上级联 | 70 | +- [X] 国标通道向上级联 |
| 71 | - [X] WEB添加上级平台 | 71 | - [X] WEB添加上级平台 |
| 72 | - [X] 注册 | 72 | - [X] 注册 |
| 73 | - [X] 心跳保活 | 73 | - [X] 心跳保活 |
| 74 | - [X] 通道选择 | 74 | - [X] 通道选择 |
| 75 | - [X] 通道推送 | 75 | - [X] 通道推送 |
| 76 | - - [ ] 点播 | ||
| 77 | - - [ ] 云台控制 | 76 | + - [X] 点播 |
| 77 | + - [X] 云台控制 | ||
| 78 | + - [X] 平台状态查询 | ||
| 79 | + - [X] 平台信息查询 | ||
| 80 | + - [X] 平台远程启动 | ||
| 78 | - [ ] 添加RTSP视频 | 81 | - [ ] 添加RTSP视频 |
| 79 | - [ ] 添加ONVIF探测局域网内的设备 | 82 | - [ ] 添加ONVIF探测局域网内的设备 |
| 80 | - [ ] 添加RTMP视频 | 83 | - [ ] 添加RTMP视频 |
src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java
| @@ -4,10 +4,20 @@ import java.util.logging.LogManager; | @@ -4,10 +4,20 @@ import java.util.logging.LogManager; | ||
| 4 | 4 | ||
| 5 | import org.springframework.boot.SpringApplication; | 5 | import org.springframework.boot.SpringApplication; |
| 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; | 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; |
| 7 | +import org.springframework.context.ConfigurableApplicationContext; | ||
| 7 | 8 | ||
| 8 | @SpringBootApplication | 9 | @SpringBootApplication |
| 9 | public class VManageBootstrap extends LogManager { | 10 | public class VManageBootstrap extends LogManager { |
| 11 | + private static String[] args; | ||
| 12 | + private static ConfigurableApplicationContext context; | ||
| 10 | public static void main(String[] args) { | 13 | public static void main(String[] args) { |
| 11 | - SpringApplication.run(VManageBootstrap.class, args); | 14 | + VManageBootstrap.args = args; |
| 15 | + VManageBootstrap.context = SpringApplication.run(VManageBootstrap.class, args); | ||
| 16 | + } | ||
| 17 | + // 项目重启 | ||
| 18 | + public static void restart() { | ||
| 19 | + context.close(); | ||
| 20 | + VManageBootstrap.context = SpringApplication.run(VManageBootstrap.class, args); | ||
| 21 | + | ||
| 12 | } | 22 | } |
| 13 | } | 23 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
| @@ -15,6 +15,7 @@ import org.springframework.stereotype.Component; | @@ -15,6 +15,7 @@ import org.springframework.stereotype.Component; | ||
| 15 | public class VideoStreamSessionManager { | 15 | public class VideoStreamSessionManager { |
| 16 | 16 | ||
| 17 | private ConcurrentHashMap<String, ClientTransaction> sessionMap = new ConcurrentHashMap<>(); | 17 | private ConcurrentHashMap<String, ClientTransaction> sessionMap = new ConcurrentHashMap<>(); |
| 18 | + private ConcurrentHashMap<String, String> ssrcMap = new ConcurrentHashMap<>(); | ||
| 18 | 19 | ||
| 19 | public String createPlaySsrc(){ | 20 | public String createPlaySsrc(){ |
| 20 | return SsrcUtil.getPlaySsrc(); | 21 | return SsrcUtil.getPlaySsrc(); |
| @@ -24,16 +25,18 @@ public class VideoStreamSessionManager { | @@ -24,16 +25,18 @@ public class VideoStreamSessionManager { | ||
| 24 | return SsrcUtil.getPlayBackSsrc(); | 25 | return SsrcUtil.getPlayBackSsrc(); |
| 25 | } | 26 | } |
| 26 | 27 | ||
| 27 | - public void put(String ssrc,ClientTransaction transaction){ | ||
| 28 | - sessionMap.put(ssrc, transaction); | 28 | + public void put(String streamId,String ssrc,ClientTransaction transaction){ |
| 29 | + sessionMap.put(streamId, transaction); | ||
| 30 | + ssrcMap.put(streamId, ssrc); | ||
| 29 | } | 31 | } |
| 30 | 32 | ||
| 31 | - public ClientTransaction get(String ssrc){ | ||
| 32 | - return sessionMap.get(ssrc); | 33 | + public ClientTransaction get(String streamId){ |
| 34 | + return sessionMap.get(streamId); | ||
| 33 | } | 35 | } |
| 34 | 36 | ||
| 35 | - public void remove(String ssrc) { | ||
| 36 | - sessionMap.remove(ssrc); | ||
| 37 | - SsrcUtil.releaseSsrc(ssrc); | 37 | + public void remove(String streamId) { |
| 38 | + sessionMap.remove(streamId); | ||
| 39 | + SsrcUtil.releaseSsrc(ssrcMap.get(streamId)); | ||
| 40 | + ssrcMap.remove(streamId); | ||
| 38 | } | 41 | } |
| 39 | } | 42 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
| @@ -156,6 +156,7 @@ public class SIPProcessorFactory { | @@ -156,6 +156,7 @@ public class SIPProcessorFactory { | ||
| 156 | processor.setRequestEvent(evt); | 156 | processor.setRequestEvent(evt); |
| 157 | processor.setRedisCatchStorage(redisCatchStorage); | 157 | processor.setRedisCatchStorage(redisCatchStorage); |
| 158 | processor.setZlmrtpServerFactory(zlmrtpServerFactory); | 158 | processor.setZlmrtpServerFactory(zlmrtpServerFactory); |
| 159 | + processor.setSIPCommander(cmder); | ||
| 159 | return processor; | 160 | return processor; |
| 160 | } else if (Request.CANCEL.equals(method)) { | 161 | } else if (Request.CANCEL.equals(method)) { |
| 161 | CancelRequestProcessor processor = new CancelRequestProcessor(); | 162 | CancelRequestProcessor processor = new CancelRequestProcessor(); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
| @@ -78,6 +78,14 @@ public interface ISIPCommander { | @@ -78,6 +78,14 @@ public interface ISIPCommander { | ||
| 78 | boolean frontEndCmd(Device device, String channelId, int cmdCode, int parameter1, int parameter2, int combineCode2); | 78 | boolean frontEndCmd(Device device, String channelId, int cmdCode, int parameter1, int parameter2, int combineCode2); |
| 79 | 79 | ||
| 80 | /** | 80 | /** |
| 81 | + * 前端控制指令(用于转发上级指令) | ||
| 82 | + * @param device 控制设备 | ||
| 83 | + * @param channelId 预览通道 | ||
| 84 | + * @param cmdString 前端控制指令串 | ||
| 85 | + */ | ||
| 86 | + boolean fronEndCmd(Device device, String channelId, String cmdString); | ||
| 87 | + | ||
| 88 | + /** | ||
| 81 | * 请求预览视频流 | 89 | * 请求预览视频流 |
| 82 | * | 90 | * |
| 83 | * @param device 视频设备 | 91 | * @param device 视频设备 |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
| @@ -42,4 +42,23 @@ public interface ISIPCommanderForPlatform { | @@ -42,4 +42,23 @@ public interface ISIPCommanderForPlatform { | ||
| 42 | * @return | 42 | * @return |
| 43 | */ | 43 | */ |
| 44 | boolean catalogQuery(DeviceChannel channel, ParentPlatform parentPlatform, String sn, String fromTag, int size); | 44 | boolean catalogQuery(DeviceChannel channel, ParentPlatform parentPlatform, String sn, String fromTag, int size); |
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * 向上级回复DeviceInfo查询信息 | ||
| 48 | + * @param parentPlatform 平台信息 | ||
| 49 | + * @param sn | ||
| 50 | + * @param fromTag | ||
| 51 | + * @return | ||
| 52 | + */ | ||
| 53 | + boolean deviceInfoResponse(ParentPlatform parentPlatform, String sn, String fromTag); | ||
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * 向上级回复DeviceStatus查询信息 | ||
| 57 | + * @param parentPlatform 平台信息 | ||
| 58 | + * @param sn | ||
| 59 | + * @param fromTag | ||
| 60 | + * @return | ||
| 61 | + */ | ||
| 62 | + boolean deviceStatusResponse(ParentPlatform parentPlatform, String sn, String fromTag); | ||
| 63 | + | ||
| 45 | } | 64 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| @@ -235,7 +235,7 @@ public class SIPCommander implements ISIPCommander { | @@ -235,7 +235,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 235 | ptzXml.append("</Control>\r\n"); | 235 | ptzXml.append("</Control>\r\n"); |
| 236 | 236 | ||
| 237 | String tm = Long.toString(System.currentTimeMillis()); | 237 | String tm = Long.toString(System.currentTimeMillis()); |
| 238 | - Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtz" + tm, null); | 238 | + Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "z9hG4bK-ViaPtz-" + tm, "FromPtz" + tm, null); |
| 239 | 239 | ||
| 240 | transmitRequest(device, request); | 240 | transmitRequest(device, request); |
| 241 | return true; | 241 | return true; |
| @@ -272,7 +272,7 @@ public class SIPCommander implements ISIPCommander { | @@ -272,7 +272,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 272 | ptzXml.append("</Control>\r\n"); | 272 | ptzXml.append("</Control>\r\n"); |
| 273 | 273 | ||
| 274 | String tm = Long.toString(System.currentTimeMillis()); | 274 | String tm = Long.toString(System.currentTimeMillis()); |
| 275 | - Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtz" + tm, null); | 275 | + Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "z9hG4bK-ViaPtz-" + tm, "FromPtz" + tm, null); |
| 276 | transmitRequest(device, request); | 276 | transmitRequest(device, request); |
| 277 | return true; | 277 | return true; |
| 278 | } catch (SipException | ParseException | InvalidArgumentException e) { | 278 | } catch (SipException | ParseException | InvalidArgumentException e) { |
| @@ -282,6 +282,36 @@ public class SIPCommander implements ISIPCommander { | @@ -282,6 +282,36 @@ public class SIPCommander implements ISIPCommander { | ||
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | /** | 284 | /** |
| 285 | + * 前端控制指令(用于转发上级指令) | ||
| 286 | + * @param device 控制设备 | ||
| 287 | + * @param channelId 预览通道 | ||
| 288 | + * @param cmdString 前端控制指令串 | ||
| 289 | + */ | ||
| 290 | + @Override | ||
| 291 | + public boolean fronEndCmd(Device device, String channelId, String cmdString) { | ||
| 292 | + try { | ||
| 293 | + StringBuffer ptzXml = new StringBuffer(200); | ||
| 294 | + ptzXml.append("<?xml version=\"1.0\" ?>\r\n"); | ||
| 295 | + ptzXml.append("<Control>\r\n"); | ||
| 296 | + ptzXml.append("<CmdType>DeviceControl</CmdType>\r\n"); | ||
| 297 | + ptzXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); | ||
| 298 | + ptzXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n"); | ||
| 299 | + ptzXml.append("<PTZCmd>" + cmdString + "</PTZCmd>\r\n"); | ||
| 300 | + ptzXml.append("<Info>\r\n"); | ||
| 301 | + ptzXml.append("</Info>\r\n"); | ||
| 302 | + ptzXml.append("</Control>\r\n"); | ||
| 303 | + | ||
| 304 | + String tm = Long.toString(System.currentTimeMillis()); | ||
| 305 | + Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "z9hG4bK-ViaPtz-" + tm, "FromPtz" + tm, null); | ||
| 306 | + transmitRequest(device, request); | ||
| 307 | + return true; | ||
| 308 | + } catch (SipException | ParseException | InvalidArgumentException e) { | ||
| 309 | + e.printStackTrace(); | ||
| 310 | + } | ||
| 311 | + return false; | ||
| 312 | + } | ||
| 313 | + | ||
| 314 | + /** | ||
| 285 | * 请求预览视频流 | 315 | * 请求预览视频流 |
| 286 | * @param device 视频设备 | 316 | * @param device 视频设备 |
| 287 | * @param channelId 预览通道 | 317 | * @param channelId 预览通道 |
| @@ -387,9 +417,7 @@ public class SIPCommander implements ISIPCommander { | @@ -387,9 +417,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 387 | Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrc); | 417 | Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrc); |
| 388 | 418 | ||
| 389 | ClientTransaction transaction = transmitRequest(device, request, errorEvent); | 419 | ClientTransaction transaction = transmitRequest(device, request, errorEvent); |
| 390 | - streamSession.put(streamId, transaction); | ||
| 391 | - | ||
| 392 | - | 420 | + streamSession.put(streamId,ssrc, transaction); |
| 393 | 421 | ||
| 394 | } catch ( SipException | ParseException | InvalidArgumentException e) { | 422 | } catch ( SipException | ParseException | InvalidArgumentException e) { |
| 395 | e.printStackTrace(); | 423 | e.printStackTrace(); |
| @@ -487,7 +515,7 @@ public class SIPCommander implements ISIPCommander { | @@ -487,7 +515,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 487 | Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null); | 515 | Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null); |
| 488 | 516 | ||
| 489 | ClientTransaction transaction = transmitRequest(device, request, errorEvent); | 517 | ClientTransaction transaction = transmitRequest(device, request, errorEvent); |
| 490 | - streamSession.put(streamId, transaction); | 518 | + streamSession.put(streamId, ssrc, transaction); |
| 491 | 519 | ||
| 492 | } catch ( SipException | ParseException | InvalidArgumentException e) { | 520 | } catch ( SipException | ParseException | InvalidArgumentException e) { |
| 493 | e.printStackTrace(); | 521 | e.printStackTrace(); |
| @@ -893,7 +921,7 @@ public class SIPCommander implements ISIPCommander { | @@ -893,7 +921,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 893 | catalogXml.append("</Query>\r\n"); | 921 | catalogXml.append("</Query>\r\n"); |
| 894 | 922 | ||
| 895 | String tm = Long.toString(System.currentTimeMillis()); | 923 | String tm = Long.toString(System.currentTimeMillis()); |
| 896 | - Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "z9hG4bK-ViaDeviceInfo" + tm, "FromDev" + tm, null); | 924 | + Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "z9hG4bK-ViaDeviceInfo-" + tm, "FromDev" + tm, null); |
| 897 | 925 | ||
| 898 | transmitRequest(device, request); | 926 | transmitRequest(device, request); |
| 899 | 927 | ||
| @@ -923,7 +951,7 @@ public class SIPCommander implements ISIPCommander { | @@ -923,7 +951,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 923 | catalogXml.append("</Query>\r\n"); | 951 | catalogXml.append("</Query>\r\n"); |
| 924 | 952 | ||
| 925 | String tm = Long.toString(System.currentTimeMillis()); | 953 | String tm = Long.toString(System.currentTimeMillis()); |
| 926 | - Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "z9hG4bK-ViaCatalog" + tm, "FromCat" + tm, null); | 954 | + Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "z9hG4bK-ViaCatalog-" + tm, "FromCat" + tm, null); |
| 927 | 955 | ||
| 928 | transmitRequest(device, request, errorEvent); | 956 | transmitRequest(device, request, errorEvent); |
| 929 | } catch (SipException | ParseException | InvalidArgumentException e) { | 957 | } catch (SipException | ParseException | InvalidArgumentException e) { |
| @@ -958,7 +986,7 @@ public class SIPCommander implements ISIPCommander { | @@ -958,7 +986,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 958 | recordInfoXml.append("</Query>\r\n"); | 986 | recordInfoXml.append("</Query>\r\n"); |
| 959 | 987 | ||
| 960 | String tm = Long.toString(System.currentTimeMillis()); | 988 | String tm = Long.toString(System.currentTimeMillis()); |
| 961 | - Request request = headerProvider.createMessageRequest(device, recordInfoXml.toString(), "ViaRecordInfoBranch", "fromRec" + tm, null); | 989 | + Request request = headerProvider.createMessageRequest(device, recordInfoXml.toString(), "z9hG4bK-ViaRecordInfo-" + tm, "fromRec" + tm, null); |
| 962 | 990 | ||
| 963 | transmitRequest(device, request); | 991 | transmitRequest(device, request); |
| 964 | } catch (SipException | ParseException | InvalidArgumentException e) { | 992 | } catch (SipException | ParseException | InvalidArgumentException e) { |
| @@ -1101,7 +1129,7 @@ public class SIPCommander implements ISIPCommander { | @@ -1101,7 +1129,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 1101 | mobilePostitionXml.append("</Query>\r\n"); | 1129 | mobilePostitionXml.append("</Query>\r\n"); |
| 1102 | 1130 | ||
| 1103 | String tm = Long.toString(System.currentTimeMillis()); | 1131 | String tm = Long.toString(System.currentTimeMillis()); |
| 1104 | - Request request = headerProvider.createMessageRequest(device, mobilePostitionXml.toString(), "viaTagPos" + tm, "fromTagPos" + tm, null); | 1132 | + Request request = headerProvider.createMessageRequest(device, mobilePostitionXml.toString(), "z9hG4bK-viaPos-" + tm, "fromTagPos" + tm, null); |
| 1105 | 1133 | ||
| 1106 | transmitRequest(device, request, errorEvent); | 1134 | transmitRequest(device, request, errorEvent); |
| 1107 | 1135 | ||
| @@ -1134,7 +1162,7 @@ public class SIPCommander implements ISIPCommander { | @@ -1134,7 +1162,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 1134 | subscribePostitionXml.append("</Query>\r\n"); | 1162 | subscribePostitionXml.append("</Query>\r\n"); |
| 1135 | 1163 | ||
| 1136 | String tm = Long.toString(System.currentTimeMillis()); | 1164 | String tm = Long.toString(System.currentTimeMillis()); |
| 1137 | - Request request = headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), "viaTagPos" + tm, "fromTagPos" + tm, null, expires, "presence" ); //Position;id=" + tm.substring(tm.length() - 4)); | 1165 | + Request request = headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), "z9hG4bK-viaPos-" + tm, "fromTagPos" + tm, null, expires, "presence" ); //Position;id=" + tm.substring(tm.length() - 4)); |
| 1138 | transmitRequest(device, request); | 1166 | transmitRequest(device, request); |
| 1139 | 1167 | ||
| 1140 | return true; | 1168 | return true; |
| @@ -1187,7 +1215,7 @@ public class SIPCommander implements ISIPCommander { | @@ -1187,7 +1215,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 1187 | cmdXml.append("</Query>\r\n"); | 1215 | cmdXml.append("</Query>\r\n"); |
| 1188 | 1216 | ||
| 1189 | String tm = Long.toString(System.currentTimeMillis()); | 1217 | String tm = Long.toString(System.currentTimeMillis()); |
| 1190 | - Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), "viaTagPos" + tm, "fromTagPos" + tm, null, expires, "presence" ); | 1218 | + Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), "z9hG4bK-viaPos-" + tm, "fromTagPos" + tm, null, expires, "presence" ); |
| 1191 | transmitRequest(device, request); | 1219 | transmitRequest(device, request); |
| 1192 | 1220 | ||
| 1193 | return true; | 1221 | return true; |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
| @@ -118,7 +118,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | @@ -118,7 +118,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | ||
| 118 | try { | 118 | try { |
| 119 | 119 | ||
| 120 | StringBuffer keepaliveXml = new StringBuffer(200); | 120 | StringBuffer keepaliveXml = new StringBuffer(200); |
| 121 | - keepaliveXml.append("<?xml version=\"1.0\"?>\r\n");//" encoding=\"GB2312\"?>\r\n"); | 121 | + keepaliveXml.append("<?xml version=\"1.0\"?>\r\n"); |
| 122 | keepaliveXml.append("<Notify>\r\n"); | 122 | keepaliveXml.append("<Notify>\r\n"); |
| 123 | keepaliveXml.append("<CmdType>Keepalive</CmdType>\r\n"); | 123 | keepaliveXml.append("<CmdType>Keepalive</CmdType>\r\n"); |
| 124 | keepaliveXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); | 124 | keepaliveXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); |
| @@ -217,4 +217,72 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | @@ -217,4 +217,72 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | ||
| 217 | } | 217 | } |
| 218 | return true; | 218 | return true; |
| 219 | } | 219 | } |
| 220 | + | ||
| 221 | + /** | ||
| 222 | + * 向上级回复DeviceInfo查询信息 | ||
| 223 | + * @param parentPlatform 平台信息 | ||
| 224 | + * @param sn | ||
| 225 | + * @param fromTag | ||
| 226 | + * @return | ||
| 227 | + */ | ||
| 228 | + @Override | ||
| 229 | + public boolean deviceInfoResponse(ParentPlatform parentPlatform, String sn, String fromTag) { | ||
| 230 | + if (parentPlatform == null) { | ||
| 231 | + return false; | ||
| 232 | + } | ||
| 233 | + try { | ||
| 234 | + StringBuffer deviceInfoXml = new StringBuffer(600); | ||
| 235 | + deviceInfoXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n"); | ||
| 236 | + deviceInfoXml.append("<Response>\r\n"); | ||
| 237 | + deviceInfoXml.append("<CmdType>DeviceInfo</CmdType>\r\n"); | ||
| 238 | + deviceInfoXml.append("<SN>" +sn + "</SN>\r\n"); | ||
| 239 | + deviceInfoXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n"); | ||
| 240 | + deviceInfoXml.append("<DeviceName>GB28181 Video Platform</DeviceName>\r\n"); | ||
| 241 | + deviceInfoXml.append("<Manufacturer>Manufacturer</Manufacturer>\r\n"); | ||
| 242 | + deviceInfoXml.append("<Model>wvp-28181</Model>\r\n"); | ||
| 243 | + deviceInfoXml.append("<Firmware>2.0.202103</Firmware>\r\n"); | ||
| 244 | + deviceInfoXml.append("<Result>OK</Result>\r\n"); | ||
| 245 | + deviceInfoXml.append("</Response>\r\n"); | ||
| 246 | + Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, deviceInfoXml.toString(), fromTag); | ||
| 247 | + transmitRequest(parentPlatform, request); | ||
| 248 | + | ||
| 249 | + } catch (SipException | ParseException | InvalidArgumentException e) { | ||
| 250 | + e.printStackTrace(); | ||
| 251 | + return false; | ||
| 252 | + } | ||
| 253 | + return true; | ||
| 254 | + } | ||
| 255 | + | ||
| 256 | + /** | ||
| 257 | + * 向上级回复DeviceStatus查询信息 | ||
| 258 | + * @param parentPlatform 平台信息 | ||
| 259 | + * @param sn | ||
| 260 | + * @param fromTag | ||
| 261 | + * @return | ||
| 262 | + */ | ||
| 263 | + @Override | ||
| 264 | + public boolean deviceStatusResponse(ParentPlatform parentPlatform, String sn, String fromTag) { | ||
| 265 | + if (parentPlatform == null) { | ||
| 266 | + return false; | ||
| 267 | + } | ||
| 268 | + try { | ||
| 269 | + StringBuffer deviceStatusXml = new StringBuffer(600); | ||
| 270 | + deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n"); | ||
| 271 | + deviceStatusXml.append("<Response>\r\n"); | ||
| 272 | + deviceStatusXml.append("<CmdType>DeviceStatus</CmdType>\r\n"); | ||
| 273 | + deviceStatusXml.append("<SN>" +sn + "</SN>\r\n"); | ||
| 274 | + deviceStatusXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n"); | ||
| 275 | + deviceStatusXml.append("<Result>OK</Result>\r\n"); | ||
| 276 | + deviceStatusXml.append("<Online>ONLINE</Online>\r\n"); | ||
| 277 | + deviceStatusXml.append("<Status>OK</Status>\r\n"); | ||
| 278 | + deviceStatusXml.append("</Response>\r\n"); | ||
| 279 | + Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), fromTag); | ||
| 280 | + transmitRequest(parentPlatform, request); | ||
| 281 | + | ||
| 282 | + } catch (SipException | ParseException | InvalidArgumentException e) { | ||
| 283 | + e.printStackTrace(); | ||
| 284 | + return false; | ||
| 285 | + } | ||
| 286 | + return true; | ||
| 287 | + } | ||
| 220 | } | 288 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
| @@ -4,7 +4,10 @@ import java.util.HashMap; | @@ -4,7 +4,10 @@ import java.util.HashMap; | ||
| 4 | import java.util.Map; | 4 | import java.util.Map; |
| 5 | 5 | ||
| 6 | import javax.sip.*; | 6 | import javax.sip.*; |
| 7 | -//import javax.sip.message.Request; | 7 | +import javax.sip.address.SipURI; |
| 8 | +import javax.sip.header.FromHeader; | ||
| 9 | +import javax.sip.header.HeaderAddress; | ||
| 10 | +import javax.sip.header.ToHeader; | ||
| 8 | 11 | ||
| 9 | import com.genersoft.iot.vmp.common.StreamInfo; | 12 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 10 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | 13 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| @@ -12,14 +15,11 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcesso | @@ -12,14 +15,11 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcesso | ||
| 12 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | 15 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 13 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 16 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 14 | 17 | ||
| 15 | -import org.springframework.stereotype.Component; | ||
| 16 | - | ||
| 17 | /** | 18 | /** |
| 18 | * @Description:ACK请求处理器 | 19 | * @Description:ACK请求处理器 |
| 19 | * @author: swwheihei | 20 | * @author: swwheihei |
| 20 | * @date: 2020年5月3日 下午5:31:45 | 21 | * @date: 2020年5月3日 下午5:31:45 |
| 21 | */ | 22 | */ |
| 22 | -@Component | ||
| 23 | public class AckRequestProcessor extends SIPRequestAbstractProcessor { | 23 | public class AckRequestProcessor extends SIPRequestAbstractProcessor { |
| 24 | 24 | ||
| 25 | private IRedisCatchStorage redisCatchStorage; | 25 | private IRedisCatchStorage redisCatchStorage; |
| @@ -38,10 +38,8 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor { | @@ -38,10 +38,8 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 38 | if (dialog == null) return; | 38 | if (dialog == null) return; |
| 39 | //DialogState state = dialog.getState(); | 39 | //DialogState state = dialog.getState(); |
| 40 | if (/*request.getMethod().equals(Request.INVITE) &&*/ dialog.getState()== DialogState.CONFIRMED) { | 40 | if (/*request.getMethod().equals(Request.INVITE) &&*/ dialog.getState()== DialogState.CONFIRMED) { |
| 41 | - String remoteUri = dialog.getRemoteParty().getURI().toString(); | ||
| 42 | - String localUri = dialog.getLocalParty().getURI().toString(); | ||
| 43 | - String platformGbId = remoteUri.substring(remoteUri.indexOf(":") + 1, remoteUri.indexOf("@")); | ||
| 44 | - String channelId = localUri.substring(remoteUri.indexOf(":") + 1, remoteUri.indexOf("@")); | 41 | + String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); |
| 42 | + String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); | ||
| 45 | SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId); | 43 | SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId); |
| 46 | String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; | 44 | String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; |
| 47 | String deviceId = sendRtpItem.getDeviceId(); | 45 | String deviceId = sendRtpItem.getDeviceId(); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java
| 1 | package com.genersoft.iot.vmp.gb28181.transmit.request.impl; | 1 | package com.genersoft.iot.vmp.gb28181.transmit.request.impl; |
| 2 | 2 | ||
| 3 | +import javax.sip.address.SipURI; | ||
| 3 | import javax.sip.Dialog; | 4 | import javax.sip.Dialog; |
| 4 | import javax.sip.DialogState; | 5 | import javax.sip.DialogState; |
| 5 | import javax.sip.InvalidArgumentException; | 6 | import javax.sip.InvalidArgumentException; |
| 6 | import javax.sip.RequestEvent; | 7 | import javax.sip.RequestEvent; |
| 7 | import javax.sip.SipException; | 8 | import javax.sip.SipException; |
| 9 | +import javax.sip.header.FromHeader; | ||
| 10 | +import javax.sip.header.HeaderAddress; | ||
| 11 | +import javax.sip.header.ToHeader; | ||
| 8 | import javax.sip.message.Response; | 12 | import javax.sip.message.Response; |
| 9 | 13 | ||
| 10 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | 14 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| 15 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; | ||
| 11 | import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; | 16 | import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; |
| 12 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | 17 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 13 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 18 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| @@ -18,12 +23,14 @@ import java.util.Map; | @@ -18,12 +23,14 @@ import java.util.Map; | ||
| 18 | 23 | ||
| 19 | /** | 24 | /** |
| 20 | * @Description: BYE请求处理器 | 25 | * @Description: BYE请求处理器 |
| 21 | - * @author: swwheihei | ||
| 22 | - * @date: 2020年5月3日 下午5:32:05 | 26 | + * @author: lawrencehj |
| 27 | + * @date: 2021年3月9日 | ||
| 23 | */ | 28 | */ |
| 24 | public class ByeRequestProcessor extends SIPRequestAbstractProcessor { | 29 | public class ByeRequestProcessor extends SIPRequestAbstractProcessor { |
| 25 | 30 | ||
| 26 | - private IRedisCatchStorage redisCatchStorage; | 31 | + private ISIPCommander cmder; |
| 32 | + | ||
| 33 | + private IRedisCatchStorage redisCatchStorage; | ||
| 27 | 34 | ||
| 28 | private ZLMRTPServerFactory zlmrtpServerFactory; | 35 | private ZLMRTPServerFactory zlmrtpServerFactory; |
| 29 | 36 | ||
| @@ -38,10 +45,8 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor { | @@ -38,10 +45,8 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 38 | Dialog dialog = evt.getDialog(); | 45 | Dialog dialog = evt.getDialog(); |
| 39 | if (dialog == null) return; | 46 | if (dialog == null) return; |
| 40 | if (dialog.getState().equals(DialogState.TERMINATED)) { | 47 | if (dialog.getState().equals(DialogState.TERMINATED)) { |
| 41 | - String remoteUri = dialog.getRemoteParty().getURI().toString(); | ||
| 42 | - String localUri = dialog.getLocalParty().getURI().toString(); | ||
| 43 | - String platformGbId = remoteUri.substring(remoteUri.indexOf(":") + 1, remoteUri.indexOf("@")); | ||
| 44 | - String channelId = localUri.substring(remoteUri.indexOf(":") + 1, remoteUri.indexOf("@")); | 48 | + String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); |
| 49 | + String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); | ||
| 45 | SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId); | 50 | SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId); |
| 46 | String streamId = sendRtpItem.getStreamId(); | 51 | String streamId = sendRtpItem.getStreamId(); |
| 47 | Map<String, Object> param = new HashMap<>(); | 52 | Map<String, Object> param = new HashMap<>(); |
| @@ -50,6 +55,11 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor { | @@ -50,6 +55,11 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 50 | param.put("stream",streamId); | 55 | param.put("stream",streamId); |
| 51 | System.out.println("停止向上级推流:" + streamId); | 56 | System.out.println("停止向上级推流:" + streamId); |
| 52 | zlmrtpServerFactory.stopSendRtpStream(param); | 57 | zlmrtpServerFactory.stopSendRtpStream(param); |
| 58 | + redisCatchStorage.deleteSendRTPServer(platformGbId, channelId); | ||
| 59 | + if (zlmrtpServerFactory.totalReaderCount(streamId) == 0) { | ||
| 60 | + System.out.println(streamId + "无其它观看者,通知设备停止推流"); | ||
| 61 | + cmder.streamByeCmd(streamId); | ||
| 62 | + } | ||
| 53 | } | 63 | } |
| 54 | } catch (SipException e) { | 64 | } catch (SipException e) { |
| 55 | e.printStackTrace(); | 65 | e.printStackTrace(); |
| @@ -58,8 +68,6 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor { | @@ -58,8 +68,6 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 58 | } catch (ParseException e) { | 68 | } catch (ParseException e) { |
| 59 | e.printStackTrace(); | 69 | e.printStackTrace(); |
| 60 | } | 70 | } |
| 61 | - // TODO 优先级99 Bye Request消息实现,此消息一般为级联消息,上级给下级发送视频停止指令 | ||
| 62 | - | ||
| 63 | } | 71 | } |
| 64 | 72 | ||
| 65 | /*** | 73 | /*** |
| @@ -89,4 +97,13 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor { | @@ -89,4 +97,13 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 89 | public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) { | 97 | public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) { |
| 90 | this.zlmrtpServerFactory = zlmrtpServerFactory; | 98 | this.zlmrtpServerFactory = zlmrtpServerFactory; |
| 91 | } | 99 | } |
| 100 | + | ||
| 101 | + public ISIPCommander getSIPCommander() { | ||
| 102 | + return cmder; | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + public void setSIPCommander(ISIPCommander cmder) { | ||
| 106 | + this.cmder = cmder; | ||
| 107 | + } | ||
| 108 | + | ||
| 92 | } | 109 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
| @@ -75,20 +75,6 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { | @@ -75,20 +75,6 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 75 | SipURI sipURI = (SipURI) request.getRequestURI(); | 75 | SipURI sipURI = (SipURI) request.getRequestURI(); |
| 76 | String channelId = sipURI.getUser(); | 76 | String channelId = sipURI.getUser(); |
| 77 | String platformId = null; | 77 | String platformId = null; |
| 78 | -// SubjectHeader subjectHeader = (SubjectHeader)request.getHeader(SubjectHeader.NAME); | ||
| 79 | -// // 查询通道是否存在 不存在回复404 | ||
| 80 | -// if (subjectHeader != null) { // 存在则从subjectHeader 获取平台信息 | ||
| 81 | -// String subject = subjectHeader.getSubject(); | ||
| 82 | -// if (subject != null) { | ||
| 83 | -// String[] info1 = subject.split(","); | ||
| 84 | -// if (info1 != null && info1 .length == 2) { | ||
| 85 | -// String[] info2 = info1[1].split(":"); | ||
| 86 | -// if (info2 != null && info2.length == 2) { | ||
| 87 | -// platformId = info2[0]; | ||
| 88 | -// } | ||
| 89 | -// } | ||
| 90 | -// } | ||
| 91 | -// } | ||
| 92 | 78 | ||
| 93 | FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME); | 79 | FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME); |
| 94 | AddressImpl address = (AddressImpl) fromHeader.getAddress(); | 80 | AddressImpl address = (AddressImpl) fromHeader.getAddress(); |
| @@ -224,7 +210,9 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { | @@ -224,7 +210,9 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 224 | e.printStackTrace(); | 210 | e.printStackTrace(); |
| 225 | } | 211 | } |
| 226 | })); | 212 | })); |
| 227 | - playResult.getResult(); | 213 | + if (logger.isDebugEnabled()) { |
| 214 | + logger.debug(playResult.getResult().toString()); | ||
| 215 | + } | ||
| 228 | 216 | ||
| 229 | } catch (SipException | InvalidArgumentException | ParseException e) { | 217 | } catch (SipException | InvalidArgumentException | ParseException e) { |
| 230 | e.printStackTrace(); | 218 | e.printStackTrace(); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
| @@ -4,14 +4,22 @@ import java.io.ByteArrayInputStream; | @@ -4,14 +4,22 @@ import java.io.ByteArrayInputStream; | ||
| 4 | import java.text.ParseException; | 4 | import java.text.ParseException; |
| 5 | import java.util.*; | 5 | import java.util.*; |
| 6 | 6 | ||
| 7 | +import javax.sip.address.SipURI; | ||
| 8 | + | ||
| 7 | import javax.sip.header.FromHeader; | 9 | import javax.sip.header.FromHeader; |
| 10 | +import javax.sip.header.HeaderAddress; | ||
| 11 | +import javax.sip.header.ToHeader; | ||
| 8 | import javax.sip.InvalidArgumentException; | 12 | import javax.sip.InvalidArgumentException; |
| 13 | +import javax.sip.ListeningPoint; | ||
| 14 | +import javax.sip.ObjectInUseException; | ||
| 9 | import javax.sip.RequestEvent; | 15 | import javax.sip.RequestEvent; |
| 10 | import javax.sip.SipException; | 16 | import javax.sip.SipException; |
| 17 | +import javax.sip.SipProvider; | ||
| 11 | import javax.sip.message.Request; | 18 | import javax.sip.message.Request; |
| 12 | import javax.sip.message.Response; | 19 | import javax.sip.message.Response; |
| 13 | 20 | ||
| 14 | import com.alibaba.fastjson.JSONObject; | 21 | import com.alibaba.fastjson.JSONObject; |
| 22 | +import com.genersoft.iot.vmp.VManageBootstrap; | ||
| 15 | import com.genersoft.iot.vmp.common.StreamInfo; | 23 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 16 | import com.genersoft.iot.vmp.common.VideoManagerConstants; | 24 | import com.genersoft.iot.vmp.common.VideoManagerConstants; |
| 17 | import com.genersoft.iot.vmp.conf.UserSetup; | 25 | import com.genersoft.iot.vmp.conf.UserSetup; |
| @@ -34,6 +42,7 @@ import com.genersoft.iot.vmp.utils.SpringBeanFactory; | @@ -34,6 +42,7 @@ import com.genersoft.iot.vmp.utils.SpringBeanFactory; | ||
| 34 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; | 42 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| 35 | import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce; | 43 | import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce; |
| 36 | 44 | ||
| 45 | +import gov.nist.javax.sip.SipStackImpl; | ||
| 37 | import gov.nist.javax.sip.address.AddressImpl; | 46 | import gov.nist.javax.sip.address.AddressImpl; |
| 38 | import gov.nist.javax.sip.address.SipUri; | 47 | import gov.nist.javax.sip.address.SipUri; |
| 39 | 48 | ||
| @@ -114,10 +123,10 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { | @@ -114,10 +123,10 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 114 | logger.info("接收到Catalog消息"); | 123 | logger.info("接收到Catalog消息"); |
| 115 | processMessageCatalogList(evt); | 124 | processMessageCatalogList(evt); |
| 116 | } else if (MESSAGE_DEVICE_INFO.equals(cmd)) { | 125 | } else if (MESSAGE_DEVICE_INFO.equals(cmd)) { |
| 117 | - logger.info("接收到DeviceInfo消息"); | 126 | + //DeviceInfo消息处理 |
| 118 | processMessageDeviceInfo(evt); | 127 | processMessageDeviceInfo(evt); |
| 119 | } else if (MESSAGE_DEVICE_STATUS.equals(cmd)) { | 128 | } else if (MESSAGE_DEVICE_STATUS.equals(cmd)) { |
| 120 | - logger.info("接收到DeviceStatus消息"); | 129 | + // DeviceStatus消息处理 |
| 121 | processMessageDeviceStatus(evt); | 130 | processMessageDeviceStatus(evt); |
| 122 | } else if (MESSAGE_DEVICE_CONTROL.equals(cmd)) { | 131 | } else if (MESSAGE_DEVICE_CONTROL.equals(cmd)) { |
| 123 | logger.info("接收到DeviceControl消息"); | 132 | logger.info("接收到DeviceControl消息"); |
| @@ -211,27 +220,48 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { | @@ -211,27 +220,48 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 211 | private void processMessageDeviceStatus(RequestEvent evt) { | 220 | private void processMessageDeviceStatus(RequestEvent evt) { |
| 212 | try { | 221 | try { |
| 213 | Element rootElement = getRootElement(evt); | 222 | Element rootElement = getRootElement(evt); |
| 214 | - String deviceId = XmlUtil.getText(rootElement, "DeviceID"); | ||
| 215 | - // 检查设备是否存在, 不存在则不回复 | ||
| 216 | - if (storager.exists(deviceId)) { | ||
| 217 | - // 回复200 OK | ||
| 218 | - responseAck(evt); | ||
| 219 | - JSONObject json = new JSONObject(); | ||
| 220 | - XmlUtil.node2Json(rootElement, json); | ||
| 221 | - if (logger.isDebugEnabled()) { | ||
| 222 | - logger.debug(json.toJSONString()); | ||
| 223 | - } | ||
| 224 | - RequestMessage msg = new RequestMessage(); | ||
| 225 | - msg.setDeviceId(deviceId); | ||
| 226 | - msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS); | ||
| 227 | - msg.setData(json); | ||
| 228 | - deferredResultHolder.invokeResult(msg); | 223 | + String name = rootElement.getName(); |
| 224 | + Element deviceIdElement = rootElement.element("DeviceID"); | ||
| 225 | + String deviceId = deviceIdElement.getText(); | ||
| 229 | 226 | ||
| 230 | - if (offLineDetector.isOnline(deviceId)) { | ||
| 231 | - publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE); | 227 | + if (name.equalsIgnoreCase("Query")) { // 区分是Response——查询响应,还是Query——查询请求 |
| 228 | + logger.info("接收到DeviceStatus查询消息"); | ||
| 229 | + FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); | ||
| 230 | + String platformId = ((SipUri) fromHeader.getAddress().getURI()).getUser(); | ||
| 231 | + if (platformId == null) { | ||
| 232 | + response404Ack(evt); | ||
| 233 | + return; | ||
| 232 | } else { | 234 | } else { |
| 235 | + // 回复200 OK | ||
| 236 | + responseAck(evt); | ||
| 237 | + String sn = rootElement.element("SN").getText(); | ||
| 238 | + ParentPlatform parentPlatform = storager.queryParentPlatById(platformId); | ||
| 239 | + cmderFroPlatform.deviceStatusResponse(parentPlatform, sn, fromHeader.getTag()); | ||
| 240 | + } | ||
| 241 | + } else { | ||
| 242 | + logger.info("接收到DeviceStatus应答消息"); | ||
| 243 | + // 检查设备是否存在, 不存在则不回复 | ||
| 244 | + if (storager.exists(deviceId)) { | ||
| 245 | + // 回复200 OK | ||
| 246 | + responseAck(evt); | ||
| 247 | + JSONObject json = new JSONObject(); | ||
| 248 | + XmlUtil.node2Json(rootElement, json); | ||
| 249 | + if (logger.isDebugEnabled()) { | ||
| 250 | + logger.debug(json.toJSONString()); | ||
| 251 | + } | ||
| 252 | + RequestMessage msg = new RequestMessage(); | ||
| 253 | + msg.setDeviceId(deviceId); | ||
| 254 | + msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS); | ||
| 255 | + msg.setData(json); | ||
| 256 | + deferredResultHolder.invokeResult(msg); | ||
| 257 | + | ||
| 258 | + if (offLineDetector.isOnline(deviceId)) { | ||
| 259 | + publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE); | ||
| 260 | + } else { | ||
| 261 | + } | ||
| 233 | } | 262 | } |
| 234 | } | 263 | } |
| 264 | + | ||
| 235 | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { | 265 | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { |
| 236 | e.printStackTrace(); | 266 | e.printStackTrace(); |
| 237 | } | 267 | } |
| @@ -263,6 +293,51 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { | @@ -263,6 +293,51 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 263 | deferredResultHolder.invokeResult(msg); | 293 | deferredResultHolder.invokeResult(msg); |
| 264 | } else { | 294 | } else { |
| 265 | // 此处是上级发出的DeviceControl指令 | 295 | // 此处是上级发出的DeviceControl指令 |
| 296 | + String platformId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); | ||
| 297 | + String targetGBId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); | ||
| 298 | + // 远程启动功能 | ||
| 299 | + if (!XmlUtil.isEmpty(XmlUtil.getText(rootElement, "TeleBoot"))) { | ||
| 300 | + if (deviceId.equals(targetGBId)) { | ||
| 301 | + // 远程启动功能:需要在重新启动程序后先对SipStack解绑 | ||
| 302 | + logger.info("执行远程启动本平台命令"); | ||
| 303 | + ParentPlatform parentPlatform = storager.queryParentPlatById(platformId); | ||
| 304 | + cmderFroPlatform.unregister(parentPlatform, null, null); | ||
| 305 | + | ||
| 306 | + Thread restartThread = new Thread(new Runnable() { | ||
| 307 | + @Override | ||
| 308 | + public void run() { | ||
| 309 | + try { | ||
| 310 | + Thread.sleep(3000); | ||
| 311 | + SipProvider up = (SipProvider) SpringBeanFactory.getBean("udpSipProvider"); | ||
| 312 | + SipStackImpl stack = (SipStackImpl)up.getSipStack(); | ||
| 313 | + stack.stop(); | ||
| 314 | + Iterator listener = stack.getListeningPoints(); | ||
| 315 | + while (listener.hasNext()) { | ||
| 316 | + stack.deleteListeningPoint((ListeningPoint) listener.next()); | ||
| 317 | + } | ||
| 318 | + Iterator providers = stack.getSipProviders(); | ||
| 319 | + while (providers.hasNext()) { | ||
| 320 | + stack.deleteSipProvider((SipProvider) providers.next()); | ||
| 321 | + } | ||
| 322 | + VManageBootstrap.restart(); | ||
| 323 | + } catch (InterruptedException ignored) { | ||
| 324 | + } catch (ObjectInUseException e) { | ||
| 325 | + e.printStackTrace(); | ||
| 326 | + } | ||
| 327 | + } | ||
| 328 | + }); | ||
| 329 | + | ||
| 330 | + restartThread.setDaemon(false); | ||
| 331 | + restartThread.start(); | ||
| 332 | + } else { | ||
| 333 | + // 远程启动指定设备 | ||
| 334 | + } | ||
| 335 | + } | ||
| 336 | + if (!XmlUtil.isEmpty(XmlUtil.getText(rootElement,"PTZCmd")) && !deviceId.equals(targetGBId)) { | ||
| 337 | + String cmdString = XmlUtil.getText(rootElement,"PTZCmd"); | ||
| 338 | + Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, deviceId); | ||
| 339 | + cmder.fronEndCmd(device, deviceId, cmdString); | ||
| 340 | + } | ||
| 266 | } | 341 | } |
| 267 | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { | 342 | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { |
| 268 | e.printStackTrace(); | 343 | e.printStackTrace(); |
| @@ -374,9 +449,21 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { | @@ -374,9 +449,21 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 374 | Element deviceIdElement = rootElement.element("DeviceID"); | 449 | Element deviceIdElement = rootElement.element("DeviceID"); |
| 375 | String deviceId = deviceIdElement.getTextTrim().toString(); | 450 | String deviceId = deviceIdElement.getTextTrim().toString(); |
| 376 | if (requestName.equals("Query")) { | 451 | if (requestName.equals("Query")) { |
| 377 | - // 回复200 OK | ||
| 378 | - responseAck(evt); | 452 | + logger.info("接收到DeviceInfo查询消息"); |
| 453 | + FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); | ||
| 454 | + String platformId = ((SipUri) fromHeader.getAddress().getURI()).getUser(); | ||
| 455 | + if (platformId == null) { | ||
| 456 | + response404Ack(evt); | ||
| 457 | + return; | ||
| 458 | + } else { | ||
| 459 | + // 回复200 OK | ||
| 460 | + responseAck(evt); | ||
| 461 | + String sn = rootElement.element("SN").getText(); | ||
| 462 | + ParentPlatform parentPlatform = storager.queryParentPlatById(platformId); | ||
| 463 | + cmderFroPlatform.deviceInfoResponse(parentPlatform, sn, fromHeader.getTag()); | ||
| 464 | + } | ||
| 379 | } else { | 465 | } else { |
| 466 | + logger.info("接收到DeviceInfo应答消息"); | ||
| 380 | Device device = storager.queryVideoDevice(deviceId); | 467 | Device device = storager.queryVideoDevice(deviceId); |
| 381 | if (device == null) { | 468 | if (device == null) { |
| 382 | return; | 469 | return; |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java
| @@ -60,16 +60,17 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor { | @@ -60,16 +60,17 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor { | ||
| 60 | logger.info(String.format("未找到callId: %s 的注册/注销平台id", callId )); | 60 | logger.info(String.format("未找到callId: %s 的注册/注销平台id", callId )); |
| 61 | return; | 61 | return; |
| 62 | } | 62 | } |
| 63 | - logger.info(String.format("收到 %s 的注册/注销%S响应", platformGBId, response.getStatusCode() )); | ||
| 64 | 63 | ||
| 65 | ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(platformGBId); | 64 | ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(platformGBId); |
| 66 | if (parentPlatformCatch == null) { | 65 | if (parentPlatformCatch == null) { |
| 67 | logger.warn(String.format("收到 %s 的注册/注销%S请求, 但是平台缓存信息未查询到!!!", platformGBId, response.getStatusCode())); | 66 | logger.warn(String.format("收到 %s 的注册/注销%S请求, 但是平台缓存信息未查询到!!!", platformGBId, response.getStatusCode())); |
| 68 | return; | 67 | return; |
| 69 | } | 68 | } |
| 69 | + String action = parentPlatformCatch.getParentPlatform().getExpires().equals("0") ? "注销" : "注册"; | ||
| 70 | + logger.info(String.format("收到 %s %s的%S响应", platformGBId, action, response.getStatusCode() )); | ||
| 70 | ParentPlatform parentPlatform = parentPlatformCatch.getParentPlatform(); | 71 | ParentPlatform parentPlatform = parentPlatformCatch.getParentPlatform(); |
| 71 | if (parentPlatform == null) { | 72 | if (parentPlatform == null) { |
| 72 | - logger.warn(String.format("收到 %s 的注册/注销%S请求, 但是平台信息未查询到!!!", platformGBId, response.getStatusCode())); | 73 | + logger.warn(String.format("收到 %s %s的%S请求, 但是平台信息未查询到!!!", platformGBId, action, response.getStatusCode())); |
| 73 | return; | 74 | return; |
| 74 | } | 75 | } |
| 75 | 76 | ||
| @@ -77,11 +78,16 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor { | @@ -77,11 +78,16 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor { | ||
| 77 | WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME); | 78 | WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME); |
| 78 | sipCommanderForPlatform.register(parentPlatform, callId, www, null, null); | 79 | sipCommanderForPlatform.register(parentPlatform, callId, www, null, null); |
| 79 | }else if (response.getStatusCode() == 200){ | 80 | }else if (response.getStatusCode() == 200){ |
| 80 | - // 注册成功 | ||
| 81 | - logger.info(String.format("%s 注册成功", platformGBId )); | 81 | + // 注册/注销成功 |
| 82 | + logger.info(String.format("%s %s成功", platformGBId, action)); | ||
| 82 | redisCatchStorage.delPlatformRegisterInfo(callId); | 83 | redisCatchStorage.delPlatformRegisterInfo(callId); |
| 83 | parentPlatform.setStatus(true); | 84 | parentPlatform.setStatus(true); |
| 85 | + // 取回Expires设置,避免注销过程中被置为0 | ||
| 86 | + ParentPlatform parentPlatformTmp = storager.queryParentPlatById(platformGBId); | ||
| 87 | + String expires = parentPlatformTmp.getExpires(); | ||
| 88 | + parentPlatform.setExpires(expires); | ||
| 84 | storager.updateParentPlatform(parentPlatform); | 89 | storager.updateParentPlatform(parentPlatform); |
| 90 | + | ||
| 85 | redisCatchStorage.updatePlatformRegister(parentPlatform); | 91 | redisCatchStorage.updatePlatformRegister(parentPlatform); |
| 86 | 92 | ||
| 87 | redisCatchStorage.updatePlatformKeepalive(parentPlatform); | 93 | redisCatchStorage.updatePlatformKeepalive(parentPlatform); |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
| @@ -267,20 +267,25 @@ public class ZLMHttpHookListener { | @@ -267,20 +267,25 @@ public class ZLMHttpHookListener { | ||
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | String streamId = json.getString("stream"); | 269 | String streamId = json.getString("stream"); |
| 270 | - | ||
| 271 | - cmder.streamByeCmd(streamId); | ||
| 272 | StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); | 270 | StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); |
| 273 | - if (streamInfo!=null){ | ||
| 274 | - redisCatchStorage.stopPlay(streamInfo); | ||
| 275 | - storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); | 271 | + |
| 272 | + JSONObject ret = new JSONObject(); | ||
| 273 | + ret.put("code", 0); | ||
| 274 | + ret.put("close", true); | ||
| 275 | + | ||
| 276 | + if (streamInfo != null) { | ||
| 277 | + if (redisCatchStorage.isChannelSendingRTP(streamInfo.getChannelId())) { | ||
| 278 | + ret.put("close", false); | ||
| 279 | + } else { | ||
| 280 | + cmder.streamByeCmd(streamId); | ||
| 281 | + redisCatchStorage.stopPlay(streamInfo); | ||
| 282 | + storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); | ||
| 283 | + } | ||
| 276 | }else{ | 284 | }else{ |
| 285 | + cmder.streamByeCmd(streamId); | ||
| 277 | streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); | 286 | streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); |
| 278 | redisCatchStorage.stopPlayback(streamInfo); | 287 | redisCatchStorage.stopPlayback(streamInfo); |
| 279 | } | 288 | } |
| 280 | - | ||
| 281 | - JSONObject ret = new JSONObject(); | ||
| 282 | - ret.put("code", 0); | ||
| 283 | - ret.put("close", true); | ||
| 284 | return new ResponseEntity<String>(ret.toString(),HttpStatus.OK); | 289 | return new ResponseEntity<String>(ret.toString(),HttpStatus.OK); |
| 285 | } | 290 | } |
| 286 | 291 |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
| @@ -153,6 +153,16 @@ public class ZLMRTPServerFactory { | @@ -153,6 +153,16 @@ public class ZLMRTPServerFactory { | ||
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | /** | 155 | /** |
| 156 | + * 查询转推的流是否有其它观看者 | ||
| 157 | + * @param streamId | ||
| 158 | + * @return | ||
| 159 | + */ | ||
| 160 | + public int totalReaderCount(String streamId) { | ||
| 161 | + JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo("rtp", "rtmp", streamId); | ||
| 162 | + return mediaInfo.getInteger("totalReaderCount"); | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + /** | ||
| 156 | * 调用zlm RESTful API —— stopSendRtp | 166 | * 调用zlm RESTful API —— stopSendRtp |
| 157 | */ | 167 | */ |
| 158 | public Boolean stopSendRtpStream(Map<String, Object>param) { | 168 | public Boolean stopSendRtpStream(Map<String, Object>param) { |
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
| @@ -89,4 +89,17 @@ public interface IRedisCatchStorage { | @@ -89,4 +89,17 @@ public interface IRedisCatchStorage { | ||
| 89 | */ | 89 | */ |
| 90 | SendRtpItem querySendRTPServer(String platformGbId, String channelId); | 90 | SendRtpItem querySendRTPServer(String platformGbId, String channelId); |
| 91 | 91 | ||
| 92 | + /** | ||
| 93 | + * 删除RTP推送信息缓存 | ||
| 94 | + * @param platformGbId | ||
| 95 | + * @param channelId | ||
| 96 | + */ | ||
| 97 | + void deleteSendRTPServer(String platformGbId, String channelId); | ||
| 98 | + | ||
| 99 | + /** | ||
| 100 | + * 查询某个通道是否存在上级点播(RTP推送) | ||
| 101 | + * @param channelId | ||
| 102 | + */ | ||
| 103 | + boolean isChannelSendingRTP(String channelId); | ||
| 104 | + | ||
| 92 | } | 105 | } |
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
| @@ -225,4 +225,30 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { | @@ -225,4 +225,30 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { | ||
| 225 | return (SendRtpItem)redis.get(key); | 225 | return (SendRtpItem)redis.get(key); |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | + /** | ||
| 229 | + * 删除RTP推送信息缓存 | ||
| 230 | + * @param platformGbId | ||
| 231 | + * @param channelId | ||
| 232 | + */ | ||
| 233 | + @Override | ||
| 234 | + public void deleteSendRTPServer(String platformGbId, String channelId) { | ||
| 235 | + String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + platformGbId + "_" + channelId; | ||
| 236 | + redis.del(key); | ||
| 237 | + } | ||
| 238 | + | ||
| 239 | + /** | ||
| 240 | + * 查询某个通道是否存在上级点播(RTP推送) | ||
| 241 | + * @param channelId | ||
| 242 | + */ | ||
| 243 | + @Override | ||
| 244 | + public boolean isChannelSendingRTP(String channelId) { | ||
| 245 | + String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + "*_" + channelId; | ||
| 246 | + List<Object> RtpStreams = redis.scan(key); | ||
| 247 | + if (RtpStreams.size() > 0) { | ||
| 248 | + return true; | ||
| 249 | + } else { | ||
| 250 | + return false; | ||
| 251 | + } | ||
| 252 | + } | ||
| 253 | + | ||
| 228 | } | 254 | } |
src/main/java/com/genersoft/iot/vmp/vmanager/platform/PlatformController.java
| @@ -60,7 +60,7 @@ public class PlatformController { | @@ -60,7 +60,7 @@ public class PlatformController { | ||
| 60 | public ResponseEntity<String> savePlatform(@RequestBody ParentPlatform parentPlatform){ | 60 | public ResponseEntity<String> savePlatform(@RequestBody ParentPlatform parentPlatform){ |
| 61 | 61 | ||
| 62 | if (logger.isDebugEnabled()) { | 62 | if (logger.isDebugEnabled()) { |
| 63 | - logger.debug("查询所有上级设备API调用"); | 63 | + logger.debug("保存上级平台信息API调用"); |
| 64 | } | 64 | } |
| 65 | if (StringUtils.isEmpty(parentPlatform.getName()) | 65 | if (StringUtils.isEmpty(parentPlatform.getName()) |
| 66 | ||StringUtils.isEmpty(parentPlatform.getServerGBId()) | 66 | ||StringUtils.isEmpty(parentPlatform.getServerGBId()) |
| @@ -87,13 +87,13 @@ public class PlatformController { | @@ -87,13 +87,13 @@ public class PlatformController { | ||
| 87 | if (parentPlatform.isEnable()) { | 87 | if (parentPlatform.isEnable()) { |
| 88 | // 只要保存就发送注册 | 88 | // 只要保存就发送注册 |
| 89 | commanderForPlatform.register(parentPlatform); | 89 | commanderForPlatform.register(parentPlatform); |
| 90 | - }else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()){ // 关闭启用时注销 | 90 | + } else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()){ // 关闭启用时注销 |
| 91 | commanderForPlatform.unregister(parentPlatform, null, null); | 91 | commanderForPlatform.unregister(parentPlatform, null, null); |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | - | 94 | + |
| 95 | return new ResponseEntity<>("success", HttpStatus.OK); | 95 | return new ResponseEntity<>("success", HttpStatus.OK); |
| 96 | - }else { | 96 | + } else { |
| 97 | return new ResponseEntity<>("fail", HttpStatus.OK); | 97 | return new ResponseEntity<>("fail", HttpStatus.OK); |
| 98 | } | 98 | } |
| 99 | } | 99 | } |
| @@ -103,7 +103,7 @@ public class PlatformController { | @@ -103,7 +103,7 @@ public class PlatformController { | ||
| 103 | public ResponseEntity<String> deletePlatform(@RequestBody ParentPlatform parentPlatform){ | 103 | public ResponseEntity<String> deletePlatform(@RequestBody ParentPlatform parentPlatform){ |
| 104 | 104 | ||
| 105 | if (logger.isDebugEnabled()) { | 105 | if (logger.isDebugEnabled()) { |
| 106 | - logger.debug("查询所有上级设备API调用"); | 106 | + logger.debug("删除上级平台API调用"); |
| 107 | } | 107 | } |
| 108 | if (StringUtils.isEmpty(parentPlatform.getServerGBId()) | 108 | if (StringUtils.isEmpty(parentPlatform.getServerGBId()) |
| 109 | ){ | 109 | ){ |
| @@ -138,7 +138,7 @@ public class PlatformController { | @@ -138,7 +138,7 @@ public class PlatformController { | ||
| 138 | public ResponseEntity<String> exitPlatform(@PathVariable String deviceGbId){ | 138 | public ResponseEntity<String> exitPlatform(@PathVariable String deviceGbId){ |
| 139 | 139 | ||
| 140 | if (logger.isDebugEnabled()) { | 140 | if (logger.isDebugEnabled()) { |
| 141 | - logger.debug("查询所有上级设备API调用"); | 141 | + logger.debug("查询上级平台是否存在API调用:" + deviceGbId); |
| 142 | } | 142 | } |
| 143 | ParentPlatform parentPlatform = storager.queryParentPlatById(deviceGbId); | 143 | ParentPlatform parentPlatform = storager.queryParentPlatById(deviceGbId); |
| 144 | return new ResponseEntity<>(String.valueOf(parentPlatform != null), HttpStatus.OK); | 144 | return new ResponseEntity<>(String.valueOf(parentPlatform != null), HttpStatus.OK); |
| @@ -184,7 +184,7 @@ public class PlatformController { | @@ -184,7 +184,7 @@ public class PlatformController { | ||
| 184 | public ResponseEntity<String> delChannelForGB(@RequestBody UpdateChannelParam param){ | 184 | public ResponseEntity<String> delChannelForGB(@RequestBody UpdateChannelParam param){ |
| 185 | 185 | ||
| 186 | if (logger.isDebugEnabled()) { | 186 | if (logger.isDebugEnabled()) { |
| 187 | - logger.debug("给上级平台添加国标通道API调用"); | 187 | + logger.debug("给上级平台删除国标通道API调用"); |
| 188 | } | 188 | } |
| 189 | int result = storager.delChannelForGB(param.getPlatformId(), param.getChannelReduces()); | 189 | int result = storager.delChannelForGB(param.getPlatformId(), param.getChannelReduces()); |
| 190 | 190 |
src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java
| @@ -86,6 +86,9 @@ public class PlayServiceImpl implements IPlayService { | @@ -86,6 +86,9 @@ public class PlayServiceImpl implements IPlayService { | ||
| 86 | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); | 86 | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); |
| 87 | msg.setData(JSON.toJSONString(streamInfo)); | 87 | msg.setData(JSON.toJSONString(streamInfo)); |
| 88 | resultHolder.invokeResult(msg); | 88 | resultHolder.invokeResult(msg); |
| 89 | + if (hookEvent != null) { | ||
| 90 | + hookEvent.response(JSONObject.parseObject(JSON.toJSONString(streamInfo))); | ||
| 91 | + } | ||
| 89 | } else { | 92 | } else { |
| 90 | redisCatchStorage.stopPlay(streamInfo); | 93 | redisCatchStorage.stopPlay(streamInfo); |
| 91 | storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); | 94 | storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); |