Commit 30ae9e929fad80f624ab632c53081db3d2dc9aec
合并主线
Showing
64 changed files
with
2275 additions
and
1052 deletions
Too many changes to show.
To preserve performance only 64 of 128 files are displayed.
.github/ISSUE_TEMPLATE/--bug---.md renamed to .github/ISSUE_TEMPLATE/bug.md
| 1 | 1 | --- |
| 2 | 2 | name: "[ BUG ] " |
| 3 | -about: Create a report to help us improve | |
| 4 | -title: '' | |
| 5 | -labels: '' | |
| 3 | +about: 关于wvp的bug,与zlm有关的建议直接在zlm的issue中提问 | |
| 4 | +title: 'BUG' | |
| 5 | +labels: 'wvp的bug' | |
| 6 | 6 | assignees: '' |
| 7 | 7 | |
| 8 | 8 | --- |
| 9 | 9 | |
| 10 | +**环境信息:** | |
| 11 | + | |
| 12 | + - 1. 部署方式 wvp-pro docker / zlm(docker) + 编译wvp-pro/ wvp-prp + zlm都是编译部署/ | |
| 13 | + - 2. 部署环境 windows / ubuntu/ centos ... | |
| 14 | + - 3. 端口开放情况 | |
| 15 | + - 4. 是否是公网部署 | |
| 16 | + - 5. 是否使用https | |
| 17 | + - 6. 方便的话提供下使用的设备品牌或平台 | |
| 18 | + - 7. 你做过哪些尝试 | |
| 19 | + - 8. 代码更新时间 | |
| 20 | + | |
| 10 | 21 | **描述错误** |
| 11 | 22 | 描述下您遇到的问题 |
| 12 | 23 | |
| 13 | 24 | **如何复现** |
| 14 | 25 | 有明确复现步骤的问题会很容易被解决 |
| 15 | 26 | |
| 16 | -**预期行为** | |
| 17 | -清晰简洁的描述您期望发生的事情 | |
| 27 | +**截图** | |
| 18 | 28 | |
| 19 | -**截图** | |
| 29 | +**抓包文件** | |
| 30 | + | |
| 31 | +**日志** | |
| 32 | +``` | |
| 33 | +日志内容放这里, 文件的话请直接上传 | |
| 34 | +``` | |
| 20 | 35 | |
| 21 | 36 | |
| 22 | -**环境信息:** | |
| 23 | - - 1. 部署方式 wvp-pro docker / zlm(docker) + 编译wvp-pro/ wvp-prp + zlm都是编译部署/ | |
| 24 | - - 2. 部署环境 windows / ubuntu/ centos ... | |
| 25 | - - 3. 端口开放情况 | |
| 26 | - - 4. 是否是公网部署 | |
| 27 | - - 5. 是否使用https | |
| 28 | - - 6. 方便的话提供下使用的设备品牌或平台 | |
| 29 | - - 7. 你做过哪些尝试 | ... | ... |
.github/ISSUE_TEMPLATE/-------.md renamed to .github/ISSUE_TEMPLATE/new.md
.github/ISSUE_TEMPLATE/solve.md
0 → 100644
| 1 | +--- | |
| 2 | +name: "[ 技术咨询 ] " | |
| 3 | +about: 对于使用中遇到问题 | |
| 4 | +title: '技术咨询' | |
| 5 | +labels: '技术咨询' | |
| 6 | +assignees: '' | |
| 7 | + | |
| 8 | +--- | |
| 9 | + | |
| 10 | +**环境信息:** | |
| 11 | + | |
| 12 | + - 1. 部署方式 wvp-pro docker / zlm(docker) + 编译wvp-pro/ wvp-prp + zlm都是编译部署/ | |
| 13 | + - 2. 部署环境 windows / ubuntu/ centos ... | |
| 14 | + - 3. 端口开放情况 | |
| 15 | + - 4. 是否是公网部署 | |
| 16 | + - 5. 是否使用https | |
| 17 | + - 6. 方便的话提供下使用的设备品牌或平台 | |
| 18 | + - 7. 你做过哪些尝试 | |
| 19 | + - 8. 代码更新时间 | |
| 20 | + | |
| 21 | + | |
| 22 | +**内容描述:** | |
| 23 | + | |
| 24 | +**截图** | |
| 25 | + | |
| 26 | +**抓包文件** | |
| 27 | + | |
| 28 | +**日志** | |
| 29 | +``` | |
| 30 | +日志内容放这里, 文件的话请直接上传 | |
| 31 | +``` | ... | ... |
README.md
| ... | ... | @@ -15,17 +15,21 @@ WEB VIDEO PLATFORM銝銝芸鈭B28181-2016蝞勗 |
| 15 | 15 | 垢憿菟鈭Kyle MediaServerUI [https://gitee.com/kkkkk5G/MediaServerUI](https://gitee.com/kkkkk5G/MediaServerUI) 餈耨. |
| 16 | 16 | |
| 17 | 17 | # 摨嚗 |
| 18 | -辣仍閫 | |
| 19 | -像VR蝑挽憭 | |
| 18 | +辣仍閫 | |
| 19 | +挽憭(像VR蝑)霈曉 | |
| 20 | +(onvif, rtsp, rtmp嚗霈曉)霈曉嚗 | |
| 20 | 21 | 漣像蝥扯楊蝵 |
| 21 | -tsp/rtmp蝑蓮像 | |
| 22 | -tsp/rtmp蝑瘚蓮像 | |
| 22 | +楊蝵撟喳鈭 | |
| 23 | 23 | |
| 24 | -# 憿寧 | |
| 25 | -銝芣蔭,蝙,靘蹂輕28181縑隞斤頂蝏, 靘皞獢ZLMediaKit, 摰銝銝芸GB28181撟喳. | |
| 26 | 24 | |
| 27 | -# 蝵脫﹝ | |
| 28 | -[doc.wvp-pro.cn](https://doc.wvp-pro.cn) | |
| 25 | +# ﹝ | |
| 26 | +wvp雿輻﹝ [https://doc.wvp-pro.cn](https://doc.wvp-pro.cn) | |
| 27 | +ZLM雿輻﹝ [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit) | |
| 28 | +> wvp﹝gitee嚗霂瑕活 | |
| 29 | + | |
| 30 | +# 蝷曄黎 | |
| 31 | +[](https://t.zsxq.com/0d8VAD3Dm) | |
| 32 | +> 韐寞銝箔憟賜嚗撖嫣憭抒銝予隞亦縑凝靽∪嚗之摰嗅蝢扎銝予說隞亦甈橘之摰嗡閬▽憳予銋銝隞乓 | |
| 29 | 33 | |
| 30 | 34 | # gitee郊隞 |
| 31 | 35 | https://gitee.com/pan648540858/wvp-GB28181-pro.git |
| ... | ... | @@ -100,23 +104,17 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git |
| 100 | 104 | - [X] 鈭垢敶瘚/隞/隞亙鈭垢嚗蝸 |
| 101 | 105 | - [X] 銵arar |
| 102 | 106 | - [X] 楊窈瘙垢氖蝵 |
| 103 | - | |
| 104 | - | |
| 105 | -# 憸圾 | |
| 106 | -暻餌鈭挽憭摰寞改隞仿閬之挽憭瘚挽憭偌撟單隞仿憸 | |
| 107 | -1. ﹝蝵粉隞亙葬雿憸 | |
| 108 | -2. 揣issues嚗之 | |
| 109 | -3. Q蝢歹901799015嚗之敹撈嚗撣歇蝏粉鈭iki揣鈭ssues | |
| 110 | -4. 雿隞亥窈雿蛹雿圾蝑晶 | |
| 111 | -5. 雿隞交憸挽憭隞交摰寞摰寡挽憭圾憸 | |
| 112 | - | |
| 113 | -# 雿輻撣桀 | |
| 114 | -QQ蝢: 901799015, ZLM雿輻﹝[https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit) | |
| 115 | -QQ蝘縑銝銝, 蝎曉.甈Z之摰嗅蝢日悄霈.閫★撖嫣葬嚗洽餈tar漱pr | |
| 116 | 107 | |
| 117 | 108 | # 悅 |
| 118 | 109 | 憿寧誨蝙摰賣IT悅嚗靽縑銝隞亥摨鈭★ 雿憿寧銋蝣蝙鈭鈭隞皞誨銝窈銵隞嚗 鈭蝙憿寧漣熒噩蛹銝璁憿寧嚗窈銵 雿輻憿寧隞嚗砲悅銝剖銵冽憿寧靘洵銝摨悅 |
| 119 | 110 | |
| 111 | +# | |
| 112 | + | |
| 113 | +[霂(https://t.zsxq.com/0d8VAD3Dm)銝”嚗 | |
| 114 | +- [雿輻蝟餃嚗VP-PRO銋(https://t.zsxq.com/0dLguVoSp) | |
| 115 | + | |
| 116 | +窈隞嗅648540858@qq.com | |
| 117 | + | |
| 120 | 118 | # 靚 |
| 121 | 119 | 陝雿憭(https://github.com/xia-chu) 皞獢,撟嗅撘葉蝏葬 |
| 122 | 120 | 陝雿dexter langhuihui](https://github.com/langhuihui) 撘皞末EB |
| ... | ... | @@ -128,7 +126,6 @@ QQ蝘縑銝銝, 蝎曉.甈Z之摰嗅蝢日悄霈.閫★撖嫣 |
| 128 | 126 | [ydpd](https://github.com/ydpd) [szy833](https://github.com/szy833) [ydwxb](https://github.com/ydwxb) [Albertzhu666](https://github.com/Albertzhu666) |
| 129 | 127 | [mk1990](https://github.com/mk1990) [SaltFish001](https://github.com/SaltFish001) |
| 130 | 128 | |
| 131 | -ps: 葵摰鈭之雿穿洽餈之雿祈頂溶 | |
| 132 | 129 | |
| 133 | 130 | ffmpeg -re -i 123.mp3 -acodec pcm_alaw -ar 8000 -ac 1 -f rtsp rtsp://192.168.1.3:30554/broadcast/34020000001320000101_34020000001310000001 |
| 134 | 131 | ... | ... |
doc/README.md
| ... | ... | @@ -14,6 +14,10 @@ |
| 14 | 14 | - 完全开源,且使用MIT许可协议。保留版权的情况下可以用于商业项目。 |
| 15 | 15 | - 支持多流媒体节点负载均衡。 |
| 16 | 16 | |
| 17 | +# 社群 | |
| 18 | +[](https://t.zsxq.com/0d8VAD3Dm) | |
| 19 | +> 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。 | |
| 20 | + | |
| 17 | 21 | # 我们实现了哪些国标功能 |
| 18 | 22 | **作为上级平台** |
| 19 | 23 | - [X] 注册 | ... | ... |
doc/_content/ability/_media/img_16.png
doc/_content/qa/bug.md
| ... | ... | @@ -2,18 +2,11 @@ |
| 2 | 2 | # 反馈bug |
| 3 | 3 | 代码是在不断的完善的,不断修改会修复旧的问题也有可能引入新的问题,所以遇到BUG是很正常的一件事。所以遇到问题不要烦燥,咱们就事论事就好了。 |
| 4 | 4 | ## 如何反馈 |
| 5 | -1. 更新代码,很可能你遇到问题别人已经更早的遇到了,或者是作者自己发现了,已经解决了,所以你可以更新代码再次进行测试; | |
| 6 | -2. 可以在github提ISSUE,我几乎每天都会去看issue,你的问题我会尽快给予答复; | |
| 7 | -3. 你可以来我的QQ群里,询问群友看看是否遇到了同样的问题; | |
| 8 | -4. 你可以私聊我的QQ,如果我有时间我会给你答复,但是除非你有明确的复现步骤或者修复方案,否则你可能等不到我的答复。 | |
| 9 | - | |
| 10 | -## 如何快速解决BUG | |
| 11 | -目前解决BUG有三种方式: | |
| 12 | -1. 作者验证以及修复; | |
| 13 | -2. 热心开发者提来的PR; | |
| 14 | -3. 使用运维手段屏蔽BUG的影响。 | |
| 15 | - | |
| 16 | -- 对于第一种:详细的复现步骤,完整的抓包文件,有条理的错误分析都可以帮助作者复现问题,进而解决问题。解决问题往往不是最难的,复现才是。 | |
| 17 | -- 对于第二种:如果你是开发者,你已经发现了造成BUG的原因以及知道如何正确的修复,那么我很希望你PR,SRS的大佬经常说的,开源不是一个人的事。所以你的参与就是最大的鼓励。 | |
| 18 | -- 对于第三种:如果你有一个有经验的运维伙伴,那么部分问题是可以通过运维的手段暂时屏蔽的,在等待修复的这段时间了以保证项目的运行。 | |
| 5 | +1. 在知识星球提问。 | |
| 6 | +2. 更新代码,很可能你遇到问题别人已经更早的遇到了,或者是作者自己发现了,已经解决了,所以你可以更新代码再次进行测试; | |
| 7 | +3. 可以在github提ISSUE,我几乎每天都会去看issue,你的问题我会尽快给予答复; | |
| 8 | +> 有偿支持可以给我发邮件, 648540858@qq.com | |
| 19 | 9 | |
| 10 | +## 社群 | |
| 11 | +[](https://t.zsxq.com/0d8VAD3Dm) | |
| 12 | +> 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。 | |
| 20 | 13 | \ No newline at end of file | ... | ... |
doc/_media/shequ.png
0 → 100644
35.3 KB
src/main/java/com/genersoft/iot/vmp/common/CommonCallback.java
0 → 100644
src/main/java/com/genersoft/iot/vmp/common/InviteInfo.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.common; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.service.bean.SSRCInfo; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * 记录每次发送invite消息的状态 | |
| 7 | + */ | |
| 8 | +public class InviteInfo { | |
| 9 | + | |
| 10 | + private String deviceId; | |
| 11 | + | |
| 12 | + private String channelId; | |
| 13 | + | |
| 14 | + private String stream; | |
| 15 | + | |
| 16 | + private SSRCInfo ssrcInfo; | |
| 17 | + | |
| 18 | + private String receiveIp; | |
| 19 | + | |
| 20 | + private Integer receivePort; | |
| 21 | + | |
| 22 | + private String streamMode; | |
| 23 | + | |
| 24 | + private InviteSessionType type; | |
| 25 | + | |
| 26 | + private InviteSessionStatus status; | |
| 27 | + | |
| 28 | + private StreamInfo streamInfo; | |
| 29 | + | |
| 30 | + | |
| 31 | + public static InviteInfo getinviteInfo(String deviceId, String channelId, String stream, SSRCInfo ssrcInfo, | |
| 32 | + String receiveIp, Integer receivePort, String streamMode, | |
| 33 | + InviteSessionType type, InviteSessionStatus status) { | |
| 34 | + InviteInfo inviteInfo = new InviteInfo(); | |
| 35 | + inviteInfo.setDeviceId(deviceId); | |
| 36 | + inviteInfo.setChannelId(channelId); | |
| 37 | + inviteInfo.setStream(stream); | |
| 38 | + inviteInfo.setSsrcInfo(ssrcInfo); | |
| 39 | + inviteInfo.setReceiveIp(receiveIp); | |
| 40 | + inviteInfo.setReceivePort(receivePort); | |
| 41 | + inviteInfo.setStreamMode(streamMode); | |
| 42 | + inviteInfo.setType(type); | |
| 43 | + inviteInfo.setStatus(status); | |
| 44 | + return inviteInfo; | |
| 45 | + } | |
| 46 | + | |
| 47 | + public String getDeviceId() { | |
| 48 | + return deviceId; | |
| 49 | + } | |
| 50 | + | |
| 51 | + public void setDeviceId(String deviceId) { | |
| 52 | + this.deviceId = deviceId; | |
| 53 | + } | |
| 54 | + | |
| 55 | + public String getChannelId() { | |
| 56 | + return channelId; | |
| 57 | + } | |
| 58 | + | |
| 59 | + public void setChannelId(String channelId) { | |
| 60 | + this.channelId = channelId; | |
| 61 | + } | |
| 62 | + | |
| 63 | + public InviteSessionType getType() { | |
| 64 | + return type; | |
| 65 | + } | |
| 66 | + | |
| 67 | + public void setType(InviteSessionType type) { | |
| 68 | + this.type = type; | |
| 69 | + } | |
| 70 | + | |
| 71 | + public InviteSessionStatus getStatus() { | |
| 72 | + return status; | |
| 73 | + } | |
| 74 | + | |
| 75 | + public void setStatus(InviteSessionStatus status) { | |
| 76 | + this.status = status; | |
| 77 | + } | |
| 78 | + | |
| 79 | + public StreamInfo getStreamInfo() { | |
| 80 | + return streamInfo; | |
| 81 | + } | |
| 82 | + | |
| 83 | + public void setStreamInfo(StreamInfo streamInfo) { | |
| 84 | + this.streamInfo = streamInfo; | |
| 85 | + } | |
| 86 | + | |
| 87 | + public String getStream() { | |
| 88 | + return stream; | |
| 89 | + } | |
| 90 | + | |
| 91 | + public void setStream(String stream) { | |
| 92 | + this.stream = stream; | |
| 93 | + } | |
| 94 | + | |
| 95 | + public SSRCInfo getSsrcInfo() { | |
| 96 | + return ssrcInfo; | |
| 97 | + } | |
| 98 | + | |
| 99 | + public void setSsrcInfo(SSRCInfo ssrcInfo) { | |
| 100 | + this.ssrcInfo = ssrcInfo; | |
| 101 | + } | |
| 102 | + | |
| 103 | + public String getReceiveIp() { | |
| 104 | + return receiveIp; | |
| 105 | + } | |
| 106 | + | |
| 107 | + public void setReceiveIp(String receiveIp) { | |
| 108 | + this.receiveIp = receiveIp; | |
| 109 | + } | |
| 110 | + | |
| 111 | + public Integer getReceivePort() { | |
| 112 | + return receivePort; | |
| 113 | + } | |
| 114 | + | |
| 115 | + public void setReceivePort(Integer receivePort) { | |
| 116 | + this.receivePort = receivePort; | |
| 117 | + } | |
| 118 | + | |
| 119 | + public String getStreamMode() { | |
| 120 | + return streamMode; | |
| 121 | + } | |
| 122 | + | |
| 123 | + public void setStreamMode(String streamMode) { | |
| 124 | + this.streamMode = streamMode; | |
| 125 | + } | |
| 126 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/common/InviteSessionStatus.java
0 → 100644
src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java
0 → 100644
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
| ... | ... | @@ -16,8 +16,6 @@ public class VideoManagerConstants { |
| 16 | 16 | |
| 17 | 17 | public static final String MEDIA_SERVERS_ONLINE_PREFIX = "VMP_MEDIA_ONLINE_SERVERS_"; |
| 18 | 18 | |
| 19 | - public static final String MEDIA_STREAM_PREFIX = "VMP_MEDIA_STREAM"; | |
| 20 | - | |
| 21 | 19 | public static final String DEVICE_PREFIX = "VMP_DEVICE_"; |
| 22 | 20 | |
| 23 | 21 | // 设备同步完成 |
| ... | ... | @@ -28,9 +26,10 @@ public class VideoManagerConstants { |
| 28 | 26 | public static final String KEEPLIVEKEY_PREFIX = "VMP_KEEPALIVE_"; |
| 29 | 27 | |
| 30 | 28 | // TODO 此处多了一个_,暂不修改 |
| 31 | - public static final String PLAYER_PREFIX = "VMP_PLAYER_"; | |
| 32 | - public static final String PLAY_BLACK_PREFIX = "VMP_PLAYBACK_"; | |
| 33 | - public static final String DOWNLOAD_PREFIX = "VMP_DOWNLOAD_"; | |
| 29 | + public static final String INVITE_PREFIX = "VMP_INVITE"; | |
| 30 | + public static final String PLAYER_PREFIX = "VMP_INVITE_PLAY_"; | |
| 31 | + public static final String PLAY_BLACK_PREFIX = "VMP_INVITE_PLAYBACK_"; | |
| 32 | + public static final String DOWNLOAD_PREFIX = "VMP_INVITE_DOWNLOAD_"; | |
| 34 | 33 | |
| 35 | 34 | public static final String PLATFORM_KEEPALIVE_PREFIX = "VMP_PLATFORM_KEEPALIVE_"; |
| 36 | 35 | |
| ... | ... | @@ -123,6 +122,7 @@ public class VideoManagerConstants { |
| 123 | 122 | */ |
| 124 | 123 | public static final String VM_MSG_SUBSCRIBE_ALARM = "alarm"; |
| 125 | 124 | |
| 125 | + | |
| 126 | 126 | /** |
| 127 | 127 | * 报警通知的发送 (收到redis发出的通知,转发给其他平台) |
| 128 | 128 | */ | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java
| ... | ... | @@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.conf; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 4 | 4 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 5 | -import org.apache.catalina.connector.ClientAbortException; | |
| 6 | 5 | import org.apache.http.HttpHost; |
| 7 | 6 | import org.apache.http.HttpRequest; |
| 8 | 7 | import org.apache.http.HttpResponse; |
| ... | ... | @@ -194,11 +193,11 @@ public class ProxyServletConfig { |
| 194 | 193 | } catch (IOException ioException) { |
| 195 | 194 | if (ioException instanceof ConnectException) { |
| 196 | 195 | logger.error("录像服务 连接失败"); |
| 197 | - }else if (ioException instanceof ClientAbortException) { | |
| 198 | - /** | |
| 199 | - * TODO 使用这个代理库实现代理在遇到代理视频文件时,如果是206结果,会遇到报错蛋市目前功能正常, | |
| 200 | - * TODO 暂时去除异常处理。后续使用其他代理框架修改测试 | |
| 201 | - */ | |
| 196 | +// }else if (ioException instanceof ClientAbortException) { | |
| 197 | +// /** | |
| 198 | +// * TODO 使用这个代理库实现代理在遇到代理视频文件时,如果是206结果,会遇到报错蛋市目前功能正常, | |
| 199 | +// * TODO 暂时去除异常处理。后续使用其他代理框架修改测试 | |
| 200 | +// */ | |
| 202 | 201 | |
| 203 | 202 | }else { |
| 204 | 203 | logger.error("录像服务 代理失败: ", e); | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/ScheduleConfig.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.conf; | |
| 2 | + | |
| 3 | +import org.apache.commons.lang3.concurrent.BasicThreadFactory; | |
| 4 | +import org.springframework.context.annotation.Configuration; | |
| 5 | +import org.springframework.scheduling.annotation.SchedulingConfigurer; | |
| 6 | +import org.springframework.scheduling.config.ScheduledTaskRegistrar; | |
| 7 | + | |
| 8 | +import java.util.concurrent.ScheduledThreadPoolExecutor; | |
| 9 | +import java.util.concurrent.ThreadPoolExecutor; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * "@Scheduled"是Spring框架提供的一种定时任务执行机制,默认情况下它是单线程的,在同时执行多个定时任务时可能会出现阻塞和性能问题。 | |
| 13 | + * 为了解决这种单线程瓶颈问题,可以将定时任务的执行机制改为支持多线程 | |
| 14 | + */ | |
| 15 | +@Configuration | |
| 16 | +public class ScheduleConfig implements SchedulingConfigurer { | |
| 17 | + | |
| 18 | + public static final int cpuNum = Runtime.getRuntime().availableProcessors(); | |
| 19 | + | |
| 20 | + private static final int corePoolSize = cpuNum; | |
| 21 | + | |
| 22 | + private static final String threadNamePrefix = "scheduled-task-pool-%d"; | |
| 23 | + | |
| 24 | + @Override | |
| 25 | + public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { | |
| 26 | + taskRegistrar.setScheduler(new ScheduledThreadPoolExecutor(corePoolSize, | |
| 27 | + new BasicThreadFactory.Builder().namingPattern(threadNamePrefix).daemon(true).build(), | |
| 28 | + new ThreadPoolExecutor.CallerRunsPolicy())); | |
| 29 | + } | |
| 30 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
| ... | ... | @@ -48,10 +48,13 @@ public class SipPlatformRunner implements CommandLineRunner { |
| 48 | 48 | parentPlatformCatch.setParentPlatform(parentPlatform); |
| 49 | 49 | parentPlatformCatch.setId(parentPlatform.getServerGBId()); |
| 50 | 50 | redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); |
| 51 | - // 取消订阅 | |
| 52 | - sipCommanderForPlatform.unregister(parentPlatform, parentPlatformCatchOld.getSipTransactionInfo(), null, (eventResult)->{ | |
| 53 | - platformService.login(parentPlatform); | |
| 54 | - }); | |
| 51 | + if (parentPlatformCatchOld != null) { | |
| 52 | + // 取消订阅 | |
| 53 | + sipCommanderForPlatform.unregister(parentPlatform, parentPlatformCatchOld.getSipTransactionInfo(), null, (eventResult)->{ | |
| 54 | + platformService.login(parentPlatform); | |
| 55 | + }); | |
| 56 | + } | |
| 57 | + | |
| 55 | 58 | // 设置所有平台离线 |
| 56 | 59 | platformService.offline(parentPlatform, true); |
| 57 | 60 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
| ... | ... | @@ -54,6 +54,9 @@ public class UserSetting { |
| 54 | 54 | |
| 55 | 55 | private Boolean refuseChannelStatusChannelFormNotify = Boolean.FALSE; |
| 56 | 56 | |
| 57 | + private Boolean deviceStatusNotify = Boolean.FALSE; | |
| 58 | + private Boolean useCustomSsrcForParentInvite = Boolean.TRUE; | |
| 59 | + | |
| 57 | 60 | private String serverId = "000000"; |
| 58 | 61 | |
| 59 | 62 | private String recordPath = null; |
| ... | ... | @@ -66,6 +69,8 @@ public class UserSetting { |
| 66 | 69 | |
| 67 | 70 | private List<String> allowedOrigins = new ArrayList<>(); |
| 68 | 71 | |
| 72 | + private int maxNotifyCountQueue = 10000; | |
| 73 | + | |
| 69 | 74 | public Boolean getSavePositionHistory() { |
| 70 | 75 | return savePositionHistory; |
| 71 | 76 | } |
| ... | ... | @@ -277,4 +282,28 @@ public class UserSetting { |
| 277 | 282 | public void setRecordPath(String recordPath) { |
| 278 | 283 | this.recordPath = recordPath; |
| 279 | 284 | } |
| 285 | + | |
| 286 | + public int getMaxNotifyCountQueue() { | |
| 287 | + return maxNotifyCountQueue; | |
| 288 | + } | |
| 289 | + | |
| 290 | + public void setMaxNotifyCountQueue(int maxNotifyCountQueue) { | |
| 291 | + this.maxNotifyCountQueue = maxNotifyCountQueue; | |
| 292 | + } | |
| 293 | + | |
| 294 | + public Boolean getDeviceStatusNotify() { | |
| 295 | + return deviceStatusNotify; | |
| 296 | + } | |
| 297 | + | |
| 298 | + public void setDeviceStatusNotify(Boolean deviceStatusNotify) { | |
| 299 | + this.deviceStatusNotify = deviceStatusNotify; | |
| 300 | + } | |
| 301 | + | |
| 302 | + public Boolean getUseCustomSsrcForParentInvite() { | |
| 303 | + return useCustomSsrcForParentInvite; | |
| 304 | + } | |
| 305 | + | |
| 306 | + public void setUseCustomSsrcForParentInvite(Boolean useCustomSsrcForParentInvite) { | |
| 307 | + this.useCustomSsrcForParentInvite = useCustomSsrcForParentInvite; | |
| 308 | + } | |
| 280 | 309 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/redis/RedisConfig.java
| 1 | -package com.genersoft.iot.vmp.conf.redis; | |
| 2 | - | |
| 3 | - | |
| 4 | -import com.genersoft.iot.vmp.common.VideoManagerConstants; | |
| 5 | -import com.genersoft.iot.vmp.service.redisMsg.*; | |
| 6 | -import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer; | |
| 7 | -import org.springframework.beans.factory.annotation.Autowired; | |
| 8 | -import org.springframework.cache.annotation.CachingConfigurerSupport; | |
| 9 | -import com.alibaba.fastjson2.support.spring.data.redis.GenericFastJsonRedisSerializer; | |
| 10 | -import org.springframework.context.annotation.Bean; | |
| 11 | -import org.springframework.context.annotation.Configuration; | |
| 12 | -import org.springframework.core.annotation.Order; | |
| 13 | -import org.springframework.data.redis.connection.RedisConnectionFactory; | |
| 14 | -import org.springframework.data.redis.core.RedisTemplate; | |
| 15 | -import org.springframework.data.redis.serializer.StringRedisSerializer; | |
| 16 | - | |
| 17 | - | |
| 18 | -/** | |
| 19 | - * Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置 | |
| 20 | - * swwheihei | |
| 21 | - * 2019年5月30日 上午10:58:25 | |
| 22 | - * | |
| 23 | - */ | |
| 24 | -@Configuration | |
| 25 | -@Order(value=1) | |
| 26 | -public class RedisConfig { | |
| 27 | - | |
| 28 | - | |
| 29 | - @Bean | |
| 30 | - public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { | |
| 31 | - | |
| 32 | - RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); | |
| 33 | - // 使用fastJson序列化 | |
| 34 | - GenericFastJsonRedisSerializer fastJsonRedisSerializer = new GenericFastJsonRedisSerializer(); | |
| 35 | - // value值的序列化采用fastJsonRedisSerializer | |
| 36 | - redisTemplate.setValueSerializer(fastJsonRedisSerializer); | |
| 37 | - redisTemplate.setHashValueSerializer(fastJsonRedisSerializer); | |
| 38 | - | |
| 39 | - // key的序列化采用StringRedisSerializer | |
| 40 | - redisTemplate.setKeySerializer(new StringRedisSerializer()); | |
| 41 | - redisTemplate.setHashKeySerializer(new StringRedisSerializer()); | |
| 42 | - redisTemplate.setConnectionFactory(redisConnectionFactory); | |
| 43 | - return redisTemplate; | |
| 44 | - } | |
| 45 | -} |
src/main/java/com/genersoft/iot/vmp/conf/redis/RedisTemplateConfig.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.conf.redis; | |
| 2 | + | |
| 3 | +import com.alibaba.fastjson2.support.spring.data.redis.GenericFastJsonRedisSerializer; | |
| 4 | +import org.springframework.context.annotation.Bean; | |
| 5 | +import org.springframework.context.annotation.Configuration; | |
| 6 | +import org.springframework.data.redis.connection.RedisConnectionFactory; | |
| 7 | +import org.springframework.data.redis.core.RedisTemplate; | |
| 8 | +import org.springframework.data.redis.serializer.StringRedisSerializer; | |
| 9 | + | |
| 10 | +@Configuration | |
| 11 | +public class RedisTemplateConfig { | |
| 12 | + | |
| 13 | + @Bean | |
| 14 | + public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { | |
| 15 | + RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); | |
| 16 | + // 使用fastJson序列化 | |
| 17 | + GenericFastJsonRedisSerializer fastJsonRedisSerializer = new GenericFastJsonRedisSerializer(); | |
| 18 | + // value值的序列化采用fastJsonRedisSerializer | |
| 19 | + redisTemplate.setValueSerializer(fastJsonRedisSerializer); | |
| 20 | + redisTemplate.setHashValueSerializer(fastJsonRedisSerializer); | |
| 21 | + | |
| 22 | + // key的序列化采用StringRedisSerializer | |
| 23 | + redisTemplate.setKeySerializer(new StringRedisSerializer()); | |
| 24 | + redisTemplate.setHashKeySerializer(new StringRedisSerializer()); | |
| 25 | + redisTemplate.setConnectionFactory(redisConnectionFactory); | |
| 26 | + return redisTemplate; | |
| 27 | + } | |
| 28 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/security/JwtAuthenticationFilter.java
| ... | ... | @@ -2,6 +2,8 @@ package com.genersoft.iot.vmp.conf.security; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 4 | 4 | import com.genersoft.iot.vmp.conf.security.dto.JwtUser; |
| 5 | +import com.genersoft.iot.vmp.storager.dao.dto.Role; | |
| 6 | +import com.genersoft.iot.vmp.storager.dao.dto.User; | |
| 5 | 7 | import org.apache.commons.lang3.StringUtils; |
| 6 | 8 | import org.springframework.beans.factory.annotation.Autowired; |
| 7 | 9 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
| ... | ... | @@ -38,7 +40,6 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { |
| 38 | 40 | return; |
| 39 | 41 | } |
| 40 | 42 | if (!userSetting.isInterfaceAuthentication()) { |
| 41 | - // 构建UsernamePasswordAuthenticationToken,这里密码为null,是因为提供了正确的JWT,实现自动登录 | |
| 42 | 43 | UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(null, null, new ArrayList<>() ); |
| 43 | 44 | SecurityContextHolder.getContext().setAuthentication(token); |
| 44 | 45 | chain.doFilter(request, response); |
| ... | ... | @@ -76,7 +77,13 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { |
| 76 | 77 | } |
| 77 | 78 | |
| 78 | 79 | // 构建UsernamePasswordAuthenticationToken,这里密码为null,是因为提供了正确的JWT,实现自动登录 |
| 79 | - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, jwtUser.getPassword(), new ArrayList<>() ); | |
| 80 | + User user = new User(); | |
| 81 | + user.setUsername(jwtUser.getUserName()); | |
| 82 | + user.setPassword(jwtUser.getPassword()); | |
| 83 | + Role role = new Role(); | |
| 84 | + role.setId(jwtUser.getRoleId()); | |
| 85 | + user.setRole(role); | |
| 86 | + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user, jwtUser.getPassword(), new ArrayList<>() ); | |
| 80 | 87 | SecurityContextHolder.getContext().setAuthentication(token); |
| 81 | 88 | chain.doFilter(request, response); |
| 82 | 89 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/security/JwtUtils.java
| ... | ... | @@ -37,7 +37,7 @@ public class JwtUtils { |
| 37 | 37 | */ |
| 38 | 38 | public static final long expirationTime = 30; |
| 39 | 39 | |
| 40 | - public static String createToken(String username, String password) { | |
| 40 | + public static String createToken(String username, String password, Integer roleId) { | |
| 41 | 41 | try { |
| 42 | 42 | /** |
| 43 | 43 | * “iss” (issuer) 发行人 |
| ... | ... | @@ -64,6 +64,7 @@ public class JwtUtils { |
| 64 | 64 | //添加自定义参数,必须是字符串类型 |
| 65 | 65 | claims.setClaim("username", username); |
| 66 | 66 | claims.setClaim("password", password); |
| 67 | + claims.setClaim("roleId", roleId); | |
| 67 | 68 | |
| 68 | 69 | //jws |
| 69 | 70 | JsonWebSignature jws = new JsonWebSignature(); |
| ... | ... | @@ -118,8 +119,10 @@ public class JwtUtils { |
| 118 | 119 | |
| 119 | 120 | String username = (String) claims.getClaimValue("username"); |
| 120 | 121 | String password = (String) claims.getClaimValue("password"); |
| 122 | + Long roleId = (Long) claims.getClaimValue("roleId"); | |
| 121 | 123 | jwtUser.setUserName(username); |
| 122 | 124 | jwtUser.setPassword(password); |
| 125 | + jwtUser.setRoleId(roleId.intValue()); | |
| 123 | 126 | |
| 124 | 127 | return jwtUser; |
| 125 | 128 | } catch (InvalidJwtException e) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/security/LoginFailureHandler.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.conf.security; | |
| 2 | - | |
| 3 | -import com.fasterxml.jackson.databind.ObjectMapper; | |
| 4 | -import org.slf4j.Logger; | |
| 5 | -import org.slf4j.LoggerFactory; | |
| 6 | -import org.springframework.beans.factory.annotation.Autowired; | |
| 7 | -import org.springframework.security.authentication.*; | |
| 8 | -import org.springframework.security.core.AuthenticationException; | |
| 9 | -import org.springframework.security.web.authentication.AuthenticationFailureHandler; | |
| 10 | -import org.springframework.stereotype.Component; | |
| 11 | - | |
| 12 | -import javax.servlet.ServletException; | |
| 13 | -import javax.servlet.http.HttpServletRequest; | |
| 14 | -import javax.servlet.http.HttpServletResponse; | |
| 15 | -import java.io.IOException; | |
| 16 | -import java.util.HashMap; | |
| 17 | -import java.util.Map; | |
| 18 | - | |
| 19 | -@Component | |
| 20 | -public class LoginFailureHandler implements AuthenticationFailureHandler { | |
| 21 | - | |
| 22 | - private final static Logger logger = LoggerFactory.getLogger(LoginFailureHandler.class); | |
| 23 | - | |
| 24 | - @Autowired | |
| 25 | - private ObjectMapper objectMapper; | |
| 26 | - | |
| 27 | - @Override | |
| 28 | - public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException { | |
| 29 | - | |
| 30 | - String username = request.getParameter("username"); | |
| 31 | - if (e instanceof AccountExpiredException) { | |
| 32 | - // 账号过期 | |
| 33 | - logger.info("[登录失败] - 用户[{}]账号过期", username); | |
| 34 | - | |
| 35 | - } else if (e instanceof BadCredentialsException) { | |
| 36 | - // 密码错误 | |
| 37 | - logger.info("[登录失败] - 用户[{}]密码/SIP服务器ID 错误", username); | |
| 38 | - | |
| 39 | - } else if (e instanceof CredentialsExpiredException) { | |
| 40 | - // 密码过期 | |
| 41 | - logger.info("[登录失败] - 用户[{}]密码过期", username); | |
| 42 | - | |
| 43 | - } else if (e instanceof DisabledException) { | |
| 44 | - // 用户被禁用 | |
| 45 | - logger.info("[登录失败] - 用户[{}]被禁用", username); | |
| 46 | - | |
| 47 | - } else if (e instanceof LockedException) { | |
| 48 | - // 用户被锁定 | |
| 49 | - logger.info("[登录失败] - 用户[{}]被锁定", username); | |
| 50 | - | |
| 51 | - } else if (e instanceof InternalAuthenticationServiceException) { | |
| 52 | - // 内部错误 | |
| 53 | - logger.error(String.format("[登录失败] - [%s]内部错误", username), e); | |
| 54 | - | |
| 55 | - } else { | |
| 56 | - // 其他错误 | |
| 57 | - logger.error(String.format("[登录失败] - [%s]其他错误", username), e); | |
| 58 | - } | |
| 59 | - Map<String, Object> map = new HashMap<>(); | |
| 60 | - map.put("code","0"); | |
| 61 | - map.put("msg","登录失败"); | |
| 62 | - response.setContentType("application/json;charset=UTF-8"); | |
| 63 | - response.getWriter().write(objectMapper.writeValueAsString(map)); | |
| 64 | - } | |
| 65 | -} |
src/main/java/com/genersoft/iot/vmp/conf/security/LoginSuccessHandler.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.conf.security; | |
| 2 | - | |
| 3 | -import org.slf4j.Logger; | |
| 4 | -import org.slf4j.LoggerFactory; | |
| 5 | -import org.springframework.security.core.Authentication; | |
| 6 | -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; | |
| 7 | -import org.springframework.stereotype.Component; | |
| 8 | - | |
| 9 | -import javax.servlet.ServletException; | |
| 10 | -import javax.servlet.http.HttpServletRequest; | |
| 11 | -import javax.servlet.http.HttpServletResponse; | |
| 12 | -import java.io.IOException; | |
| 13 | - | |
| 14 | -/** | |
| 15 | - * @author lin | |
| 16 | - */ | |
| 17 | -@Component | |
| 18 | -public class LoginSuccessHandler implements AuthenticationSuccessHandler { | |
| 19 | - | |
| 20 | - private final static Logger logger = LoggerFactory.getLogger(LoginSuccessHandler.class); | |
| 21 | - | |
| 22 | - @Override | |
| 23 | - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { | |
| 24 | -// String username = request.getParameter("username"); | |
| 25 | -// httpServletResponse.setContentType("application/json;charset=UTF-8"); | |
| 26 | -// // 生成JWT,并放置到请求头中 | |
| 27 | -// String jwt = JwtUtils.createToken(authentication.getName(), ); | |
| 28 | -// httpServletResponse.setHeader(JwtUtils.getHeader(), jwt); | |
| 29 | -// ServletOutputStream outputStream = httpServletResponse.getOutputStream(); | |
| 30 | -// outputStream.write(JSON.toJSONString(ErrorCode.SUCCESS).getBytes(StandardCharsets.UTF_8)); | |
| 31 | -// outputStream.flush(); | |
| 32 | -// outputStream.close(); | |
| 33 | - | |
| 34 | -// logger.info("[登录成功] - [{}]", username); | |
| 35 | - } | |
| 36 | -} |
src/main/java/com/genersoft/iot/vmp/conf/security/SecurityUtils.java
| ... | ... | @@ -53,14 +53,10 @@ public class SecurityUtils { |
| 53 | 53 | Authentication authentication = getAuthentication(); |
| 54 | 54 | if(authentication!=null){ |
| 55 | 55 | Object principal = authentication.getPrincipal(); |
| 56 | - if(principal!=null && !"anonymousUser".equals(principal)){ | |
| 57 | -// LoginUser user = (LoginUser) authentication.getPrincipal(); | |
| 56 | + if(principal!=null && !"anonymousUser".equals(principal.toString())){ | |
| 58 | 57 | |
| 59 | - String username = (String) principal; | |
| 60 | - User user = new User(); | |
| 61 | - user.setUsername(username); | |
| 62 | - LoginUser loginUser = new LoginUser(user, LocalDateTime.now()); | |
| 63 | - return loginUser; | |
| 58 | + User user = (User) principal; | |
| 59 | + return new LoginUser(user, LocalDateTime.now()); | |
| 64 | 60 | } |
| 65 | 61 | } |
| 66 | 62 | return null; | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java
| ... | ... | @@ -47,16 +47,6 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { |
| 47 | 47 | * 登出成功的处理 |
| 48 | 48 | */ |
| 49 | 49 | @Autowired |
| 50 | - private LoginFailureHandler loginFailureHandler; | |
| 51 | - /** | |
| 52 | - * 登录成功的处理 | |
| 53 | - */ | |
| 54 | - @Autowired | |
| 55 | - private LoginSuccessHandler loginSuccessHandler; | |
| 56 | - /** | |
| 57 | - * 登出成功的处理 | |
| 58 | - */ | |
| 59 | - @Autowired | |
| 60 | 50 | private LogoutHandler logoutHandler; |
| 61 | 51 | /** |
| 62 | 52 | * 未登录的处理 | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/security/dto/JwtUser.java
| ... | ... | @@ -25,6 +25,8 @@ public class JwtUser { |
| 25 | 25 | |
| 26 | 26 | private String password; |
| 27 | 27 | |
| 28 | + private int roleId; | |
| 29 | + | |
| 28 | 30 | private TokenStatus status; |
| 29 | 31 | |
| 30 | 32 | public String getUserName() { |
| ... | ... | @@ -50,4 +52,12 @@ public class JwtUser { |
| 50 | 52 | public void setPassword(String password) { |
| 51 | 53 | this.password = password; |
| 52 | 54 | } |
| 55 | + | |
| 56 | + public int getRoleId() { | |
| 57 | + return roleId; | |
| 58 | + } | |
| 59 | + | |
| 60 | + public void setRoleId(int roleId) { | |
| 61 | + this.roleId = roleId; | |
| 62 | + } | |
| 53 | 63 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
| ... | ... | @@ -36,8 +36,6 @@ public class SipLayer implements CommandLineRunner { |
| 36 | 36 | private final Map<String, SipProviderImpl> tcpSipProviderMap = new ConcurrentHashMap<>(); |
| 37 | 37 | private final Map<String, SipProviderImpl> udpSipProviderMap = new ConcurrentHashMap<>(); |
| 38 | 38 | |
| 39 | - private SipFactory sipFactory; | |
| 40 | - | |
| 41 | 39 | @Override |
| 42 | 40 | public void run(String... args) { |
| 43 | 41 | List<String> monitorIps = new ArrayList<>(); |
| ... | ... | @@ -50,8 +48,7 @@ public class SipLayer implements CommandLineRunner { |
| 50 | 48 | monitorIps.add(sipConfig.getIp()); |
| 51 | 49 | } |
| 52 | 50 | |
| 53 | - sipFactory = SipFactory.getInstance(); | |
| 54 | - sipFactory.setPathName("gov.nist"); | |
| 51 | + SipFactory.getInstance().setPathName("gov.nist"); | |
| 55 | 52 | if (monitorIps.size() > 0) { |
| 56 | 53 | for (String monitorIp : monitorIps) { |
| 57 | 54 | addListeningPoint(monitorIp, sipConfig.getPort()); |
| ... | ... | @@ -65,7 +62,7 @@ public class SipLayer implements CommandLineRunner { |
| 65 | 62 | private void addListeningPoint(String monitorIp, int port){ |
| 66 | 63 | SipStackImpl sipStack; |
| 67 | 64 | try { |
| 68 | - sipStack = (SipStackImpl)sipFactory.createSipStack(DefaultProperties.getProperties(monitorIp, userSetting.getSipLog())); | |
| 65 | + sipStack = (SipStackImpl)SipFactory.getInstance().createSipStack(DefaultProperties.getProperties(monitorIp, userSetting.getSipLog())); | |
| 69 | 66 | } catch (PeerUnavailableException e) { |
| 70 | 67 | logger.error("[Sip Server] SIP服务启动失败, 监听地址{}失败,请检查ip是否正确", monitorIp); |
| 71 | 68 | return; |
| ... | ... | @@ -106,10 +103,6 @@ public class SipLayer implements CommandLineRunner { |
| 106 | 103 | } |
| 107 | 104 | } |
| 108 | 105 | |
| 109 | - public SipFactory getSipFactory() { | |
| 110 | - return sipFactory; | |
| 111 | - } | |
| 112 | - | |
| 113 | 106 | public SipProviderImpl getUdpSipProvider(String ip) { |
| 114 | 107 | if (ObjectUtils.isEmpty(ip)) { |
| 115 | 108 | return null; | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/CmdSendFailEvent.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.bean; | |
| 2 | - | |
| 3 | -import javax.sip.Dialog; | |
| 4 | -import java.util.EventObject; | |
| 5 | - | |
| 6 | -public class CmdSendFailEvent extends EventObject { | |
| 7 | - | |
| 8 | - private String callId; | |
| 9 | - | |
| 10 | - /** | |
| 11 | - * Constructs a prototypical Event. | |
| 12 | - * | |
| 13 | - * @param dialog | |
| 14 | - * @throws IllegalArgumentException if source is null. | |
| 15 | - */ | |
| 16 | - public CmdSendFailEvent(Dialog dialog) { | |
| 17 | - super(dialog); | |
| 18 | - } | |
| 19 | - | |
| 20 | - public String getCallId() { | |
| 21 | - return callId; | |
| 22 | - } | |
| 23 | - | |
| 24 | - public void setCallId(String callId) { | |
| 25 | - this.callId = callId; | |
| 26 | - } | |
| 27 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
| ... | ... | @@ -247,6 +247,17 @@ public class Device { |
| 247 | 247 | return streamMode; |
| 248 | 248 | } |
| 249 | 249 | |
| 250 | + public Integer getStreamModeForParam() { | |
| 251 | + if (streamMode.equalsIgnoreCase("UDP")) { | |
| 252 | + return 0; | |
| 253 | + }else if (streamMode.equalsIgnoreCase("TCP-PASSIVE")) { | |
| 254 | + return 1; | |
| 255 | + }else if (streamMode.equalsIgnoreCase("TCP-ACTIVE")) { | |
| 256 | + return 2; | |
| 257 | + } | |
| 258 | + return 0; | |
| 259 | + } | |
| 260 | + | |
| 250 | 261 | public void setStreamMode(String streamMode) { |
| 251 | 262 | this.streamMode = streamMode; |
| 252 | 263 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamType.java
| ... | ... | @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.gb28181.bean; |
| 2 | 2 | |
| 3 | 3 | public enum InviteStreamType { |
| 4 | 4 | |
| 5 | - PLAY,PLAYBACK,PUSH,PROXY,CLOUD_RECORD_PUSH,CLOUD_RECORD_PROXY,BROADCAST,TALK | |
| 5 | + PLAY,PLAYBACK,DOWNLOAD,PUSH,PROXY,CLOUD_RECORD_PUSH,CLOUD_RECORD_PROXY,BROADCAST,TALK | |
| 6 | 6 | |
| 7 | 7 | |
| 8 | 8 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SsrcTransaction.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.bean; |
| 2 | 2 | |
| 3 | -import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | |
| 3 | +import com.genersoft.iot.vmp.common.InviteSessionType; | |
| 4 | 4 | |
| 5 | 5 | public class SsrcTransaction { |
| 6 | 6 | |
| ... | ... | @@ -13,7 +13,7 @@ public class SsrcTransaction { |
| 13 | 13 | |
| 14 | 14 | private SipTransactionInfo sipTransactionInfo; |
| 15 | 15 | |
| 16 | - private VideoStreamSessionManager.SessionType type; | |
| 16 | + private InviteSessionType type; | |
| 17 | 17 | |
| 18 | 18 | public String getDeviceId() { |
| 19 | 19 | return deviceId; |
| ... | ... | @@ -63,11 +63,11 @@ public class SsrcTransaction { |
| 63 | 63 | this.ssrc = ssrc; |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | - public VideoStreamSessionManager.SessionType getType() { | |
| 66 | + public InviteSessionType getType() { | |
| 67 | 67 | return type; |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | - public void setType(VideoStreamSessionManager.SessionType type) { | |
| 70 | + public void setType(InviteSessionType type) { | |
| 71 | 71 | this.type = type; |
| 72 | 72 | } |
| 73 | 73 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/conf/ServerLoggerImpl.java
| ... | ... | @@ -27,7 +27,7 @@ public class ServerLoggerImpl implements ServerLogger { |
| 27 | 27 | return; |
| 28 | 28 | } |
| 29 | 29 | StringBuilder stringBuilder = new StringBuilder(); |
| 30 | - stringBuilder.append(!sender? "发送:目标--->" + from:"接收:来自--->" + to) | |
| 30 | + stringBuilder.append(sender? "发送:目标--->" + from:"接收:来自--->" + to) | |
| 31 | 31 | .append("\r\n") |
| 32 | 32 | .append(message); |
| 33 | 33 | this.stackLogger.logInfo(stringBuilder.toString()); |
| ... | ... | @@ -40,7 +40,7 @@ public class ServerLoggerImpl implements ServerLogger { |
| 40 | 40 | return; |
| 41 | 41 | } |
| 42 | 42 | StringBuilder stringBuilder = new StringBuilder(); |
| 43 | - stringBuilder.append(!sender? "发送: 目标->" + from :"接收:来自->" + to) | |
| 43 | + stringBuilder.append(sender? "发送: 目标->" + from :"接收:来自->" + to) | |
| 44 | 44 | .append("\r\n") |
| 45 | 45 | .append(message); |
| 46 | 46 | this.stackLogger.logInfo(stringBuilder.toString()); |
| ... | ... | @@ -52,7 +52,7 @@ public class ServerLoggerImpl implements ServerLogger { |
| 52 | 52 | return; |
| 53 | 53 | } |
| 54 | 54 | StringBuilder stringBuilder = new StringBuilder(); |
| 55 | - stringBuilder.append(!sender? "发送: 目标->" + from :"接收:来自->" + to) | |
| 55 | + stringBuilder.append(sender? "发送: 目标->" + from :"接收:来自->" + to) | |
| 56 | 56 | .append("\r\n") |
| 57 | 57 | .append(message); |
| 58 | 58 | this.stackLogger.logInfo(stringBuilder.toString()); |
| ... | ... | @@ -87,6 +87,4 @@ public class ServerLoggerImpl implements ServerLogger { |
| 87 | 87 | this.stackLogger = this.sipStack.getStackLogger(); |
| 88 | 88 | } |
| 89 | 89 | } |
| 90 | - | |
| 91 | - | |
| 92 | 90 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
| ... | ... | @@ -76,7 +76,11 @@ public class SipSubscribe { |
| 76 | 76 | // 会话已结束 |
| 77 | 77 | dialogTerminated, |
| 78 | 78 | // 设备未找到 |
| 79 | - deviceNotFoundEvent | |
| 79 | + deviceNotFoundEvent, | |
| 80 | + // 消息发送失败 | |
| 81 | + cmdSendFailEvent, | |
| 82 | + // 消息发送失败 | |
| 83 | + failedToGetPort | |
| 80 | 84 | } |
| 81 | 85 | |
| 82 | 86 | public static class EventResult<EventObject>{ |
| ... | ... | @@ -86,9 +90,7 @@ public class SipSubscribe { |
| 86 | 90 | public String callId; |
| 87 | 91 | public EventObject event; |
| 88 | 92 | |
| 89 | - public EventResult(int statusCode, String msg) { | |
| 90 | - this.statusCode = statusCode; | |
| 91 | - this.msg = msg; | |
| 93 | + public EventResult() { | |
| 92 | 94 | } |
| 93 | 95 | |
| 94 | 96 | public EventResult(EventObject event) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.event.subscribe.catalog; |
| 2 | 2 | |
| 3 | -import com.genersoft.iot.vmp.common.VideoManagerConstants; | |
| 4 | -import com.genersoft.iot.vmp.conf.SipConfig; | |
| 5 | 3 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 6 | 4 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 7 | 5 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; |
| 8 | -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | |
| 9 | 6 | import com.genersoft.iot.vmp.service.IGbStreamService; |
| 10 | -import com.genersoft.iot.vmp.service.IMediaServerService; | |
| 11 | -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | |
| 12 | 7 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 13 | 8 | import org.slf4j.Logger; |
| 14 | 9 | import org.slf4j.LoggerFactory; |
| ... | ... | @@ -16,12 +11,14 @@ import org.springframework.beans.factory.annotation.Autowired; |
| 16 | 11 | import org.springframework.context.ApplicationListener; |
| 17 | 12 | import org.springframework.stereotype.Component; |
| 18 | 13 | import org.springframework.util.ObjectUtils; |
| 19 | -import org.springframework.util.StringUtils; | |
| 20 | 14 | |
| 21 | 15 | import javax.sip.InvalidArgumentException; |
| 22 | 16 | import javax.sip.SipException; |
| 23 | 17 | import java.text.ParseException; |
| 24 | -import java.util.*; | |
| 18 | +import java.util.ArrayList; | |
| 19 | +import java.util.HashMap; | |
| 20 | +import java.util.List; | |
| 21 | +import java.util.Map; | |
| 25 | 22 | |
| 26 | 23 | /** |
| 27 | 24 | * catalog事件 |
| ... | ... | @@ -43,6 +40,9 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> { |
| 43 | 40 | @Autowired |
| 44 | 41 | private SubscribeHolder subscribeHolder; |
| 45 | 42 | |
| 43 | + @Autowired | |
| 44 | + private UserSetting userSetting; | |
| 45 | + | |
| 46 | 46 | @Override |
| 47 | 47 | public void onApplicationEvent(CatalogEvent event) { |
| 48 | 48 | SubscribeInfo subscribe = null; |
| ... | ... | @@ -93,6 +93,9 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> { |
| 93 | 93 | } |
| 94 | 94 | if (event.getGbStreams() != null && event.getGbStreams().size() > 0){ |
| 95 | 95 | for (GbStream gbStream : event.getGbStreams()) { |
| 96 | + if (gbStream.getStreamType().equals("push") && !userSetting.isUsePushingAsStatus()) { | |
| 97 | + continue; | |
| 98 | + } | |
| 96 | 99 | DeviceChannel deviceChannelByStream = gbStreamService.getDeviceChannelListByStream(gbStream, gbStream.getCatalogId(), parentPlatform); |
| 97 | 100 | deviceChannelList.add(deviceChannelByStream); |
| 98 | 101 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/session/SSRCFactory.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.gb28181.session; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.conf.SipConfig; | |
| 4 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 5 | +import org.springframework.data.redis.core.StringRedisTemplate; | |
| 6 | +import org.springframework.stereotype.Component; | |
| 7 | + | |
| 8 | +import java.util.ArrayList; | |
| 9 | +import java.util.List; | |
| 10 | +import java.util.Set; | |
| 11 | + | |
| 12 | +/** | |
| 13 | + * ssrc使用 | |
| 14 | + */ | |
| 15 | +@Component | |
| 16 | +public class SSRCFactory { | |
| 17 | + | |
| 18 | + /** | |
| 19 | + * 播流最大并发个数 | |
| 20 | + */ | |
| 21 | + private static final Integer MAX_STREAM_COUNT = 10000; | |
| 22 | + | |
| 23 | + /** | |
| 24 | + * 播流最大并发个数 | |
| 25 | + */ | |
| 26 | + private static final String SSRC_INFO_KEY = "VMP_SSRC_INFO_"; | |
| 27 | + | |
| 28 | + @Autowired | |
| 29 | + private StringRedisTemplate redisTemplate; | |
| 30 | + | |
| 31 | + @Autowired | |
| 32 | + private SipConfig sipConfig; | |
| 33 | + | |
| 34 | + | |
| 35 | + public void initMediaServerSSRC(String mediaServerId, Set<String> usedSet) { | |
| 36 | + String ssrcPrefix = sipConfig.getDomain().substring(3, 8); | |
| 37 | + String redisKey = SSRC_INFO_KEY + mediaServerId; | |
| 38 | + List<String> ssrcList = new ArrayList<>(); | |
| 39 | + for (int i = 1; i < MAX_STREAM_COUNT; i++) { | |
| 40 | + String ssrc = String.format("%s%04d", ssrcPrefix, i); | |
| 41 | + | |
| 42 | + if (null == usedSet || !usedSet.contains(ssrc)) { | |
| 43 | + ssrcList.add(ssrc); | |
| 44 | + | |
| 45 | + } | |
| 46 | + } | |
| 47 | + if (redisTemplate.opsForSet().size(redisKey) != null) { | |
| 48 | + redisTemplate.delete(redisKey); | |
| 49 | + } | |
| 50 | + redisTemplate.opsForSet().add(redisKey, ssrcList.toArray(new String[0])); | |
| 51 | + } | |
| 52 | + | |
| 53 | + | |
| 54 | + /** | |
| 55 | + * 获取视频预览的SSRC值,第一位固定为0 | |
| 56 | + * | |
| 57 | + * @return ssrc | |
| 58 | + */ | |
| 59 | + public String getPlaySsrc(String mediaServerId) { | |
| 60 | + return "0" + getSN(mediaServerId); | |
| 61 | + } | |
| 62 | + | |
| 63 | + /** | |
| 64 | + * 获取录像回放的SSRC值,第一位固定为1 | |
| 65 | + */ | |
| 66 | + public String getPlayBackSsrc(String mediaServerId) { | |
| 67 | + return "1" + getSN(mediaServerId); | |
| 68 | + } | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * 释放ssrc,主要用完的ssrc一定要释放,否则会耗尽 | |
| 72 | + * | |
| 73 | + * @param ssrc 需要重置的ssrc | |
| 74 | + */ | |
| 75 | + public void releaseSsrc(String mediaServerId, String ssrc) { | |
| 76 | + if (ssrc == null) { | |
| 77 | + return; | |
| 78 | + } | |
| 79 | + String sn = ssrc.substring(1); | |
| 80 | + String redisKey = SSRC_INFO_KEY + mediaServerId; | |
| 81 | + redisTemplate.opsForSet().add(redisKey, sn); | |
| 82 | + } | |
| 83 | + | |
| 84 | + /** | |
| 85 | + * 获取后四位数SN,随机数 | |
| 86 | + */ | |
| 87 | + private String getSN(String mediaServerId) { | |
| 88 | + String sn = null; | |
| 89 | + String redisKey = SSRC_INFO_KEY + mediaServerId; | |
| 90 | + Long size = redisTemplate.opsForSet().size(redisKey); | |
| 91 | + if (size == null || size == 0) { | |
| 92 | + throw new RuntimeException("ssrc已经用完"); | |
| 93 | + } else { | |
| 94 | + // 在集合中移除并返回一个随机成员。 | |
| 95 | + sn = (String) redisTemplate.opsForSet().pop(redisKey); | |
| 96 | + redisTemplate.opsForSet().remove(redisKey, sn); | |
| 97 | + } | |
| 98 | + return sn; | |
| 99 | + } | |
| 100 | + | |
| 101 | + /** | |
| 102 | + * 重置一个流媒体服务的所有ssrc | |
| 103 | + * | |
| 104 | + * @param mediaServerId 流媒体服务ID | |
| 105 | + */ | |
| 106 | + public void reset(String mediaServerId) { | |
| 107 | + this.initMediaServerSSRC(mediaServerId, null); | |
| 108 | + } | |
| 109 | + | |
| 110 | + /** | |
| 111 | + * 是否已经存在了某个MediaServer的SSRC信息 | |
| 112 | + * | |
| 113 | + * @param mediaServerId 流媒体服务ID | |
| 114 | + */ | |
| 115 | + public boolean hasMediaServerSSRC(String mediaServerId) { | |
| 116 | + String redisKey = SSRC_INFO_KEY + mediaServerId; | |
| 117 | + return redisTemplate.opsForSet().members(redisKey) != null; | |
| 118 | + } | |
| 119 | + | |
| 120 | + /** | |
| 121 | + * 查询ssrc是否可用 | |
| 122 | + * | |
| 123 | + * @param mediaServerId | |
| 124 | + * @param ssrc | |
| 125 | + * @return | |
| 126 | + */ | |
| 127 | + public boolean checkSsrc(String mediaServerId, String ssrc) { | |
| 128 | + String sn = ssrc.substring(1); | |
| 129 | + String redisKey = SSRC_INFO_KEY + mediaServerId; | |
| 130 | + return redisTemplate.opsForSet().isMember(redisKey, sn) != null; | |
| 131 | + } | |
| 132 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcConfig.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.session; | |
| 2 | - | |
| 3 | -import com.genersoft.iot.vmp.utils.ConfigConst; | |
| 4 | -import io.swagger.v3.oas.annotations.media.Schema; | |
| 5 | - | |
| 6 | -import java.util.ArrayList; | |
| 7 | -import java.util.List; | |
| 8 | -import java.util.Random; | |
| 9 | -import java.util.Set; | |
| 10 | - | |
| 11 | -@Schema(description = "ssrc信息") | |
| 12 | -public class SsrcConfig { | |
| 13 | - | |
| 14 | - /** | |
| 15 | - * zlm流媒体服务器Id | |
| 16 | - */ | |
| 17 | - @Schema(description = "流媒体服务器Id") | |
| 18 | - private String mediaServerId; | |
| 19 | - | |
| 20 | - @Schema(description = "SSRC前缀") | |
| 21 | - private String ssrcPrefix; | |
| 22 | - | |
| 23 | - /** | |
| 24 | - * zlm流媒体服务器已用会话句柄 | |
| 25 | - */ | |
| 26 | - @Schema(description = "zlm流媒体服务器已用会话句柄") | |
| 27 | - private List<String> isUsed; | |
| 28 | - | |
| 29 | - /** | |
| 30 | - * zlm流媒体服务器可用会话句柄 | |
| 31 | - */ | |
| 32 | - @Schema(description = "zlm流媒体服务器可用会话句柄") | |
| 33 | - private List<String> notUsed; | |
| 34 | - | |
| 35 | - public SsrcConfig() { | |
| 36 | - } | |
| 37 | - | |
| 38 | - public SsrcConfig(String mediaServerId, Set<String> usedSet, String sipDomain) { | |
| 39 | - this.mediaServerId = mediaServerId; | |
| 40 | - this.isUsed = new ArrayList<>(); | |
| 41 | - this.ssrcPrefix = sipDomain.substring(3, 8); | |
| 42 | - this.notUsed = new ArrayList<>(); | |
| 43 | - for (int i = 1; i < ConfigConst.MAX_STRTEAM_COUNT; i++) { | |
| 44 | - String ssrc; | |
| 45 | - if (i < 10) { | |
| 46 | - ssrc = "000" + i; | |
| 47 | - } else if (i < 100) { | |
| 48 | - ssrc = "00" + i; | |
| 49 | - } else if (i < 1000) { | |
| 50 | - ssrc = "0" + i; | |
| 51 | - } else { | |
| 52 | - ssrc = String.valueOf(i); | |
| 53 | - } | |
| 54 | - if (null == usedSet || !usedSet.contains(ssrc)) { | |
| 55 | - this.notUsed.add(ssrc); | |
| 56 | - } else { | |
| 57 | - this.isUsed.add(ssrc); | |
| 58 | - } | |
| 59 | - } | |
| 60 | - } | |
| 61 | - | |
| 62 | - | |
| 63 | - /** | |
| 64 | - * 获取视频预览的SSRC值,第一位固定为0 | |
| 65 | - * @return ssrc | |
| 66 | - */ | |
| 67 | - public String getPlaySsrc() { | |
| 68 | - return "0" + getSsrcPrefix() + getSN(); | |
| 69 | - } | |
| 70 | - | |
| 71 | - /** | |
| 72 | - * 获取录像回放的SSRC值,第一位固定为1 | |
| 73 | - * | |
| 74 | - */ | |
| 75 | - public String getPlayBackSsrc() { | |
| 76 | - return "1" + getSsrcPrefix() + getSN(); | |
| 77 | - } | |
| 78 | - | |
| 79 | - /** | |
| 80 | - * 释放ssrc,主要用完的ssrc一定要释放,否则会耗尽 | |
| 81 | - * @param ssrc 需要重置的ssrc | |
| 82 | - */ | |
| 83 | - public void releaseSsrc(String ssrc) { | |
| 84 | - if (ssrc == null) { | |
| 85 | - return; | |
| 86 | - } | |
| 87 | - String sn = ssrc.substring(6); | |
| 88 | - try { | |
| 89 | - isUsed.remove(sn); | |
| 90 | - notUsed.add(sn); | |
| 91 | - }catch (NullPointerException e){ | |
| 92 | - } | |
| 93 | - } | |
| 94 | - | |
| 95 | - /** | |
| 96 | - * 获取后四位数SN,随机数 | |
| 97 | - * | |
| 98 | - */ | |
| 99 | - private String getSN() { | |
| 100 | - String sn = null; | |
| 101 | - int index = 0; | |
| 102 | - if (notUsed.size() == 0) { | |
| 103 | - throw new RuntimeException("ssrc已经用完"); | |
| 104 | - } else if (notUsed.size() == 1) { | |
| 105 | - sn = notUsed.get(0); | |
| 106 | - } else { | |
| 107 | - index = new Random().nextInt(notUsed.size() - 1); | |
| 108 | - sn = notUsed.get(index); | |
| 109 | - } | |
| 110 | - notUsed.remove(index); | |
| 111 | - isUsed.add(sn); | |
| 112 | - return sn; | |
| 113 | - } | |
| 114 | - | |
| 115 | - public String getSsrcPrefix() { | |
| 116 | - return ssrcPrefix; | |
| 117 | - } | |
| 118 | - | |
| 119 | - public String getMediaServerId() { | |
| 120 | - return mediaServerId; | |
| 121 | - } | |
| 122 | - | |
| 123 | - public void setMediaServerId(String mediaServerId) { | |
| 124 | - this.mediaServerId = mediaServerId; | |
| 125 | - } | |
| 126 | - | |
| 127 | - public void setSsrcPrefix(String ssrcPrefix) { | |
| 128 | - this.ssrcPrefix = ssrcPrefix; | |
| 129 | - } | |
| 130 | - | |
| 131 | - public List<String> getIsUsed() { | |
| 132 | - return isUsed; | |
| 133 | - } | |
| 134 | - | |
| 135 | - public void setIsUsed(List<String> isUsed) { | |
| 136 | - this.isUsed = isUsed; | |
| 137 | - } | |
| 138 | - | |
| 139 | - public List<String> getNotUsed() { | |
| 140 | - return notUsed; | |
| 141 | - } | |
| 142 | - | |
| 143 | - public void setNotUsed(List<String> notUsed) { | |
| 144 | - this.notUsed = notUsed; | |
| 145 | - } | |
| 146 | - | |
| 147 | - public boolean checkSsrc(String ssrcInResponse) { | |
| 148 | - return !isUsed.contains(ssrcInResponse); | |
| 149 | - } | |
| 150 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.session; |
| 2 | 2 | |
| 3 | +import com.genersoft.iot.vmp.common.InviteSessionType; | |
| 3 | 4 | import com.genersoft.iot.vmp.common.VideoManagerConstants; |
| 4 | 5 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 5 | 6 | import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo; |
| ... | ... | @@ -27,14 +28,6 @@ public class VideoStreamSessionManager { |
| 27 | 28 | @Autowired |
| 28 | 29 | private RedisTemplate<Object, Object> redisTemplate; |
| 29 | 30 | |
| 30 | - public enum SessionType { | |
| 31 | - play, | |
| 32 | - playback, | |
| 33 | - download, | |
| 34 | - broadcast, | |
| 35 | - talk | |
| 36 | - } | |
| 37 | - | |
| 38 | 31 | /** |
| 39 | 32 | * 添加一个点播/回放的事务信息 |
| 40 | 33 | * 后续可以通过流Id/callID |
| ... | ... | @@ -45,7 +38,7 @@ public class VideoStreamSessionManager { |
| 45 | 38 | * @param mediaServerId 所使用的流媒体ID |
| 46 | 39 | * @param response 回复 |
| 47 | 40 | */ |
| 48 | - public void put(String deviceId, String channelId, String callId, String stream, String ssrc, String mediaServerId, SIPResponse response, SessionType type){ | |
| 41 | + public void put(String deviceId, String channelId, String callId, String stream, String ssrc, String mediaServerId, SIPResponse response, InviteSessionType type){ | |
| 49 | 42 | SsrcTransaction ssrcTransaction = new SsrcTransaction(); |
| 50 | 43 | ssrcTransaction.setDeviceId(deviceId); |
| 51 | 44 | ssrcTransaction.setChannelId(channelId); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java
| ... | ... | @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.conf.UserSetting; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 6 | 6 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 7 | 7 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| 8 | +import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; | |
| 8 | 9 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 9 | 10 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 10 | 11 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| ... | ... | @@ -38,6 +39,9 @@ public class SipRunner implements CommandLineRunner { |
| 38 | 39 | private IRedisCatchStorage redisCatchStorage; |
| 39 | 40 | |
| 40 | 41 | @Autowired |
| 42 | + private SSRCFactory ssrcFactory; | |
| 43 | + | |
| 44 | + @Autowired | |
| 41 | 45 | private UserSetting userSetting; |
| 42 | 46 | |
| 43 | 47 | @Autowired |
| ... | ... | @@ -96,6 +100,7 @@ public class SipRunner implements CommandLineRunner { |
| 96 | 100 | MediaServerItem mediaServerItem = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| 97 | 101 | redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(),sendRtpItem.getChannelId(), sendRtpItem.getCallId(),sendRtpItem.getStream()); |
| 98 | 102 | if (mediaServerItem != null) { |
| 103 | + ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); | |
| 99 | 104 | Map<String, Object> param = new HashMap<>(); |
| 100 | 105 | param.put("vhost","__defaultVhost__"); |
| 101 | 106 | param.put("app",sendRtpItem.getApp()); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java
| ... | ... | @@ -46,8 +46,7 @@ public class SIPSender { |
| 46 | 46 | transmitRequest(ip, message, errorEvent, null); |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | - public void transmitRequest(String ip, Message message, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws SipException, ParseException { | |
| 50 | - try { | |
| 49 | + public void transmitRequest(String ip, Message message, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws SipException { | |
| 51 | 50 | ViaHeader viaHeader = (ViaHeader)message.getHeader(ViaHeader.NAME); |
| 52 | 51 | String transport = "UDP"; |
| 53 | 52 | if (viaHeader == null) { |
| ... | ... | @@ -57,7 +56,7 @@ public class SIPSender { |
| 57 | 56 | } |
| 58 | 57 | if (message.getHeader(UserAgentHeader.NAME) == null) { |
| 59 | 58 | try { |
| 60 | - message.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 59 | + message.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 61 | 60 | } catch (ParseException e) { |
| 62 | 61 | logger.error("添加UserAgentHeader失败", e); |
| 63 | 62 | } |
| ... | ... | @@ -104,9 +103,6 @@ public class SIPSender { |
| 104 | 103 | sipProvider.sendResponse((Response)message); |
| 105 | 104 | } |
| 106 | 105 | } |
| 107 | - } finally { | |
| 108 | -// logger.info("[SEND]:SUCCESS:{}", message); | |
| 109 | - } | |
| 110 | 106 | } |
| 111 | 107 | |
| 112 | 108 | public CallIdHeader getNewCallIdHeader(String ip, String transport){ | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
| ... | ... | @@ -3,6 +3,8 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; |
| 3 | 3 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 4 | 4 | import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.Device; | |
| 7 | +import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; | |
| 6 | 8 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 7 | 9 | import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; |
| 8 | 10 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| ... | ... | @@ -107,7 +109,7 @@ public interface ISIPCommander { |
| 107 | 109 | * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss |
| 108 | 110 | * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss |
| 109 | 111 | */ |
| 110 | - void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime,InviteStreamCallback inviteStreamCallback, InviteStreamCallback event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; | |
| 112 | + void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime,ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; | |
| 111 | 113 | |
| 112 | 114 | /** |
| 113 | 115 | * 请求历史媒体下载 |
| ... | ... | @@ -119,7 +121,7 @@ public interface ISIPCommander { |
| 119 | 121 | * @param downloadSpeed 下载倍速参数 |
| 120 | 122 | */ |
| 121 | 123 | void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, |
| 122 | - String startTime, String endTime, int downloadSpeed, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, | |
| 124 | + String startTime, String endTime, int downloadSpeed, ZlmHttpHookSubscribe.Event hookEvent, | |
| 123 | 125 | SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException; |
| 124 | 126 | |
| 125 | 127 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
| ... | ... | @@ -17,6 +17,7 @@ import org.springframework.util.DigestUtils; |
| 17 | 17 | |
| 18 | 18 | import javax.sip.InvalidArgumentException; |
| 19 | 19 | import javax.sip.PeerUnavailableException; |
| 20 | +import javax.sip.SipFactory; | |
| 20 | 21 | import javax.sip.address.Address; |
| 21 | 22 | import javax.sip.address.SipURI; |
| 22 | 23 | import javax.sip.header.*; |
| ... | ... | @@ -50,39 +51,39 @@ public class SIPRequestHeaderPlarformProvider { |
| 50 | 51 | Request request = null; |
| 51 | 52 | String sipAddress = parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort(); |
| 52 | 53 | //请求行 |
| 53 | - SipURI requestLine = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), | |
| 54 | + SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), | |
| 54 | 55 | parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); |
| 55 | 56 | //via |
| 56 | 57 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 57 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(parentPlatform.getServerIP(), | |
| 58 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(parentPlatform.getServerIP(), | |
| 58 | 59 | parentPlatform.getServerPort(), parentPlatform.getTransport(), SipUtils.getNewViaTag()); |
| 59 | 60 | viaHeader.setRPort(); |
| 60 | 61 | viaHeaders.add(viaHeader); |
| 61 | 62 | //from |
| 62 | - SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), sipConfig.getDomain()); | |
| 63 | - Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | |
| 64 | - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, fromTag); | |
| 63 | + SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), sipConfig.getDomain()); | |
| 64 | + Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI); | |
| 65 | + FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, fromTag); | |
| 65 | 66 | //to |
| 66 | - SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), sipConfig.getDomain()); | |
| 67 | - Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | |
| 68 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress,toTag); | |
| 67 | + SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), sipConfig.getDomain()); | |
| 68 | + Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI); | |
| 69 | + ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress,toTag); | |
| 69 | 70 | |
| 70 | 71 | //Forwards |
| 71 | - MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | |
| 72 | + MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); | |
| 72 | 73 | |
| 73 | 74 | //ceq |
| 74 | - CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(CSeq, Request.REGISTER); | |
| 75 | - request = sipLayer.getSipFactory().createMessageFactory().createRequest(requestLine, Request.REGISTER, callIdHeader, | |
| 75 | + CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(CSeq, Request.REGISTER); | |
| 76 | + request = SipFactory.getInstance().createMessageFactory().createRequest(requestLine, Request.REGISTER, callIdHeader, | |
| 76 | 77 | cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); |
| 77 | 78 | |
| 78 | - Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory() | |
| 79 | + Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(SipFactory.getInstance().createAddressFactory() | |
| 79 | 80 | .createSipURI(parentPlatform.getDeviceGBId(), sipAddress)); |
| 80 | - request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress)); | |
| 81 | + request.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress)); | |
| 81 | 82 | |
| 82 | - ExpiresHeader expiresHeader = sipLayer.getSipFactory().createHeaderFactory().createExpiresHeader(expires); | |
| 83 | + ExpiresHeader expiresHeader = SipFactory.getInstance().createHeaderFactory().createExpiresHeader(expires); | |
| 83 | 84 | request.addHeader(expiresHeader); |
| 84 | 85 | |
| 85 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 86 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 86 | 87 | |
| 87 | 88 | return request; |
| 88 | 89 | } |
| ... | ... | @@ -92,9 +93,9 @@ public class SIPRequestHeaderPlarformProvider { |
| 92 | 93 | |
| 93 | 94 | |
| 94 | 95 | Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(), fromTag, toTag, callIdHeader, expires); |
| 95 | - SipURI requestURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); | |
| 96 | + SipURI requestURI = SipFactory.getInstance().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); | |
| 96 | 97 | if (www == null) { |
| 97 | - AuthorizationHeader authorizationHeader = sipLayer.getSipFactory().createHeaderFactory().createAuthorizationHeader("Digest"); | |
| 98 | + AuthorizationHeader authorizationHeader = SipFactory.getInstance().createHeaderFactory().createAuthorizationHeader("Digest"); | |
| 98 | 99 | String username = parentPlatform.getUsername(); |
| 99 | 100 | if ( username == null || username == "" ) |
| 100 | 101 | { |
| ... | ... | @@ -147,7 +148,7 @@ public class SIPRequestHeaderPlarformProvider { |
| 147 | 148 | |
| 148 | 149 | String RESPONSE = DigestUtils.md5DigestAsHex(reStr.toString().getBytes()); |
| 149 | 150 | |
| 150 | - AuthorizationHeader authorizationHeader = sipLayer.getSipFactory().createHeaderFactory().createAuthorizationHeader(scheme); | |
| 151 | + AuthorizationHeader authorizationHeader = SipFactory.getInstance().createHeaderFactory().createAuthorizationHeader(scheme); | |
| 151 | 152 | authorizationHeader.setUsername(parentPlatform.getDeviceGBId()); |
| 152 | 153 | authorizationHeader.setRealm(realm); |
| 153 | 154 | authorizationHeader.setNonce(nonce); |
| ... | ... | @@ -165,7 +166,7 @@ public class SIPRequestHeaderPlarformProvider { |
| 165 | 166 | } |
| 166 | 167 | |
| 167 | 168 | public Request createMessageRequest(ParentPlatform parentPlatform, String content, SendRtpItem sendRtpItem) throws PeerUnavailableException, ParseException, InvalidArgumentException { |
| 168 | - CallIdHeader callIdHeader = sipLayer.getSipFactory().createHeaderFactory().createCallIdHeader(sendRtpItem.getCallId()); | |
| 169 | + CallIdHeader callIdHeader = SipFactory.getInstance().createHeaderFactory().createCallIdHeader(sendRtpItem.getCallId()); | |
| 169 | 170 | return createMessageRequest(parentPlatform, content, sendRtpItem.getToTag(), SipUtils.getNewViaTag(), sendRtpItem.getFromTag(), callIdHeader); |
| 170 | 171 | } |
| 171 | 172 | |
| ... | ... | @@ -178,36 +179,36 @@ public class SIPRequestHeaderPlarformProvider { |
| 178 | 179 | Request request = null; |
| 179 | 180 | String serverAddress = parentPlatform.getServerIP()+ ":" + parentPlatform.getServerPort(); |
| 180 | 181 | // sipuri |
| 181 | - SipURI requestURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), serverAddress); | |
| 182 | + SipURI requestURI = SipFactory.getInstance().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), serverAddress); | |
| 182 | 183 | // via |
| 183 | 184 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 184 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(), parentPlatform.getDevicePort(), | |
| 185 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(), parentPlatform.getDevicePort(), | |
| 185 | 186 | parentPlatform.getTransport(), viaTag); |
| 186 | 187 | viaHeader.setRPort(); |
| 187 | 188 | viaHeaders.add(viaHeader); |
| 188 | 189 | // from |
| 189 | - // SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), parentPlatform.getDeviceIp() + ":" + parentPlatform.getDeviceIp()); | |
| 190 | - SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), sipConfig.getDomain()); | |
| 191 | - Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | |
| 192 | - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, fromTag); | |
| 190 | + // SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), parentPlatform.getDeviceIp() + ":" + parentPlatform.getDeviceIp()); | |
| 191 | + SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), sipConfig.getDomain()); | |
| 192 | + Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI); | |
| 193 | + FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, fromTag); | |
| 193 | 194 | // to |
| 194 | - SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), serverAddress); | |
| 195 | - Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | |
| 196 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress, toTag); | |
| 195 | + SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), serverAddress); | |
| 196 | + Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI); | |
| 197 | + ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress, toTag); | |
| 197 | 198 | |
| 198 | 199 | // Forwards |
| 199 | - MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | |
| 200 | + MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); | |
| 200 | 201 | // ceq |
| 201 | - CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.MESSAGE); | |
| 202 | - MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipLayer.getSipFactory().createMessageFactory(); | |
| 202 | + CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.MESSAGE); | |
| 203 | + MessageFactoryImpl messageFactory = (MessageFactoryImpl) SipFactory.getInstance().createMessageFactory(); | |
| 203 | 204 | // 设置编码, 防止中文乱码 |
| 204 | 205 | messageFactory.setDefaultContentEncodingCharset(parentPlatform.getCharacterSet()); |
| 205 | 206 | request = messageFactory.createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader, |
| 206 | 207 | toHeader, viaHeaders, maxForwards); |
| 207 | 208 | |
| 208 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 209 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 209 | 210 | |
| 210 | - ContentTypeHeader contentTypeHeader = sipLayer.getSipFactory().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); | |
| 211 | + ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); | |
| 211 | 212 | request.setContent(content, contentTypeHeader); |
| 212 | 213 | return request; |
| 213 | 214 | } |
| ... | ... | @@ -215,54 +216,54 @@ public class SIPRequestHeaderPlarformProvider { |
| 215 | 216 | public SIPRequest createNotifyRequest(ParentPlatform parentPlatform, String content, SubscribeInfo subscribeInfo) throws PeerUnavailableException, ParseException, InvalidArgumentException { |
| 216 | 217 | SIPRequest request = null; |
| 217 | 218 | // sipuri |
| 218 | - SipURI requestURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP()+ ":" + parentPlatform.getServerPort()); | |
| 219 | + SipURI requestURI = SipFactory.getInstance().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP()+ ":" + parentPlatform.getServerPort()); | |
| 219 | 220 | // via |
| 220 | 221 | ArrayList<ViaHeader> viaHeaders = new ArrayList<>(); |
| 221 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(), parentPlatform.getDevicePort(), | |
| 222 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(), parentPlatform.getDevicePort(), | |
| 222 | 223 | parentPlatform.getTransport(), SipUtils.getNewViaTag()); |
| 223 | 224 | viaHeader.setRPort(); |
| 224 | 225 | viaHeaders.add(viaHeader); |
| 225 | 226 | // from |
| 226 | - SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), | |
| 227 | + SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), | |
| 227 | 228 | parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort()); |
| 228 | - Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | |
| 229 | - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, subscribeInfo.getResponse().getToTag()); | |
| 229 | + Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI); | |
| 230 | + FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, subscribeInfo.getResponse().getToTag()); | |
| 230 | 231 | // to |
| 231 | - SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerGBDomain()); | |
| 232 | - Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | |
| 233 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress, subscribeInfo.getRequest().getFromTag()); | |
| 232 | + SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerGBDomain()); | |
| 233 | + Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI); | |
| 234 | + ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress, subscribeInfo.getRequest().getFromTag()); | |
| 234 | 235 | |
| 235 | 236 | // Forwards |
| 236 | - MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | |
| 237 | + MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); | |
| 237 | 238 | // ceq |
| 238 | - CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.NOTIFY); | |
| 239 | - MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipLayer.getSipFactory().createMessageFactory(); | |
| 239 | + CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.NOTIFY); | |
| 240 | + MessageFactoryImpl messageFactory = (MessageFactoryImpl) SipFactory.getInstance().createMessageFactory(); | |
| 240 | 241 | // 设置编码, 防止中文乱码 |
| 241 | 242 | messageFactory.setDefaultContentEncodingCharset("gb2312"); |
| 242 | 243 | |
| 243 | - CallIdHeader callIdHeader = sipLayer.getSipFactory().createHeaderFactory().createCallIdHeader(subscribeInfo.getRequest().getCallIdHeader().getCallId()); | |
| 244 | + CallIdHeader callIdHeader = SipFactory.getInstance().createHeaderFactory().createCallIdHeader(subscribeInfo.getRequest().getCallIdHeader().getCallId()); | |
| 244 | 245 | |
| 245 | 246 | request = (SIPRequest) messageFactory.createRequest(requestURI, Request.NOTIFY, callIdHeader, cSeqHeader, fromHeader, |
| 246 | 247 | toHeader, viaHeaders, maxForwards); |
| 247 | 248 | |
| 248 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 249 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 249 | 250 | |
| 250 | - EventHeader event = sipLayer.getSipFactory().createHeaderFactory().createEventHeader(subscribeInfo.getEventType()); | |
| 251 | + EventHeader event = SipFactory.getInstance().createHeaderFactory().createEventHeader(subscribeInfo.getEventType()); | |
| 251 | 252 | if (subscribeInfo.getEventId() != null) { |
| 252 | 253 | event.setEventId(subscribeInfo.getEventId()); |
| 253 | 254 | } |
| 254 | 255 | |
| 255 | 256 | request.addHeader(event); |
| 256 | 257 | |
| 257 | - SubscriptionStateHeader active = sipLayer.getSipFactory().createHeaderFactory().createSubscriptionStateHeader("active"); | |
| 258 | + SubscriptionStateHeader active = SipFactory.getInstance().createHeaderFactory().createSubscriptionStateHeader("active"); | |
| 258 | 259 | request.setHeader(active); |
| 259 | 260 | |
| 260 | 261 | String sipAddress = parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort(); |
| 261 | - Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory() | |
| 262 | + Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(SipFactory.getInstance().createAddressFactory() | |
| 262 | 263 | .createSipURI(parentPlatform.getDeviceGBId(), sipAddress)); |
| 263 | - request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress)); | |
| 264 | + request.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress)); | |
| 264 | 265 | |
| 265 | - ContentTypeHeader contentTypeHeader = sipLayer.getSipFactory().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); | |
| 266 | + ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); | |
| 266 | 267 | request.setContent(content, contentTypeHeader); |
| 267 | 268 | return request; |
| 268 | 269 | } |
| ... | ... | @@ -275,42 +276,42 @@ public class SIPRequestHeaderPlarformProvider { |
| 275 | 276 | |
| 276 | 277 | SIPRequest request = null; |
| 277 | 278 | // sipuri |
| 278 | - SipURI requestURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(platform.getServerGBId(), platform.getServerIP()+ ":" + platform.getServerPort()); | |
| 279 | + SipURI requestURI = SipFactory.getInstance().createAddressFactory().createSipURI(platform.getServerGBId(), platform.getServerIP()+ ":" + platform.getServerPort()); | |
| 279 | 280 | // via |
| 280 | 281 | ArrayList<ViaHeader> viaHeaders = new ArrayList<>(); |
| 281 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(platform.getDeviceIp(), platform.getDevicePort(), | |
| 282 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(platform.getDeviceIp(), platform.getDevicePort(), | |
| 282 | 283 | platform.getTransport(), SipUtils.getNewViaTag()); |
| 283 | 284 | viaHeader.setRPort(); |
| 284 | 285 | viaHeaders.add(viaHeader); |
| 285 | 286 | // from |
| 286 | - SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(platform.getDeviceGBId(), | |
| 287 | + SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(platform.getDeviceGBId(), | |
| 287 | 288 | platform.getDeviceIp() + ":" + platform.getDevicePort()); |
| 288 | - Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | |
| 289 | - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, sendRtpItem.getToTag()); | |
| 289 | + Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI); | |
| 290 | + FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, sendRtpItem.getToTag()); | |
| 290 | 291 | // to |
| 291 | - SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(platform.getServerGBId(), platform.getServerGBDomain()); | |
| 292 | - Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | |
| 293 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress, sendRtpItem.getFromTag()); | |
| 292 | + SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(platform.getServerGBId(), platform.getServerGBDomain()); | |
| 293 | + Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI); | |
| 294 | + ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress, sendRtpItem.getFromTag()); | |
| 294 | 295 | |
| 295 | 296 | // Forwards |
| 296 | - MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | |
| 297 | + MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); | |
| 297 | 298 | // ceq |
| 298 | - CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.BYE); | |
| 299 | - MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipLayer.getSipFactory().createMessageFactory(); | |
| 299 | + CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.BYE); | |
| 300 | + MessageFactoryImpl messageFactory = (MessageFactoryImpl) SipFactory.getInstance().createMessageFactory(); | |
| 300 | 301 | // 设置编码, 防止中文乱码 |
| 301 | 302 | messageFactory.setDefaultContentEncodingCharset("gb2312"); |
| 302 | 303 | |
| 303 | - CallIdHeader callIdHeader = sipLayer.getSipFactory().createHeaderFactory().createCallIdHeader(sendRtpItem.getCallId()); | |
| 304 | + CallIdHeader callIdHeader = SipFactory.getInstance().createHeaderFactory().createCallIdHeader(sendRtpItem.getCallId()); | |
| 304 | 305 | |
| 305 | 306 | request = (SIPRequest) messageFactory.createRequest(requestURI, Request.BYE, callIdHeader, cSeqHeader, fromHeader, |
| 306 | 307 | toHeader, viaHeaders, maxForwards); |
| 307 | 308 | |
| 308 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 309 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 309 | 310 | |
| 310 | 311 | String sipAddress = platform.getDeviceIp() + ":" + platform.getDevicePort(); |
| 311 | - Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory() | |
| 312 | + Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(SipFactory.getInstance().createAddressFactory() | |
| 312 | 313 | .createSipURI(platform.getDeviceGBId(), sipAddress)); |
| 313 | - request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress)); | |
| 314 | + request.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress)); | |
| 314 | 315 | |
| 315 | 316 | return request; |
| 316 | 317 | } |
| ... | ... | @@ -320,37 +321,37 @@ public class SIPRequestHeaderPlarformProvider { |
| 320 | 321 | //请求行 |
| 321 | 322 | String platformHostAddress = platform.getServerIP() + ":" + platform.getServerPort(); |
| 322 | 323 | String localHostAddress = sipLayer.getLocalIp(platform.getDeviceIp())+":"+ platform.getDevicePort(); |
| 323 | - SipURI requestLine = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, platformHostAddress); | |
| 324 | + SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, platformHostAddress); | |
| 324 | 325 | //via |
| 325 | 326 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 326 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(platform.getDeviceIp()), platform.getDevicePort(), platform.getTransport(), viaTag); | |
| 327 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(platform.getDeviceIp()), platform.getDevicePort(), platform.getTransport(), viaTag); | |
| 327 | 328 | viaHeader.setRPort(); |
| 328 | 329 | viaHeaders.add(viaHeader); |
| 329 | 330 | |
| 330 | 331 | //from |
| 331 | - SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(platform.getDeviceGBId(), sipConfig.getDomain()); | |
| 332 | - Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | |
| 333 | - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack | |
| 332 | + SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(platform.getDeviceGBId(), sipConfig.getDomain()); | |
| 333 | + Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI); | |
| 334 | + FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack | |
| 334 | 335 | //to |
| 335 | - SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, platformHostAddress); | |
| 336 | - Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | |
| 337 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress,null); | |
| 336 | + SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, platformHostAddress); | |
| 337 | + Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI); | |
| 338 | + ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress,null); | |
| 338 | 339 | |
| 339 | 340 | //Forwards |
| 340 | - MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | |
| 341 | + MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); | |
| 341 | 342 | |
| 342 | 343 | //ceq |
| 343 | - CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.INVITE); | |
| 344 | - request = sipLayer.getSipFactory().createMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | |
| 344 | + CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.INVITE); | |
| 345 | + request = SipFactory.getInstance().createMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | |
| 345 | 346 | |
| 346 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 347 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 347 | 348 | |
| 348 | - Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(),localHostAddress)); | |
| 349 | - request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress)); | |
| 349 | + Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(),localHostAddress)); | |
| 350 | + request.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress)); | |
| 350 | 351 | // Subject |
| 351 | - SubjectHeader subjectHeader = sipLayer.getSipFactory().createHeaderFactory().createSubjectHeader(String.format("%s:%s,%s:%s", channelId, ssrc, sipConfig.getId(), 0)); | |
| 352 | + SubjectHeader subjectHeader = SipFactory.getInstance().createHeaderFactory().createSubjectHeader(String.format("%s:%s,%s:%s", channelId, ssrc, sipConfig.getId(), 0)); | |
| 352 | 353 | request.addHeader(subjectHeader); |
| 353 | - ContentTypeHeader contentTypeHeader = sipLayer.getSipFactory().createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); | |
| 354 | + ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); | |
| 354 | 355 | request.setContent(content, contentTypeHeader); |
| 355 | 356 | return request; |
| 356 | 357 | } |
| ... | ... | @@ -358,35 +359,35 @@ public class SIPRequestHeaderPlarformProvider { |
| 358 | 359 | public Request createByteRequest(ParentPlatform platform, String channelId, SipTransactionInfo transactionInfo) throws PeerUnavailableException, ParseException, InvalidArgumentException { |
| 359 | 360 | String deviceHostAddress = platform.getDeviceIp() + ":" + platform.getDevicePort(); |
| 360 | 361 | Request request = null; |
| 361 | - SipURI requestLine = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, deviceHostAddress); | |
| 362 | + SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, deviceHostAddress); | |
| 362 | 363 | |
| 363 | 364 | // via |
| 364 | 365 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 365 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(platform.getDeviceIp()), platform.getDevicePort(), platform.getTransport(), SipUtils.getNewViaTag()); | |
| 366 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(platform.getDeviceIp()), platform.getDevicePort(), platform.getTransport(), SipUtils.getNewViaTag()); | |
| 366 | 367 | viaHeaders.add(viaHeader); |
| 367 | 368 | //from |
| 368 | - SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain()); | |
| 369 | - Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | |
| 370 | - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, transactionInfo.isAsSender()?transactionInfo.getFromTag():transactionInfo.getToTag()); | |
| 369 | + SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain()); | |
| 370 | + Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI); | |
| 371 | + FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, transactionInfo.isAsSender()?transactionInfo.getFromTag():transactionInfo.getToTag()); | |
| 371 | 372 | //to |
| 372 | - SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, deviceHostAddress); | |
| 373 | - Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | |
| 374 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress,transactionInfo.isAsSender()?transactionInfo.getToTag():transactionInfo.getFromTag()); | |
| 373 | + SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, deviceHostAddress); | |
| 374 | + Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI); | |
| 375 | + ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress,transactionInfo.isAsSender()?transactionInfo.getToTag():transactionInfo.getFromTag()); | |
| 375 | 376 | |
| 376 | 377 | //Forwards |
| 377 | - MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | |
| 378 | + MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); | |
| 378 | 379 | |
| 379 | 380 | //ceq |
| 380 | - CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.BYE); | |
| 381 | - CallIdHeader callIdHeader = sipLayer.getSipFactory().createHeaderFactory().createCallIdHeader(transactionInfo.getCallId()); | |
| 382 | - request = sipLayer.getSipFactory().createMessageFactory().createRequest(requestLine, Request.BYE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | |
| 381 | + CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.BYE); | |
| 382 | + CallIdHeader callIdHeader = SipFactory.getInstance().createHeaderFactory().createCallIdHeader(transactionInfo.getCallId()); | |
| 383 | + request = SipFactory.getInstance().createMessageFactory().createRequest(requestLine, Request.BYE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | |
| 383 | 384 | |
| 384 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 385 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 385 | 386 | |
| 386 | - Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(platform.getDeviceIp())+":"+ platform.getDevicePort())); | |
| 387 | - request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress)); | |
| 387 | + Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(platform.getDeviceIp())+":"+ platform.getDevicePort())); | |
| 388 | + request.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress)); | |
| 388 | 389 | |
| 389 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 390 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 390 | 391 | |
| 391 | 392 | return request; |
| 392 | 393 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
| ... | ... | @@ -16,6 +16,7 @@ import org.springframework.stereotype.Component; |
| 16 | 16 | import javax.sip.InvalidArgumentException; |
| 17 | 17 | import javax.sip.PeerUnavailableException; |
| 18 | 18 | import javax.sip.SipException; |
| 19 | +import javax.sip.SipFactory; | |
| 19 | 20 | import javax.sip.address.Address; |
| 20 | 21 | import javax.sip.address.SipURI; |
| 21 | 22 | import javax.sip.header.*; |
| ... | ... | @@ -49,32 +50,32 @@ public class SIPRequestHeaderProvider { |
| 49 | 50 | public Request createMessageRequest(Device device, String content, String viaTag, String fromTag, String toTag, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException { |
| 50 | 51 | Request request = null; |
| 51 | 52 | // sipuri |
| 52 | - SipURI requestURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress()); | |
| 53 | + SipURI requestURI = SipFactory.getInstance().createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress()); | |
| 53 | 54 | // via |
| 54 | 55 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 55 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), device.getTransport(), viaTag); | |
| 56 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), device.getTransport(), viaTag); | |
| 56 | 57 | viaHeader.setRPort(); |
| 57 | 58 | viaHeaders.add(viaHeader); |
| 58 | 59 | // from |
| 59 | - SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain()); | |
| 60 | - Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | |
| 61 | - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, fromTag); | |
| 60 | + SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain()); | |
| 61 | + Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI); | |
| 62 | + FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, fromTag); | |
| 62 | 63 | // to |
| 63 | - SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress()); | |
| 64 | - Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | |
| 65 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress, toTag); | |
| 64 | + SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress()); | |
| 65 | + Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI); | |
| 66 | + ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress, toTag); | |
| 66 | 67 | |
| 67 | 68 | // Forwards |
| 68 | - MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | |
| 69 | + MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); | |
| 69 | 70 | // ceq |
| 70 | - CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.MESSAGE); | |
| 71 | + CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.MESSAGE); | |
| 71 | 72 | |
| 72 | - request = sipLayer.getSipFactory().createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader, | |
| 73 | + request = SipFactory.getInstance().createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader, | |
| 73 | 74 | toHeader, viaHeaders, maxForwards); |
| 74 | 75 | |
| 75 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 76 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 76 | 77 | |
| 77 | - ContentTypeHeader contentTypeHeader = sipLayer.getSipFactory().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); | |
| 78 | + ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); | |
| 78 | 79 | request.setContent(content, contentTypeHeader); |
| 79 | 80 | return request; |
| 80 | 81 | } |
| ... | ... | @@ -82,39 +83,39 @@ public class SIPRequestHeaderProvider { |
| 82 | 83 | public Request createInviteRequest(Device device, String channelId, String content, String viaTag, String fromTag, String toTag, String ssrc, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException { |
| 83 | 84 | Request request = null; |
| 84 | 85 | //请求行 |
| 85 | - SipURI requestLine = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 86 | + SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 86 | 87 | //via |
| 87 | 88 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 88 | - HeaderFactory headerFactory = sipLayer.getSipFactory().createHeaderFactory(); | |
| 89 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), device.getTransport(), viaTag); | |
| 89 | + HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); | |
| 90 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), device.getTransport(), viaTag); | |
| 90 | 91 | viaHeader.setRPort(); |
| 91 | 92 | viaHeaders.add(viaHeader); |
| 92 | 93 | |
| 93 | 94 | //from |
| 94 | - SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain()); | |
| 95 | - Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | |
| 96 | - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack | |
| 95 | + SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain()); | |
| 96 | + Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI); | |
| 97 | + FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack | |
| 97 | 98 | //to |
| 98 | - SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 99 | - Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | |
| 100 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress,null); | |
| 99 | + SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 100 | + Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI); | |
| 101 | + ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress,null); | |
| 101 | 102 | |
| 102 | 103 | //Forwards |
| 103 | - MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | |
| 104 | + MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); | |
| 104 | 105 | |
| 105 | 106 | //ceq |
| 106 | - CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.INVITE); | |
| 107 | - request = sipLayer.getSipFactory().createMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | |
| 107 | + CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.INVITE); | |
| 108 | + request = SipFactory.getInstance().createMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | |
| 108 | 109 | |
| 109 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 110 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 110 | 111 | |
| 111 | - Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(device.getLocalIp())+":"+sipConfig.getPort())); | |
| 112 | - // Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), device.getHost().getIp()+":"+device.getHost().getPort())); | |
| 113 | - request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress)); | |
| 112 | + Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(device.getLocalIp())+":"+sipConfig.getPort())); | |
| 113 | + // Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), device.getHost().getIp()+":"+device.getHost().getPort())); | |
| 114 | + request.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress)); | |
| 114 | 115 | // Subject |
| 115 | - SubjectHeader subjectHeader = sipLayer.getSipFactory().createHeaderFactory().createSubjectHeader(String.format("%s:%s,%s:%s", channelId, ssrc, sipConfig.getId(), 0)); | |
| 116 | + SubjectHeader subjectHeader = SipFactory.getInstance().createHeaderFactory().createSubjectHeader(String.format("%s:%s,%s:%s", channelId, ssrc, sipConfig.getId(), 0)); | |
| 116 | 117 | request.addHeader(subjectHeader); |
| 117 | - ContentTypeHeader contentTypeHeader = sipLayer.getSipFactory().createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); | |
| 118 | + ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); | |
| 118 | 119 | request.setContent(content, contentTypeHeader); |
| 119 | 120 | return request; |
| 120 | 121 | } |
| ... | ... | @@ -122,69 +123,74 @@ public class SIPRequestHeaderProvider { |
| 122 | 123 | public Request createPlaybackInviteRequest(Device device, String channelId, String content, String viaTag, String fromTag, String toTag, CallIdHeader callIdHeader, String ssrc) throws ParseException, InvalidArgumentException, PeerUnavailableException { |
| 123 | 124 | Request request = null; |
| 124 | 125 | //请求行 |
| 125 | - SipURI requestLine = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 126 | + SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 126 | 127 | // via |
| 127 | 128 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 128 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), device.getTransport(), viaTag); | |
| 129 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), device.getTransport(), viaTag); | |
| 129 | 130 | viaHeader.setRPort(); |
| 130 | 131 | viaHeaders.add(viaHeader); |
| 131 | 132 | //from |
| 132 | - SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain()); | |
| 133 | - Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | |
| 134 | - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack | |
| 133 | + SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain()); | |
| 134 | + Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI); | |
| 135 | + FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack | |
| 135 | 136 | //to |
| 136 | - SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 137 | - Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | |
| 138 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress,null); | |
| 137 | + SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 138 | + Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI); | |
| 139 | + ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress,null); | |
| 139 | 140 | |
| 140 | 141 | //Forwards |
| 141 | - MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | |
| 142 | + MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); | |
| 142 | 143 | |
| 143 | 144 | //ceq |
| 144 | - CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.INVITE); | |
| 145 | - request = sipLayer.getSipFactory().createMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | |
| 145 | + CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.INVITE); | |
| 146 | + request = SipFactory.getInstance().createMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | |
| 146 | 147 | |
| 147 | - Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(device.getLocalIp())+":"+sipConfig.getPort())); | |
| 148 | - // Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), device.getHost().getIp()+":"+device.getHost().getPort())); | |
| 149 | - request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress)); | |
| 148 | + Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(device.getLocalIp())+":"+sipConfig.getPort())); | |
| 149 | + // Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), device.getHost().getIp()+":"+device.getHost().getPort())); | |
| 150 | + request.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress)); | |
| 150 | 151 | |
| 151 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 152 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 152 | 153 | |
| 153 | 154 | // Subject |
| 154 | - SubjectHeader subjectHeader = sipLayer.getSipFactory().createHeaderFactory().createSubjectHeader(String.format("%s:%s,%s:%s", channelId, ssrc, sipConfig.getId(), 0)); | |
| 155 | + SubjectHeader subjectHeader = SipFactory.getInstance().createHeaderFactory().createSubjectHeader(String.format("%s:%s,%s:%s", channelId, ssrc, sipConfig.getId(), 0)); | |
| 155 | 156 | request.addHeader(subjectHeader); |
| 156 | 157 | |
| 157 | - ContentTypeHeader contentTypeHeader = sipLayer.getSipFactory().createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); | |
| 158 | + ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); | |
| 158 | 159 | request.setContent(content, contentTypeHeader); |
| 159 | 160 | return request; |
| 160 | 161 | } |
| 161 | 162 | |
| 162 | 163 | public Request createByteRequest(Device device, String channelId, SipTransactionInfo transactionInfo) throws ParseException, InvalidArgumentException, PeerUnavailableException { |
| 163 | 164 | Request request = null; |
| 164 | - SipURI requestLine = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 165 | - | |
| 165 | + //请求行 | |
| 166 | + SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 166 | 167 | // via |
| 167 | 168 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 168 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), device.getTransport(), SipUtils.getNewViaTag()); | |
| 169 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), device.getTransport(), SipUtils.getNewViaTag()); | |
| 169 | 170 | viaHeaders.add(viaHeader); |
| 170 | 171 | //from |
| 171 | - SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain()); | |
| 172 | - Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | |
| 173 | - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, !transactionInfo.isAsSender()? transactionInfo.getToTag():transactionInfo.getFromTag()); | |
| 172 | + SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain()); | |
| 173 | + Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI); | |
| 174 | + FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, transactionInfo.getFromTag()); | |
| 174 | 175 | //to |
| 175 | - SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId,device.getHostAddress()); | |
| 176 | - Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | |
| 177 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress, !transactionInfo.isAsSender()? transactionInfo.getToTag(): transactionInfo.getFromTag()); | |
| 176 | + SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(channelId,device.getHostAddress()); | |
| 177 | + Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI); | |
| 178 | + ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress, transactionInfo.getToTag()); | |
| 178 | 179 | |
| 179 | 180 | //Forwards |
| 180 | - MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | |
| 181 | + MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); | |
| 181 | 182 | |
| 182 | 183 | //ceq |
| 183 | - CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.BYE); | |
| 184 | - CallIdHeader callIdHeader = sipLayer.getSipFactory().createHeaderFactory().createCallIdHeader(transactionInfo.getCallId()); | |
| 185 | - request = sipLayer.getSipFactory().createMessageFactory().createRequest(requestLine, Request.BYE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | |
| 184 | + CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.BYE); | |
| 185 | + CallIdHeader callIdHeader = SipFactory.getInstance().createHeaderFactory().createCallIdHeader(transactionInfo.getCallId()); | |
| 186 | + request = SipFactory.getInstance().createMessageFactory().createRequest(requestLine, Request.BYE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | |
| 187 | + | |
| 188 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 186 | 189 | |
| 187 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 190 | + Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(device.getLocalIp())+":"+sipConfig.getPort())); | |
| 191 | + request.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress)); | |
| 192 | + | |
| 193 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 188 | 194 | |
| 189 | 195 | return request; |
| 190 | 196 | } |
| ... | ... | @@ -192,50 +198,50 @@ public class SIPRequestHeaderProvider { |
| 192 | 198 | public Request createSubscribeRequest(Device device, String content, SIPRequest requestOld, Integer expires, String event, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException { |
| 193 | 199 | Request request = null; |
| 194 | 200 | // sipuri |
| 195 | - SipURI requestURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress()); | |
| 201 | + SipURI requestURI = SipFactory.getInstance().createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress()); | |
| 196 | 202 | // via |
| 197 | 203 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 198 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), | |
| 204 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), | |
| 199 | 205 | device.getTransport(), SipUtils.getNewViaTag()); |
| 200 | 206 | viaHeader.setRPort(); |
| 201 | 207 | viaHeaders.add(viaHeader); |
| 202 | 208 | // from |
| 203 | - SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain()); | |
| 204 | - Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | |
| 205 | - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, requestOld == null ? SipUtils.getNewFromTag() :requestOld.getFromTag()); | |
| 209 | + SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain()); | |
| 210 | + Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI); | |
| 211 | + FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, requestOld == null ? SipUtils.getNewFromTag() :requestOld.getFromTag()); | |
| 206 | 212 | // to |
| 207 | - SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress()); | |
| 208 | - Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | |
| 209 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress, requestOld == null ? null :requestOld.getToTag()); | |
| 213 | + SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress()); | |
| 214 | + Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI); | |
| 215 | + ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress, requestOld == null ? null :requestOld.getToTag()); | |
| 210 | 216 | |
| 211 | 217 | // Forwards |
| 212 | - MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | |
| 218 | + MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); | |
| 213 | 219 | |
| 214 | 220 | // ceq |
| 215 | - CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.SUBSCRIBE); | |
| 221 | + CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.SUBSCRIBE); | |
| 216 | 222 | |
| 217 | - request = sipLayer.getSipFactory().createMessageFactory().createRequest(requestURI, Request.SUBSCRIBE, callIdHeader, cSeqHeader, fromHeader, | |
| 223 | + request = SipFactory.getInstance().createMessageFactory().createRequest(requestURI, Request.SUBSCRIBE, callIdHeader, cSeqHeader, fromHeader, | |
| 218 | 224 | toHeader, viaHeaders, maxForwards); |
| 219 | 225 | |
| 220 | 226 | |
| 221 | - Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(device.getLocalIp())+":"+sipConfig.getPort())); | |
| 222 | - request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress)); | |
| 227 | + Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(device.getLocalIp())+":"+sipConfig.getPort())); | |
| 228 | + request.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress)); | |
| 223 | 229 | |
| 224 | 230 | // Expires |
| 225 | - ExpiresHeader expireHeader = sipLayer.getSipFactory().createHeaderFactory().createExpiresHeader(expires); | |
| 231 | + ExpiresHeader expireHeader = SipFactory.getInstance().createHeaderFactory().createExpiresHeader(expires); | |
| 226 | 232 | request.addHeader(expireHeader); |
| 227 | 233 | |
| 228 | 234 | // Event |
| 229 | - EventHeader eventHeader = sipLayer.getSipFactory().createHeaderFactory().createEventHeader(event); | |
| 235 | + EventHeader eventHeader = SipFactory.getInstance().createHeaderFactory().createEventHeader(event); | |
| 230 | 236 | |
| 231 | 237 | int random = (int) Math.floor(Math.random() * 10000); |
| 232 | 238 | eventHeader.setEventId(random + ""); |
| 233 | 239 | request.addHeader(eventHeader); |
| 234 | 240 | |
| 235 | - ContentTypeHeader contentTypeHeader = sipLayer.getSipFactory().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); | |
| 241 | + ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); | |
| 236 | 242 | request.setContent(content, contentTypeHeader); |
| 237 | 243 | |
| 238 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 244 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 239 | 245 | |
| 240 | 246 | return request; |
| 241 | 247 | } |
| ... | ... | @@ -247,37 +253,37 @@ public class SIPRequestHeaderProvider { |
| 247 | 253 | } |
| 248 | 254 | SIPRequest request = null; |
| 249 | 255 | //请求行 |
| 250 | - SipURI requestLine = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 256 | + SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 251 | 257 | // via |
| 252 | 258 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 253 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), device.getTransport(), SipUtils.getNewViaTag()); | |
| 259 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), device.getTransport(), SipUtils.getNewViaTag()); | |
| 254 | 260 | viaHeaders.add(viaHeader); |
| 255 | 261 | //from |
| 256 | - SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain()); | |
| 257 | - Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | |
| 258 | - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, transactionInfo.getFromTag()); | |
| 262 | + SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain()); | |
| 263 | + Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI); | |
| 264 | + FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, transactionInfo.getFromTag()); | |
| 259 | 265 | //to |
| 260 | - SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId,device.getHostAddress()); | |
| 261 | - Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | |
| 262 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress, transactionInfo.getToTag()); | |
| 266 | + SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(channelId,device.getHostAddress()); | |
| 267 | + Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI); | |
| 268 | + ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress, transactionInfo.getToTag()); | |
| 263 | 269 | |
| 264 | 270 | //Forwards |
| 265 | - MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | |
| 271 | + MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); | |
| 266 | 272 | |
| 267 | 273 | //ceq |
| 268 | - CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.INFO); | |
| 269 | - CallIdHeader callIdHeader = sipLayer.getSipFactory().createHeaderFactory().createCallIdHeader(transactionInfo.getCallId()); | |
| 270 | - request = (SIPRequest)sipLayer.getSipFactory().createMessageFactory().createRequest(requestLine, Request.INFO, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | |
| 274 | + CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.INFO); | |
| 275 | + CallIdHeader callIdHeader = SipFactory.getInstance().createHeaderFactory().createCallIdHeader(transactionInfo.getCallId()); | |
| 276 | + request = (SIPRequest)SipFactory.getInstance().createMessageFactory().createRequest(requestLine, Request.INFO, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | |
| 271 | 277 | |
| 272 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 278 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 273 | 279 | |
| 274 | - Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(device.getLocalIp())+":"+sipConfig.getPort())); | |
| 275 | - request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress)); | |
| 280 | + Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(device.getLocalIp())+":"+sipConfig.getPort())); | |
| 281 | + request.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress)); | |
| 276 | 282 | |
| 277 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 283 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 278 | 284 | |
| 279 | 285 | if (content != null) { |
| 280 | - ContentTypeHeader contentTypeHeader = sipLayer.getSipFactory().createHeaderFactory().createContentTypeHeader("Application", | |
| 286 | + ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("Application", | |
| 281 | 287 | "MANSRTSP"); |
| 282 | 288 | request.setContent(content, contentTypeHeader); |
| 283 | 289 | } |
| ... | ... | @@ -289,56 +295,55 @@ public class SIPRequestHeaderProvider { |
| 289 | 295 | |
| 290 | 296 | // via |
| 291 | 297 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 292 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(localIp, sipConfig.getPort(), sipResponse.getTopmostViaHeader().getTransport(), SipUtils.getNewViaTag()); | |
| 298 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(localIp, sipConfig.getPort(), sipResponse.getTopmostViaHeader().getTransport(), SipUtils.getNewViaTag()); | |
| 293 | 299 | viaHeaders.add(viaHeader); |
| 294 | 300 | |
| 295 | 301 | //Forwards |
| 296 | - MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | |
| 302 | + MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); | |
| 297 | 303 | |
| 298 | 304 | //ceq |
| 299 | - CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(sipResponse.getCSeqHeader().getSeqNumber(), Request.ACK); | |
| 305 | + CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(sipResponse.getCSeqHeader().getSeqNumber(), Request.ACK); | |
| 300 | 306 | |
| 301 | - Request request = sipLayer.getSipFactory().createMessageFactory().createRequest(sipURI, Request.ACK, sipResponse.getCallIdHeader(), cSeqHeader, sipResponse.getFromHeader(), sipResponse.getToHeader(), viaHeaders, maxForwards); | |
| 307 | + Request request = SipFactory.getInstance().createMessageFactory().createRequest(sipURI, Request.ACK, sipResponse.getCallIdHeader(), cSeqHeader, sipResponse.getFromHeader(), sipResponse.getToHeader(), viaHeaders, maxForwards); | |
| 302 | 308 | |
| 303 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 309 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 304 | 310 | |
| 305 | - Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), localIp + ":"+sipConfig.getPort())); | |
| 306 | - request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress)); | |
| 311 | + Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), localIp + ":"+sipConfig.getPort())); | |
| 312 | + request.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress)); | |
| 307 | 313 | |
| 308 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 314 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 309 | 315 | |
| 310 | 316 | return request; |
| 311 | 317 | } |
| 312 | - | |
| 313 | 318 | public Request createBroadcastMessageRequest(Device device, String channelId, String content, String viaTag, String fromTag, String toTag, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException { |
| 314 | 319 | Request request = null; |
| 315 | 320 | // sipuri |
| 316 | - SipURI requestURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 321 | + SipURI requestURI = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 317 | 322 | // via |
| 318 | 323 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 319 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(sipConfig.getIp(), sipConfig.getPort(), device.getTransport(), viaTag); | |
| 324 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(sipConfig.getIp(), sipConfig.getPort(), device.getTransport(), viaTag); | |
| 320 | 325 | viaHeader.setRPort(); |
| 321 | 326 | viaHeaders.add(viaHeader); |
| 322 | 327 | // from |
| 323 | - SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain()); | |
| 324 | - Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | |
| 325 | - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, fromTag); | |
| 328 | + SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain()); | |
| 329 | + Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI); | |
| 330 | + FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, fromTag); | |
| 326 | 331 | // to |
| 327 | - SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 328 | - Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | |
| 329 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress, toTag); | |
| 332 | + SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | |
| 333 | + Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI); | |
| 334 | + ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress, toTag); | |
| 330 | 335 | |
| 331 | 336 | // Forwards |
| 332 | - MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | |
| 337 | + MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); | |
| 333 | 338 | // ceq |
| 334 | - CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.MESSAGE); | |
| 339 | + CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.MESSAGE); | |
| 335 | 340 | |
| 336 | - ContentTypeHeader contentTypeHeader = sipLayer.getSipFactory().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); | |
| 341 | + ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); | |
| 337 | 342 | |
| 338 | - request = sipLayer.getSipFactory().createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader, | |
| 343 | + request = SipFactory.getInstance().createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader, | |
| 339 | 344 | toHeader, viaHeaders, maxForwards, contentTypeHeader, content); |
| 340 | 345 | |
| 341 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 346 | + request.addHeader(SipUtils.createUserAgentHeader(gitUtil)); | |
| 342 | 347 | |
| 343 | 348 | return request; |
| 344 | 349 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; |
| 2 | 2 | |
| 3 | 3 | import com.alibaba.fastjson2.JSONObject; |
| 4 | +import com.genersoft.iot.vmp.common.InviteSessionType; | |
| 4 | 5 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 5 | 6 | import com.genersoft.iot.vmp.conf.SipConfig; |
| 6 | 7 | import com.genersoft.iot.vmp.conf.UserSetting; |
| ... | ... | @@ -36,6 +37,7 @@ import org.springframework.util.ObjectUtils; |
| 36 | 37 | import javax.sip.InvalidArgumentException; |
| 37 | 38 | import javax.sip.ResponseEvent; |
| 38 | 39 | import javax.sip.SipException; |
| 40 | +import javax.sip.SipFactory; | |
| 39 | 41 | import javax.sip.header.CallIdHeader; |
| 40 | 42 | import javax.sip.message.Request; |
| 41 | 43 | import java.text.ParseException; |
| ... | ... | @@ -358,7 +360,7 @@ public class SIPCommander implements ISIPCommander { |
| 358 | 360 | // 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值 |
| 359 | 361 | ResponseEvent responseEvent = (ResponseEvent) e.event; |
| 360 | 362 | SIPResponse response = (SIPResponse) responseEvent.getResponse(); |
| 361 | - streamSession.put(device.getDeviceId(), channelId, "play", stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.play); | |
| 363 | + streamSession.put(device.getDeviceId(), channelId, "play", stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.PLAY); | |
| 362 | 364 | okEvent.response(e); |
| 363 | 365 | }); |
| 364 | 366 | } |
| ... | ... | @@ -373,11 +375,11 @@ public class SIPCommander implements ISIPCommander { |
| 373 | 375 | */ |
| 374 | 376 | @Override |
| 375 | 377 | public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, |
| 376 | - String startTime, String endTime, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, | |
| 378 | + String startTime, String endTime, ZlmHttpHookSubscribe.Event hookEvent, | |
| 377 | 379 | SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { |
| 378 | 380 | |
| 379 | 381 | |
| 380 | - logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getSdpIp(), mediaServerItem.getIp(), ssrcInfo.getPort()); | |
| 382 | + logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getSdpIp(), ssrcInfo.getPort()); | |
| 381 | 383 | String sdpIp; |
| 382 | 384 | if (!ObjectUtils.isEmpty(device.getSdpIp())) { |
| 383 | 385 | sdpIp = device.getSdpIp(); |
| ... | ... | @@ -450,8 +452,7 @@ public class SIPCommander implements ISIPCommander { |
| 450 | 452 | // 添加订阅 |
| 451 | 453 | subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> { |
| 452 | 454 | if (hookEvent != null) { |
| 453 | - InviteStreamInfo inviteStreamInfo = new InviteStreamInfo(mediaServerItemInUse, json,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), "rtp", ssrcInfo.getStream()); | |
| 454 | - hookEvent.call(inviteStreamInfo); | |
| 455 | + hookEvent.response(mediaServerItemInUse, json); | |
| 455 | 456 | } |
| 456 | 457 | subscribe.removeSubscribe(hookSubscribe); |
| 457 | 458 | }); |
| ... | ... | @@ -460,12 +461,9 @@ public class SIPCommander implements ISIPCommander { |
| 460 | 461 | sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, event -> { |
| 461 | 462 | ResponseEvent responseEvent = (ResponseEvent) event.event; |
| 462 | 463 | SIPResponse response = (SIPResponse) responseEvent.getResponse(); |
| 463 | - streamSession.put(device.getDeviceId(), channelId,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.playback); | |
| 464 | + streamSession.put(device.getDeviceId(), channelId,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.PLAYBACK); | |
| 464 | 465 | okEvent.response(event); |
| 465 | 466 | }); |
| 466 | - if (inviteStreamCallback != null) { | |
| 467 | - inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), "rtp", ssrcInfo.getStream())); | |
| 468 | - } | |
| 469 | 467 | } |
| 470 | 468 | |
| 471 | 469 | /** |
| ... | ... | @@ -480,10 +478,10 @@ public class SIPCommander implements ISIPCommander { |
| 480 | 478 | @Override |
| 481 | 479 | public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, |
| 482 | 480 | String startTime, String endTime, int downloadSpeed, |
| 483 | - InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, | |
| 481 | + ZlmHttpHookSubscribe.Event hookEvent, | |
| 484 | 482 | SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException { |
| 485 | 483 | |
| 486 | - logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getSdpIp(), mediaServerItem.getIp(), ssrcInfo.getPort()); | |
| 484 | + logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getSdpIp(), ssrcInfo.getPort()); | |
| 487 | 485 | String sdpIp; |
| 488 | 486 | if (!ObjectUtils.isEmpty(device.getSdpIp())) { |
| 489 | 487 | sdpIp = device.getSdpIp(); |
| ... | ... | @@ -551,13 +549,13 @@ public class SIPCommander implements ISIPCommander { |
| 551 | 549 | |
| 552 | 550 | content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc |
| 553 | 551 | logger.debug("此时请求下载信令的ssrc===>{}",ssrcInfo.getSsrc()); |
| 554 | - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, null, mediaServerItem.getId()); | |
| 552 | + HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId()); | |
| 555 | 553 | // 添加订阅 |
| 556 | 554 | CallIdHeader newCallIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport()); |
| 557 | - String callId=newCallIdHeader.getCallId(); | |
| 555 | + String callId= newCallIdHeader.getCallId(); | |
| 558 | 556 | subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> { |
| 559 | 557 | logger.debug("sipc 添加订阅===callId {}",callId); |
| 560 | - hookEvent.call(new InviteStreamInfo(mediaServerItem, json,callId, "rtp", ssrcInfo.getStream())); | |
| 558 | + hookEvent.response(mediaServerItemInUse, json); | |
| 561 | 559 | subscribe.removeSubscribe(hookSubscribe); |
| 562 | 560 | hookSubscribe.getContent().put("regist", false); |
| 563 | 561 | hookSubscribe.getContent().put("schema", "rtsp"); |
| ... | ... | @@ -566,7 +564,7 @@ public class SIPCommander implements ISIPCommander { |
| 566 | 564 | (MediaServerItem mediaServerItemForEnd, JSONObject jsonForEnd) -> { |
| 567 | 565 | logger.info("[录像]下载结束, 发送BYE"); |
| 568 | 566 | try { |
| 569 | - streamByeCmd(device, channelId, ssrcInfo.getStream(),callId); | |
| 567 | + streamByeCmd(device, channelId, ssrcInfo.getStream(), callId); | |
| 570 | 568 | } catch (InvalidArgumentException | ParseException | SipException | |
| 571 | 569 | SsrcTransactionNotFoundException e) { |
| 572 | 570 | logger.error("[录像]下载结束, 发送BYE失败 {}", e.getMessage()); |
| ... | ... | @@ -575,9 +573,6 @@ public class SIPCommander implements ISIPCommander { |
| 575 | 573 | }); |
| 576 | 574 | |
| 577 | 575 | Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, SipUtils.getNewFromTag(), null,newCallIdHeader, ssrcInfo.getSsrc()); |
| 578 | - if (inviteStreamCallback != null) { | |
| 579 | - inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null,callId, "rtp", ssrcInfo.getStream())); | |
| 580 | - } | |
| 581 | 576 | |
| 582 | 577 | sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, event -> { |
| 583 | 578 | ResponseEvent responseEvent = (ResponseEvent) event.event; |
| ... | ... | @@ -588,9 +583,7 @@ public class SIPCommander implements ISIPCommander { |
| 588 | 583 | if (ssrcIndex >= 0) { |
| 589 | 584 | ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); |
| 590 | 585 | } |
| 591 | - logger.debug("接收到的下载响应ssrc====>{}",ssrcInfo.getSsrc()); | |
| 592 | - logger.debug("接收到的下载响应ssrc====>{}",ssrc); | |
| 593 | - streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrc, mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.download); | |
| 586 | + streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrc, mediaServerItem.getId(), response, InviteSessionType.DOWNLOAD); | |
| 594 | 587 | okEvent.response(event); |
| 595 | 588 | }); |
| 596 | 589 | } |
| ... | ... | @@ -654,7 +647,7 @@ public class SIPCommander implements ISIPCommander { |
| 654 | 647 | // 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值 |
| 655 | 648 | ResponseEvent responseEvent = (ResponseEvent) e.event; |
| 656 | 649 | SIPResponse response = (SIPResponse) responseEvent.getResponse(); |
| 657 | - streamSession.put(device.getDeviceId(), channelId, "talk", stream, sendRtpItem.getSsrc(), mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.talk); | |
| 650 | + streamSession.put(device.getDeviceId(), channelId, "talk", stream, sendRtpItem.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.TALK); | |
| 658 | 651 | okEvent.response(e); |
| 659 | 652 | }); |
| 660 | 653 | } |
| ... | ... | @@ -1247,7 +1240,7 @@ public class SIPCommander implements ISIPCommander { |
| 1247 | 1240 | CallIdHeader callIdHeader; |
| 1248 | 1241 | |
| 1249 | 1242 | if (requestOld != null) { |
| 1250 | - callIdHeader = sipLayer.getSipFactory().createHeaderFactory().createCallIdHeader(requestOld.getCallIdHeader().getCallId()); | |
| 1243 | + callIdHeader = SipFactory.getInstance().createHeaderFactory().createCallIdHeader(requestOld.getCallIdHeader().getCallId()); | |
| 1251 | 1244 | } else { |
| 1252 | 1245 | callIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()); |
| 1253 | 1246 | } |
| ... | ... | @@ -1322,7 +1315,7 @@ public class SIPCommander implements ISIPCommander { |
| 1322 | 1315 | CallIdHeader callIdHeader; |
| 1323 | 1316 | |
| 1324 | 1317 | if (requestOld != null) { |
| 1325 | - callIdHeader = sipLayer.getSipFactory().createHeaderFactory().createCallIdHeader(requestOld.getCallIdHeader().getCallId()); | |
| 1318 | + callIdHeader = SipFactory.getInstance().createHeaderFactory().createCallIdHeader(requestOld.getCallIdHeader().getCallId()); | |
| 1326 | 1319 | } else { |
| 1327 | 1320 | callIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()); |
| 1328 | 1321 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
| ... | ... | @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; |
| 2 | 2 | |
| 3 | 3 | import com.alibaba.fastjson2.JSON; |
| 4 | 4 | import com.alibaba.fastjson2.JSONObject; |
| 5 | +import com.genersoft.iot.vmp.common.InviteSessionType; | |
| 5 | 6 | import com.genersoft.iot.vmp.conf.DynamicTask; |
| 6 | 7 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 7 | 8 | import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; |
| ... | ... | @@ -39,6 +40,7 @@ import org.springframework.util.ObjectUtils; |
| 39 | 40 | import javax.sip.InvalidArgumentException; |
| 40 | 41 | import javax.sip.ResponseEvent; |
| 41 | 42 | import javax.sip.SipException; |
| 43 | +import javax.sip.SipFactory; | |
| 42 | 44 | import javax.sip.header.CallIdHeader; |
| 43 | 45 | import javax.sip.header.WWWAuthenticateHeader; |
| 44 | 46 | import javax.sip.message.Request; |
| ... | ... | @@ -518,7 +520,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 518 | 520 | private void sendNotify(ParentPlatform parentPlatform, String catalogXmlContent, |
| 519 | 521 | SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent ) |
| 520 | 522 | throws SipException, ParseException, InvalidArgumentException { |
| 521 | - MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipLayer.getSipFactory().createMessageFactory(); | |
| 523 | + MessageFactoryImpl messageFactory = (MessageFactoryImpl) SipFactory.getInstance().createMessageFactory(); | |
| 522 | 524 | String characterSet = parentPlatform.getCharacterSet(); |
| 523 | 525 | // 设置编码, 防止中文乱码 |
| 524 | 526 | messageFactory.setDefaultContentEncodingCharset(characterSet); |
| ... | ... | @@ -854,7 +856,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 854 | 856 | }), e -> { |
| 855 | 857 | ResponseEvent responseEvent = (ResponseEvent) e.event; |
| 856 | 858 | SIPResponse response = (SIPResponse) responseEvent.getResponse(); |
| 857 | - streamSession.put(platform.getServerGBId(), channelId, callIdHeader.getCallId(), stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.broadcast); | |
| 859 | + streamSession.put(platform.getServerGBId(), channelId, callIdHeader.getCallId(), stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.BROADCAST); | |
| 858 | 860 | okEvent.response(e); |
| 859 | 861 | }); |
| 860 | 862 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; |
| 2 | 2 | |
| 3 | -import com.genersoft.iot.vmp.common.StreamInfo; | |
| 3 | +import com.genersoft.iot.vmp.common.InviteInfo; | |
| 4 | +import com.genersoft.iot.vmp.common.InviteSessionType; | |
| 4 | 5 | import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; |
| 5 | 6 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 6 | 7 | import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; |
| 8 | +import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; | |
| 7 | 9 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 8 | 10 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| 9 | 11 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
| ... | ... | @@ -13,6 +15,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorP |
| 13 | 15 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 14 | 16 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 15 | 17 | import com.genersoft.iot.vmp.service.IDeviceService; |
| 18 | +import com.genersoft.iot.vmp.service.IInviteStreamService; | |
| 16 | 19 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 17 | 20 | import com.genersoft.iot.vmp.service.IPlayService; |
| 18 | 21 | import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; |
| ... | ... | @@ -29,6 +32,7 @@ import javax.sip.InvalidArgumentException; |
| 29 | 32 | import javax.sip.RequestEvent; |
| 30 | 33 | import javax.sip.SipException; |
| 31 | 34 | import javax.sip.address.SipURI; |
| 35 | +import javax.sip.header.CallIdHeader; | |
| 32 | 36 | import javax.sip.header.FromHeader; |
| 33 | 37 | import javax.sip.header.HeaderAddress; |
| 34 | 38 | import javax.sip.header.ToHeader; |
| ... | ... | @@ -57,6 +61,9 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In |
| 57 | 61 | private IRedisCatchStorage redisCatchStorage; |
| 58 | 62 | |
| 59 | 63 | @Autowired |
| 64 | + private IInviteStreamService inviteStreamService; | |
| 65 | + | |
| 66 | + @Autowired | |
| 60 | 67 | private IDeviceService deviceService; |
| 61 | 68 | |
| 62 | 69 | @Autowired |
| ... | ... | @@ -69,6 +76,9 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In |
| 69 | 76 | private ZLMRTPServerFactory zlmrtpServerFactory; |
| 70 | 77 | |
| 71 | 78 | @Autowired |
| 79 | + private SSRCFactory ssrcFactory; | |
| 80 | + | |
| 81 | + @Autowired | |
| 72 | 82 | private IMediaServerService mediaServerService; |
| 73 | 83 | |
| 74 | 84 | @Autowired |
| ... | ... | @@ -100,92 +110,89 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In |
| 100 | 110 | } catch (SipException | InvalidArgumentException | ParseException e) { |
| 101 | 111 | logger.error("[回复BYE信息失败],{}", e.getMessage()); |
| 102 | 112 | } |
| 103 | - | |
| 104 | - SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, null, request.getCallIdHeader().getCallId()); | |
| 105 | - | |
| 106 | - if (sendRtpItem != null){ | |
| 107 | - logger.info("[收到bye] {}/{}", sendRtpItem.getPlatformId(), sendRtpItem.getChannelId()); | |
| 108 | - String streamId = sendRtpItem.getStream(); | |
| 109 | - MediaServerItem mediaServerItem = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | |
| 110 | - if (mediaServerItem == null) { | |
| 111 | - return; | |
| 112 | - } | |
| 113 | - | |
| 114 | - Boolean ready = zlmrtpServerFactory.isStreamReady(mediaServerItem, sendRtpItem.getApp(), streamId); | |
| 115 | - if (!ready) { | |
| 116 | - logger.info("[收到bye] 发现流{}/{}已经结束,不需处理", sendRtpItem.getApp(), sendRtpItem.getStream()); | |
| 117 | - return; | |
| 118 | - } | |
| 119 | - Map<String, Object> param = new HashMap<>(); | |
| 120 | - param.put("vhost","__defaultVhost__"); | |
| 121 | - param.put("app",sendRtpItem.getApp()); | |
| 122 | - param.put("stream",streamId); | |
| 123 | - param.put("ssrc",sendRtpItem.getSsrc()); | |
| 124 | - logger.info("[收到bye] 停止推流:{}", streamId); | |
| 125 | - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | |
| 126 | - redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), request.getCallIdHeader().getCallId(), null); | |
| 127 | - zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); | |
| 128 | - | |
| 129 | - int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId); | |
| 130 | - if (totalReaderCount <= 0) { | |
| 131 | - logger.info("[收到bye] {} 无其它观看者,通知设备停止推流", streamId); | |
| 132 | - if (sendRtpItem.getPlayType().equals(InviteStreamType.PLAY)) { | |
| 133 | - Device device = deviceService.getDevice(sendRtpItem.getDeviceId()); | |
| 134 | - if (device == null) { | |
| 135 | - logger.info("[收到bye] {} 通知设备停止推流时未找到设备信息", streamId); | |
| 113 | + CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME); | |
| 114 | + String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); | |
| 115 | + String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); | |
| 116 | + SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId, null, callIdHeader.getCallId()); | |
| 117 | + logger.info("[收到bye] {}/{}", platformGbId, channelId); | |
| 118 | + if (sendRtpItem != null){ | |
| 119 | + String streamId = sendRtpItem.getStream(); | |
| 120 | + Map<String, Object> param = new HashMap<>(); | |
| 121 | + param.put("vhost","__defaultVhost__"); | |
| 122 | + param.put("app",sendRtpItem.getApp()); | |
| 123 | + param.put("stream",streamId); | |
| 124 | + param.put("ssrc",sendRtpItem.getSsrc()); | |
| 125 | + logger.info("[收到bye] 停止向上级推流:{}", streamId); | |
| 126 | + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | |
| 127 | + redisCatchStorage.deleteSendRTPServer(platformGbId, channelId, callIdHeader.getCallId(), null); | |
| 128 | + ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); | |
| 129 | + zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); | |
| 130 | + int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId); | |
| 131 | + if (totalReaderCount <= 0) { | |
| 132 | + logger.info("[收到bye] {} 无其它观看者,通知设备停止推流", streamId); | |
| 133 | + if (sendRtpItem.getPlayType().equals(InviteStreamType.PLAY)) { | |
| 134 | + Device device = deviceService.getDevice(sendRtpItem.getDeviceId()); | |
| 135 | + if (device == null) { | |
| 136 | + logger.info("[收到bye] {} 通知设备停止推流时未找到设备信息", streamId); | |
| 137 | + } | |
| 138 | + try { | |
| 139 | + logger.warn("[停止点播] {}/{}", sendRtpItem.getDeviceId(), channelId); | |
| 140 | + cmder.streamByeCmd(device, channelId, streamId, null); | |
| 141 | + } catch (InvalidArgumentException | ParseException | SipException | | |
| 142 | + SsrcTransactionNotFoundException e) { | |
| 143 | + logger.error("[收到bye] {} 无其它观看者,通知设备停止推流, 发送BYE失败 {}",streamId, e.getMessage()); | |
| 144 | + } | |
| 136 | 145 | } |
| 137 | - try { | |
| 138 | - logger.warn("[停止点播] {}/{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); | |
| 139 | - cmder.streamByeCmd(device, sendRtpItem.getChannelId(), streamId, null); | |
| 140 | - } catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) { | |
| 141 | - logger.error("[收到bye] {} 无其它观看者,通知设备停止推流, 发送BYE失败 {}",streamId, e.getMessage()); | |
| 146 | + if (sendRtpItem.getPlayType().equals(InviteStreamType.PUSH)) { | |
| 147 | + MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, | |
| 148 | + sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(), | |
| 149 | + sendRtpItem.getPlatformId(), null, null, sendRtpItem.getMediaServerId()); | |
| 150 | + redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel); | |
| 142 | 151 | } |
| 143 | 152 | } |
| 144 | - | |
| 145 | - if (sendRtpItem.getPlayType().equals(InviteStreamType.PUSH)) { | |
| 146 | - MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, | |
| 147 | - sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(), | |
| 148 | - sendRtpItem.getPlatformId(), null, null, sendRtpItem.getMediaServerId()); | |
| 149 | - redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel); | |
| 150 | - } | |
| 151 | 153 | } |
| 154 | + // 可能是设备主动停止 | |
| 155 | + Device device = storager.queryVideoDeviceByChannelId(platformGbId); | |
| 156 | + if (device != null) { | |
| 157 | + storager.stopPlay(device.getDeviceId(), channelId); | |
| 158 | + SsrcTransaction ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "play", null); | |
| 159 | + if (ssrcTransactionForPlay != null){ | |
| 160 | + if (ssrcTransactionForPlay.getCallId().equals(callIdHeader.getCallId())){ | |
| 161 | + // 释放ssrc | |
| 162 | + MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlay.getMediaServerId()); | |
| 163 | + if (mediaServerItem != null) { | |
| 164 | + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransactionForPlay.getSsrc()); | |
| 165 | + } | |
| 166 | + streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlay.getStream()); | |
| 167 | + } | |
| 168 | + InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId); | |
| 152 | 169 | |
| 153 | - playService.stopAudioBroadcast(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); | |
| 154 | - } | |
| 155 | - | |
| 156 | - String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); | |
| 157 | - String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); | |
| 158 | - | |
| 159 | - // 可能是设备主动停止 | |
| 160 | - Device device = storager.queryVideoDeviceByChannelId(platformGbId); | |
| 161 | - if (device != null) { | |
| 162 | - storager.stopPlay(device.getDeviceId(), channelId); | |
| 163 | - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId); | |
| 164 | - if (streamInfo != null) { | |
| 165 | - redisCatchStorage.stopPlay(streamInfo); | |
| 166 | - mediaServerService.closeRTPServer(streamInfo.getMediaServerId(), streamInfo.getStream()); | |
| 167 | - } | |
| 168 | - SsrcTransaction ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "play", null); | |
| 169 | - if (ssrcTransactionForPlay != null){ | |
| 170 | - if (ssrcTransactionForPlay.getCallId().equals(request.getCallIdHeader().getCallId())){ | |
| 170 | + if (inviteInfo != null) { | |
| 171 | + inviteStreamService.removeInviteInfo(inviteInfo); | |
| 172 | + if (inviteInfo.getStreamInfo() != null) { | |
| 173 | + mediaServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServerId(), inviteInfo.getStream()); | |
| 174 | + } | |
| 175 | + } | |
| 176 | + } | |
| 177 | + SsrcTransaction ssrcTransactionForPlayBack = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, callIdHeader.getCallId(), null); | |
| 178 | + if (ssrcTransactionForPlayBack != null) { | |
| 171 | 179 | // 释放ssrc |
| 172 | - MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlay.getMediaServerId()); | |
| 180 | + MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlayBack.getMediaServerId()); | |
| 173 | 181 | if (mediaServerItem != null) { |
| 174 | - mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransactionForPlay.getSsrc()); | |
| 182 | + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransactionForPlayBack.getSsrc()); | |
| 183 | + } | |
| 184 | + streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlayBack.getStream()); | |
| 185 | + InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAYBACK, device.getDeviceId(), channelId); | |
| 186 | + | |
| 187 | + if (inviteInfo != null) { | |
| 188 | + inviteStreamService.removeInviteInfo(inviteInfo); | |
| 189 | + if (inviteInfo.getStreamInfo() != null) { | |
| 190 | + mediaServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServerId(), inviteInfo.getStream()); | |
| 191 | + } | |
| 175 | 192 | } |
| 176 | - streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlay.getStream()); | |
| 177 | - } | |
| 178 | - } | |
| 179 | - SsrcTransaction ssrcTransactionForPlayBack = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, request.getCallIdHeader().getCallId(), null); | |
| 180 | - if (ssrcTransactionForPlayBack != null) { | |
| 181 | - // 释放ssrc | |
| 182 | - MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlayBack.getMediaServerId()); | |
| 183 | - if (mediaServerItem != null) { | |
| 184 | - mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransactionForPlayBack.getSsrc()); | |
| 185 | 193 | } |
| 186 | - streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlayBack.getStream()); | |
| 187 | 194 | } |
| 188 | - } | |
| 195 | + | |
| 189 | 196 | SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(null, null, request.getCallIdHeader().getCallId(), null); |
| 190 | 197 | if (ssrcTransaction != null) { |
| 191 | 198 | // 释放ssrc |
| ... | ... | @@ -203,7 +210,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In |
| 203 | 210 | // break; |
| 204 | 211 | // case download: |
| 205 | 212 | // break; |
| 206 | - case broadcast: | |
| 213 | + case BROADCAST: | |
| 207 | 214 | String channelId1 = ssrcTransaction.getChannelId(); |
| 208 | 215 | |
| 209 | 216 | Device deviceFromTransaction = storager.queryVideoDevice(ssrcTransaction.getDeviceId()); |
| ... | ... | @@ -255,7 +262,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In |
| 255 | 262 | List<SsrcTransaction> ssrcTransactions = streamSession.getSsrcTransactionForAll(null, channelId1, null, null); |
| 256 | 263 | if (ssrcTransactions.size() > 0) { |
| 257 | 264 | for (SsrcTransaction transaction : ssrcTransactions) { |
| 258 | - if (transaction.getType().equals(VideoStreamSessionManager.SessionType.broadcast)) { | |
| 265 | + if (transaction.getType().equals(InviteSessionType.BROADCAST)) { | |
| 259 | 266 | ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(transaction.getDeviceId()); |
| 260 | 267 | if (parentPlatform != null) { |
| 261 | 268 | try { | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; |
| 2 | 2 | |
| 3 | -import com.alibaba.fastjson2.JSONObject; | |
| 4 | 3 | import com.genersoft.iot.vmp.common.VideoManagerConstants; |
| 4 | +import com.genersoft.iot.vmp.common.StreamInfo; | |
| 5 | 5 | import com.genersoft.iot.vmp.conf.DynamicTask; |
| 6 | 6 | import com.genersoft.iot.vmp.conf.SipConfig; |
| 7 | 7 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 8 | 8 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 9 | -import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | |
| 10 | 9 | import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; |
| 11 | -import com.genersoft.iot.vmp.gb28181.session.SsrcConfig; | |
| 12 | 10 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 11 | +import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; | |
| 13 | 12 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| 14 | 13 | import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; |
| 15 | 14 | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| ... | ... | @@ -23,7 +22,12 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 23 | 22 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 24 | 23 | import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; |
| 25 | 24 | import com.genersoft.iot.vmp.media.zlm.dto.*; |
| 26 | -import com.genersoft.iot.vmp.service.*; | |
| 25 | +import com.genersoft.iot.vmp.service.IMediaServerService; | |
| 26 | +import com.genersoft.iot.vmp.service.IPlayService; | |
| 27 | +import com.genersoft.iot.vmp.service.IStreamProxyService; | |
| 28 | +import com.genersoft.iot.vmp.service.IStreamPushService; | |
| 29 | +import com.genersoft.iot.vmp.service.bean.InviteErrorCallback; | |
| 30 | +import com.genersoft.iot.vmp.service.bean.InviteErrorCode; | |
| 27 | 31 | import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; |
| 28 | 32 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| 29 | 33 | import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; |
| ... | ... | @@ -79,6 +83,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 79 | 83 | private IRedisCatchStorage redisCatchStorage; |
| 80 | 84 | |
| 81 | 85 | @Autowired |
| 86 | + private SSRCFactory ssrcFactory; | |
| 87 | + | |
| 88 | + @Autowired | |
| 82 | 89 | private DynamicTask dynamicTask; |
| 83 | 90 | |
| 84 | 91 | @Autowired |
| ... | ... | @@ -90,8 +97,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 90 | 97 | @Autowired |
| 91 | 98 | private SIPSender sipSender; |
| 92 | 99 | |
| 93 | - @Autowired | |
| 94 | - private AudioBroadcastManager audioBroadcastManager; | |
| 100 | + @Autowired | |
| 101 | + private AudioBroadcastManager audioBroadcastManager; | |
| 95 | 102 | |
| 96 | 103 | @Autowired |
| 97 | 104 | private ZLMRTPServerFactory zlmrtpServerFactory; |
| ... | ... | @@ -102,8 +109,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 102 | 109 | @Autowired |
| 103 | 110 | private ISIPCommander commander; |
| 104 | 111 | |
| 105 | - @Autowired | |
| 106 | - private ZLMRESTfulUtils zlmresTfulUtils; | |
| 112 | + @Autowired | |
| 113 | + private ZLMRESTfulUtils zlmresTfulUtils; | |
| 107 | 114 | |
| 108 | 115 | @Autowired |
| 109 | 116 | private ZlmHttpHookSubscribe zlmHttpHookSubscribe; |
| ... | ... | @@ -112,28 +119,24 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 112 | 119 | private SIPProcessorObserver sipProcessorObserver; |
| 113 | 120 | |
| 114 | 121 | @Autowired |
| 115 | - private VideoStreamSessionManager sessionManager; | |
| 116 | - | |
| 117 | - @Autowired | |
| 118 | 122 | private UserSetting userSetting; |
| 119 | 123 | |
| 120 | 124 | @Autowired |
| 121 | 125 | private ZLMMediaListManager mediaListManager; |
| 122 | 126 | |
| 123 | - @Autowired | |
| 124 | - private DeferredResultHolder resultHolder; | |
| 127 | + @Autowired | |
| 128 | + private DeferredResultHolder resultHolder; | |
| 125 | 129 | |
| 126 | - @Autowired | |
| 127 | - private ZlmHttpHookSubscribe subscribe; | |
| 130 | + @Autowired | |
| 131 | + private ZlmHttpHookSubscribe subscribe; | |
| 128 | 132 | |
| 129 | - @Autowired | |
| 130 | - private SipConfig config; | |
| 133 | + @Autowired | |
| 134 | + private SipConfig config; | |
| 131 | 135 | |
| 132 | 136 | @Autowired |
| 133 | 137 | private VideoStreamSessionManager streamSession; |
| 134 | 138 | |
| 135 | 139 | |
| 136 | - | |
| 137 | 140 | @Autowired |
| 138 | 141 | private RedisGbPlayMsgListener redisGbPlayMsgListener; |
| 139 | 142 | |
| ... | ... | @@ -153,7 +156,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 153 | 156 | public void process(RequestEvent evt) { |
| 154 | 157 | // Invite Request消息实现,此消息一般为级联消息,上级给下级发送请求视频指令 |
| 155 | 158 | try { |
| 156 | - SIPRequest request = (SIPRequest)evt.getRequest(); | |
| 159 | + SIPRequest request = (SIPRequest) evt.getRequest(); | |
| 157 | 160 | String channelId = SipUtils.getChannelIdFromRequest(request); |
| 158 | 161 | String requesterId = SipUtils.getUserIdFromFromHeader(request); |
| 159 | 162 | CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME); |
| ... | ... | @@ -167,27 +170,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 167 | 170 | } |
| 168 | 171 | return; |
| 169 | 172 | } |
| 170 | - String ssrc = null; | |
| 171 | - SessionDescription sdp = null; | |
| 172 | - String ssrcDefault = "0000000000"; | |
| 173 | - if (channelId == null) { | |
| 174 | - // 解析sdp消息, 使用jainsip 自带的sdp解析方式 | |
| 175 | - String contentString = new String(request.getRawContent()); | |
| 176 | - | |
| 177 | - // jainSip不支持y=字段, 移除以解析。 | |
| 178 | - int ssrcIndex = contentString.indexOf("y="); | |
| 179 | - | |
| 180 | - if (ssrcIndex >= 0) { | |
| 181 | - //ssrc规定长度为10个字节,不取余下长度以避免后续还有“f=”字段 | |
| 182 | - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); | |
| 183 | - String substring = contentString.substring(0, contentString.indexOf("y=")); | |
| 184 | - sdp = SdpFactory.getInstance().createSessionDescription(substring); | |
| 185 | - } else { | |
| 186 | - ssrc = ssrcDefault; | |
| 187 | - sdp = SdpFactory.getInstance().createSessionDescription(contentString); | |
| 188 | - } | |
| 189 | - channelId = sdp.getOrigin().getUsername(); | |
| 190 | - } | |
| 191 | 173 | |
| 192 | 174 | |
| 193 | 175 | // 查询请求是否来自上级平台\设备 |
| ... | ... | @@ -249,7 +231,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 249 | 231 | } |
| 250 | 232 | return; |
| 251 | 233 | } |
| 252 | - }else if("proxy".equals(gbStream.getStreamType())){ | |
| 234 | + } else if ("proxy".equals(gbStream.getStreamType())) { | |
| 253 | 235 | proxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(gbStream.getApp(), gbStream.getStream()); |
| 254 | 236 | if (proxyByAppAndStream == null) { |
| 255 | 237 | logger.info("[ app={}, stream={} ]找不到zlm {},返回410", gbStream.getApp(), gbStream.getStream(), mediaServerId); |
| ... | ... | @@ -285,23 +267,21 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 285 | 267 | } |
| 286 | 268 | return; |
| 287 | 269 | } |
| 288 | - if (sdp == null || ssrc == null) { | |
| 289 | - // 解析sdp消息, 使用jainsip 自带的sdp解析方式 | |
| 290 | - String contentString = new String(request.getRawContent()); | |
| 291 | - | |
| 292 | - // jainSip不支持y=字段, 移除以解析。 | |
| 293 | - int ssrcIndex = contentString.indexOf("y="); | |
| 294 | - if (ssrcIndex >= 0) { | |
| 295 | - //ssrc规定长度为10个字节,不取余下长度以避免后续还有“f=”字段 | |
| 296 | - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); | |
| 297 | - String substring = contentString.substring(0, contentString.indexOf("y=")); | |
| 298 | - sdp = SdpFactory.getInstance().createSessionDescription(substring); | |
| 299 | - } else { | |
| 300 | - ssrc = ssrcDefault; | |
| 301 | - sdp = SdpFactory.getInstance().createSessionDescription(contentString); | |
| 302 | - } | |
| 303 | - } | |
| 270 | + // 解析sdp消息, 使用jainsip 自带的sdp解析方式 | |
| 271 | + String contentString = new String(request.getRawContent()); | |
| 304 | 272 | |
| 273 | + // jainSip不支持y=字段, 移除以解析。 | |
| 274 | + // 检查是否有y字段 | |
| 275 | + int ssrcIndex = contentString.indexOf("y="); | |
| 276 | + | |
| 277 | + SessionDescription sdp; | |
| 278 | + if (ssrcIndex >= 0) { | |
| 279 | + //ssrc规定长度为10个字节,不取余下长度以避免后续还有“f=”字段 | |
| 280 | + String substring = contentString.substring(0, ssrcIndex); | |
| 281 | + sdp = SdpFactory.getInstance().createSessionDescription(substring); | |
| 282 | + } else { | |
| 283 | + sdp = SdpFactory.getInstance().createSessionDescription(contentString); | |
| 284 | + } | |
| 305 | 285 | String sessionName = sdp.getSessionName().getValue(); |
| 306 | 286 | |
| 307 | 287 | Long startTime = null; |
| ... | ... | @@ -363,7 +343,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 363 | 343 | String username = sdp.getOrigin().getUsername(); |
| 364 | 344 | String addressStr = sdp.getConnection().getAddress(); |
| 365 | 345 | |
| 366 | - logger.info("[上级点播]用户:{}, 通道:{}, 地址:{}:{}, ssrc:{}", username, channelId, addressStr, port, ssrc); | |
| 346 | + | |
| 367 | 347 | Device device = null; |
| 368 | 348 | // 通过 channel 和 gbStream 是否为null 值判断来源是直播流合适国标 |
| 369 | 349 | if (channel != null) { |
| ... | ... | @@ -387,6 +367,25 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 387 | 367 | } |
| 388 | 368 | return; |
| 389 | 369 | } |
| 370 | + | |
| 371 | + String ssrc; | |
| 372 | + if (userSetting.getUseCustomSsrcForParentInvite() || ssrcIndex < 0) { | |
| 373 | + // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 | |
| 374 | + ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); | |
| 375 | + } else { | |
| 376 | + ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); | |
| 377 | + } | |
| 378 | + String streamTypeStr = null; | |
| 379 | + if (mediaTransmissionTCP) { | |
| 380 | + if (tcpActive) { | |
| 381 | + streamTypeStr = "TCP-ACTIVE"; | |
| 382 | + } else { | |
| 383 | + streamTypeStr = "TCP-PASSIVE"; | |
| 384 | + } | |
| 385 | + } else { | |
| 386 | + streamTypeStr = "UDP"; | |
| 387 | + } | |
| 388 | + logger.info("[上级Invite] {}, 平台:{}, 通道:{}, 收流地址:{}:{},收流方式:{}, ssrc:{}", sessionName, username, channelId, addressStr, port, streamTypeStr, ssrc); | |
| 390 | 389 | SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, |
| 391 | 390 | device.getDeviceId(), channelId, mediaTransmissionTCP, platform.isRtcp()); |
| 392 | 391 | |
| ... | ... | @@ -407,11 +406,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 407 | 406 | |
| 408 | 407 | Long finalStartTime = startTime; |
| 409 | 408 | Long finalStopTime = stopTime; |
| 410 | - String finalChannelId = channelId; | |
| 411 | - ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON) -> { | |
| 412 | - String app = responseJSON.getString("app"); | |
| 413 | - String stream = responseJSON.getString("stream"); | |
| 414 | - logger.info("[上级点播]下级已经开始推流。 回复200OK(SDP), {}/{}", app, stream); | |
| 409 | + InviteErrorCallback<Object> hookEvent = (code, msg, data) -> { | |
| 410 | + StreamInfo streamInfo = (StreamInfo) data; | |
| 411 | + MediaServerItem mediaServerItemInUSe = mediaServerService.getOne(streamInfo.getMediaServerId()); | |
| 412 | + logger.info("[上级Invite]下级已经开始推流。 回复200OK(SDP), {}/{}", streamInfo.getApp(), streamInfo.getStream()); | |
| 415 | 413 | // * 0 等待设备推流上来 |
| 416 | 414 | // * 1 下级已经推流,等待上级平台回复ack |
| 417 | 415 | // * 2 推流中 |
| ... | ... | @@ -420,7 +418,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 420 | 418 | |
| 421 | 419 | StringBuffer content = new StringBuffer(200); |
| 422 | 420 | content.append("v=0\r\n"); |
| 423 | - content.append("o=" + finalChannelId + " 0 0 IN IP4 " + mediaServerItemInUSe.getSdpIp() + "\r\n"); | |
| 421 | + content.append("o=" + channelId + " 0 0 IN IP4 " + mediaServerItemInUSe.getSdpIp() + "\r\n"); | |
| 424 | 422 | content.append("s=" + sessionName + "\r\n"); |
| 425 | 423 | content.append("c=IN IP4 " + mediaServerItemInUSe.getSdpIp() + "\r\n"); |
| 426 | 424 | if ("Playback".equalsIgnoreCase(sessionName)) { |
| ... | ... | @@ -462,111 +460,118 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 462 | 460 | logger.error("[命令发送失败] 国标级联 回复SdpAck", e); |
| 463 | 461 | } |
| 464 | 462 | }; |
| 465 | - SipSubscribe.Event errorEvent = ((event) -> { | |
| 463 | + InviteErrorCallback<Object> errorEvent = ((statusCode, msg, data) -> { | |
| 466 | 464 | // 未知错误。直接转发设备点播的错误 |
| 467 | 465 | try { |
| 468 | - Response response = getMessageFactory().createResponse(event.statusCode, evt.getRequest()); | |
| 469 | - sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response); | |
| 470 | - } catch (ParseException | SipException e) { | |
| 466 | + if (statusCode > 0) { | |
| 467 | + Response response = getMessageFactory().createResponse(statusCode, evt.getRequest()); | |
| 468 | + sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response); | |
| 469 | + } | |
| 470 | + } catch (ParseException | SipException e) { | |
| 471 | 471 | logger.error("未处理的异常 ", e); |
| 472 | 472 | } |
| 473 | 473 | }); |
| 474 | 474 | sendRtpItem.setApp("rtp"); |
| 475 | 475 | if ("Playback".equalsIgnoreCase(sessionName)) { |
| 476 | 476 | sendRtpItem.setPlayType(InviteStreamType.PLAYBACK); |
| 477 | - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, device.isSsrcCheck(), true); | |
| 477 | + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, null, device.isSsrcCheck(), true, 0, false, false, device.getStreamModeForParam()); | |
| 478 | 478 | sendRtpItem.setStream(ssrcInfo.getStream()); |
| 479 | 479 | // 写入redis, 超时时回复 |
| 480 | 480 | redisCatchStorage.updateSendRTPSever(sendRtpItem); |
| 481 | 481 | playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.formatter.format(start), |
| 482 | - DateUtil.formatter.format(end), null, result -> { | |
| 483 | - if (result.getCode() != 0) { | |
| 484 | - logger.warn("录像回放失败"); | |
| 485 | - if (result.getEvent() != null) { | |
| 486 | - errorEvent.response(result.getEvent()); | |
| 487 | - } | |
| 488 | - redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), finalChannelId, callIdHeader.getCallId(), null); | |
| 489 | - try { | |
| 490 | - responseAck(request, Response.REQUEST_TIMEOUT); | |
| 491 | - } catch (SipException | InvalidArgumentException | ParseException e) { | |
| 492 | - logger.error("[命令发送失败] 国标级联 录像回放 发送REQUEST_TIMEOUT: {}", e.getMessage()); | |
| 493 | - } | |
| 482 | + DateUtil.formatter.format(end), | |
| 483 | + (code, msg, data) -> { | |
| 484 | + if (code == InviteErrorCode.SUCCESS.getCode()) { | |
| 485 | + hookEvent.run(code, msg, data); | |
| 486 | + } else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()) { | |
| 487 | + logger.info("[录像回放]超时, 用户:{}, 通道:{}", username, channelId); | |
| 488 | + redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); | |
| 489 | + errorEvent.run(code, msg, data); | |
| 490 | + } else { | |
| 491 | + errorEvent.run(code, msg, data); | |
| 492 | + } | |
| 493 | + }); | |
| 494 | + } else if ("Download".equalsIgnoreCase(sessionName)) { | |
| 495 | + // 获取指定的下载速度 | |
| 496 | + Vector sdpMediaDescriptions = sdp.getMediaDescriptions(true); | |
| 497 | + MediaDescription mediaDescription = null; | |
| 498 | + String downloadSpeed = "1"; | |
| 499 | + if (sdpMediaDescriptions.size() > 0) { | |
| 500 | + mediaDescription = (MediaDescription) sdpMediaDescriptions.get(0); | |
| 501 | + } | |
| 502 | + if (mediaDescription != null) { | |
| 503 | + downloadSpeed = mediaDescription.getAttribute("downloadspeed"); | |
| 504 | + } | |
| 505 | + | |
| 506 | + sendRtpItem.setPlayType(InviteStreamType.DOWNLOAD); | |
| 507 | + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, null, device.isSsrcCheck(), true, 0, false, false, device.getStreamModeForParam()); | |
| 508 | + sendRtpItem.setStream(ssrcInfo.getStream()); | |
| 509 | + // 写入redis, 超时时回复 | |
| 510 | + redisCatchStorage.updateSendRTPSever(sendRtpItem); | |
| 511 | + playService.download(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.formatter.format(start), | |
| 512 | + DateUtil.formatter.format(end), Integer.parseInt(downloadSpeed), | |
| 513 | + (code, msg, data) -> { | |
| 514 | + if (code == InviteErrorCode.SUCCESS.getCode()) { | |
| 515 | + hookEvent.run(code, msg, data); | |
| 516 | + } else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()) { | |
| 517 | + logger.info("[录像下载]超时, 用户:{}, 通道:{}", username, channelId); | |
| 518 | + redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); | |
| 519 | + errorEvent.run(code, msg, data); | |
| 494 | 520 | } else { |
| 495 | - if (result.getMediaServerItem() != null) { | |
| 496 | - hookEvent.response(result.getMediaServerItem(), result.getResponse()); | |
| 497 | - } | |
| 521 | + errorEvent.run(code, msg, data); | |
| 498 | 522 | } |
| 499 | 523 | }); |
| 500 | 524 | } else { |
| 501 | 525 | sendRtpItem.setPlayType(InviteStreamType.PLAY); |
| 502 | - SsrcTransaction playTransaction = sessionManager.getSsrcTransaction(device.getDeviceId(), channelId, "play", null); | |
| 503 | - if (playTransaction != null) { | |
| 504 | - Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, "rtp", playTransaction.getStream()); | |
| 505 | - if (!streamReady) { | |
| 506 | - boolean hasRtpServer = mediaServerService.checkRtpServer(mediaServerItem, "rtp", playTransaction.getStream()); | |
| 507 | - if (hasRtpServer) { | |
| 508 | - logger.info("[上级点播]已经开启rtpServer但是尚未收到流,开启监听流的到来"); | |
| 509 | - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", playTransaction.getStream(), true, "rtsp", mediaServerItem.getId()); | |
| 510 | - zlmHttpHookSubscribe.addSubscribe(hookSubscribe, hookEvent); | |
| 511 | - }else { | |
| 512 | - playTransaction = null; | |
| 513 | - } | |
| 514 | - } | |
| 515 | - } | |
| 516 | - if (playTransaction == null) { | |
| 517 | - String streamId = null; | |
| 518 | - if (mediaServerItem.isRtpEnable()) { | |
| 519 | - streamId = String.format("%s_%s", device.getDeviceId(), channelId); | |
| 520 | - } | |
| 521 | - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false); | |
| 522 | - logger.info(JSONObject.toJSONString(ssrcInfo)); | |
| 523 | - sendRtpItem.setStream(ssrcInfo.getStream()); | |
| 524 | - sendRtpItem.setSsrc(ssrc.equals(ssrcDefault) ? ssrcInfo.getSsrc() : ssrc); | |
| 525 | - | |
| 526 | - // 写入redis, 超时时回复 | |
| 527 | - redisCatchStorage.updateSendRTPSever(sendRtpItem); | |
| 528 | - playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg) -> { | |
| 529 | - logger.info("[上级点播]超时, 用户:{}, 通道:{}", username, finalChannelId); | |
| 530 | - redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), finalChannelId, callIdHeader.getCallId(), null); | |
| 531 | - }); | |
| 526 | + String streamId = null; | |
| 527 | + if (mediaServerItem.isRtpEnable()) { | |
| 528 | + streamId = String.format("%s_%s", device.getDeviceId(), channelId); | |
| 532 | 529 | } else { |
| 533 | - sendRtpItem.setStream(playTransaction.getStream()); | |
| 534 | - // 写入redis, 超时时回复 | |
| 535 | - redisCatchStorage.updateSendRTPSever(sendRtpItem); | |
| 536 | - JSONObject jsonObject = new JSONObject(); | |
| 537 | - jsonObject.put("app", sendRtpItem.getApp()); | |
| 538 | - jsonObject.put("stream", sendRtpItem.getStream()); | |
| 539 | - hookEvent.response(mediaServerItem, jsonObject); | |
| 530 | + streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); | |
| 540 | 531 | } |
| 532 | + sendRtpItem.setStream(streamId); | |
| 533 | + redisCatchStorage.updateSendRTPSever(sendRtpItem); | |
| 534 | + playService.play(mediaServerItem, device.getDeviceId(), channelId, ((code, msg, data) -> { | |
| 535 | + if (code == InviteErrorCode.SUCCESS.getCode()) { | |
| 536 | + hookEvent.run(code, msg, data); | |
| 537 | + } else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()) { | |
| 538 | + logger.info("[上级点播]超时, 用户:{}, 通道:{}", username, channelId); | |
| 539 | + redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); | |
| 540 | + errorEvent.run(code, msg, data); | |
| 541 | + } else { | |
| 542 | + errorEvent.run(code, msg, data); | |
| 543 | + } | |
| 544 | + })); | |
| 545 | + | |
| 541 | 546 | } |
| 542 | 547 | } else if (gbStream != null) { |
| 543 | - if(ssrc.equals(ssrcDefault)) | |
| 544 | - { | |
| 545 | - SsrcConfig ssrcConfig = mediaServerItem.getSsrcConfig(); | |
| 546 | - if(ssrcConfig != null) | |
| 547 | - { | |
| 548 | - ssrc = ssrcConfig.getPlaySsrc(); | |
| 549 | - ssrcConfig.releaseSsrc(ssrc); | |
| 550 | - } | |
| 548 | + | |
| 549 | + String ssrc; | |
| 550 | + if (userSetting.getUseCustomSsrcForParentInvite() || ssrcIndex < 0) { | |
| 551 | + // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 | |
| 552 | + ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); | |
| 553 | + } else { | |
| 554 | + ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); | |
| 551 | 555 | } |
| 552 | - if("push".equals(gbStream.getStreamType())) { | |
| 556 | + | |
| 557 | + if ("push".equals(gbStream.getStreamType())) { | |
| 553 | 558 | if (streamPushItem != null && streamPushItem.isPushIng()) { |
| 554 | 559 | // 推流状态 |
| 555 | 560 | pushStream(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, |
| 556 | 561 | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| 557 | 562 | } else { |
| 558 | 563 | // 未推流 拉起 |
| 559 | - notifyStreamOnline(evt, request,gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, | |
| 564 | + notifyStreamOnline(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, | |
| 560 | 565 | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| 561 | 566 | } |
| 562 | - }else if ("proxy".equals(gbStream.getStreamType())){ | |
| 567 | + } else if ("proxy".equals(gbStream.getStreamType())) { | |
| 563 | 568 | if (null != proxyByAppAndStream) { |
| 564 | - if(proxyByAppAndStream.isStatus()){ | |
| 565 | - pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive, | |
| 569 | + if (proxyByAppAndStream.isStatus()) { | |
| 570 | + pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive, | |
| 566 | 571 | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| 567 | - }else{ | |
| 572 | + } else { | |
| 568 | 573 | //开启代理拉流 |
| 569 | - notifyStreamOnline(evt, request,gbStream, null, platform, callIdHeader, mediaServerItem, port, tcpActive, | |
| 574 | + notifyStreamOnline(evt, request, gbStream, null, platform, callIdHeader, mediaServerItem, port, tcpActive, | |
| 570 | 575 | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| 571 | 576 | } |
| 572 | 577 | } |
| ... | ... | @@ -586,42 +591,43 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 586 | 591 | * 安排推流 |
| 587 | 592 | */ |
| 588 | 593 | private void pushProxyStream(RequestEvent evt, SIPRequest request, GbStream gbStream, ParentPlatform platform, |
| 589 | - CallIdHeader callIdHeader, MediaServerItem mediaServerItem, | |
| 590 | - int port, Boolean tcpActive, boolean mediaTransmissionTCP, | |
| 591 | - String channelId, String addressStr, String ssrc, String requesterId) { | |
| 592 | - Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream()); | |
| 593 | - if (streamReady) { | |
| 594 | - // 自平台内容 | |
| 595 | - SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, | |
| 596 | - gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp()); | |
| 597 | - | |
| 598 | - if (sendRtpItem == null) { | |
| 599 | - logger.warn("服务器端口资源不足"); | |
| 600 | - try { | |
| 601 | - responseAck(request, Response.BUSY_HERE); | |
| 602 | - } catch (SipException | InvalidArgumentException | ParseException e) { | |
| 603 | - logger.error("[命令发送失败] invite 服务器端口资源不足: {}", e.getMessage()); | |
| 604 | - } | |
| 605 | - return; | |
| 606 | - } | |
| 607 | - if (tcpActive != null) { | |
| 608 | - sendRtpItem.setTcpActive(tcpActive); | |
| 609 | - } | |
| 610 | - sendRtpItem.setPlayType(InviteStreamType.PUSH); | |
| 611 | - // 写入redis, 超时时回复 | |
| 612 | - sendRtpItem.setStatus(1); | |
| 613 | - sendRtpItem.setCallId(callIdHeader.getCallId()); | |
| 614 | - sendRtpItem.setFromTag(request.getFromTag()); | |
| 615 | - | |
| 616 | - SIPResponse response = sendStreamAck(mediaServerItem, request, sendRtpItem, platform, evt); | |
| 617 | - if (response != null) { | |
| 618 | - sendRtpItem.setToTag(response.getToTag()); | |
| 594 | + CallIdHeader callIdHeader, MediaServerItem mediaServerItem, | |
| 595 | + int port, Boolean tcpActive, boolean mediaTransmissionTCP, | |
| 596 | + String channelId, String addressStr, String ssrc, String requesterId) { | |
| 597 | + Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream()); | |
| 598 | + if (streamReady != null && streamReady) { | |
| 599 | + // 自平台内容 | |
| 600 | + SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, | |
| 601 | + gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp()); | |
| 602 | + | |
| 603 | + if (sendRtpItem == null) { | |
| 604 | + logger.warn("服务器端口资源不足"); | |
| 605 | + try { | |
| 606 | + responseAck(request, Response.BUSY_HERE); | |
| 607 | + } catch (SipException | InvalidArgumentException | ParseException e) { | |
| 608 | + logger.error("[命令发送失败] invite 服务器端口资源不足: {}", e.getMessage()); | |
| 619 | 609 | } |
| 620 | - redisCatchStorage.updateSendRTPSever(sendRtpItem); | |
| 610 | + return; | |
| 611 | + } | |
| 612 | + if (tcpActive != null) { | |
| 613 | + sendRtpItem.setTcpActive(tcpActive); | |
| 614 | + } | |
| 615 | + sendRtpItem.setPlayType(InviteStreamType.PUSH); | |
| 616 | + // 写入redis, 超时时回复 | |
| 617 | + sendRtpItem.setStatus(1); | |
| 618 | + sendRtpItem.setCallId(callIdHeader.getCallId()); | |
| 619 | + sendRtpItem.setFromTag(request.getFromTag()); | |
| 620 | + | |
| 621 | + SIPResponse response = sendStreamAck(mediaServerItem, request, sendRtpItem, platform, evt); | |
| 622 | + if (response != null) { | |
| 623 | + sendRtpItem.setToTag(response.getToTag()); | |
| 624 | + } | |
| 625 | + redisCatchStorage.updateSendRTPSever(sendRtpItem); | |
| 621 | 626 | |
| 622 | 627 | } |
| 623 | 628 | |
| 624 | 629 | } |
| 630 | + | |
| 625 | 631 | private void pushStream(RequestEvent evt, SIPRequest request, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform, |
| 626 | 632 | CallIdHeader callIdHeader, MediaServerItem mediaServerItem, |
| 627 | 633 | int port, Boolean tcpActive, boolean mediaTransmissionTCP, |
| ... | ... | @@ -629,7 +635,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 629 | 635 | // 推流 |
| 630 | 636 | if (streamPushItem.isSelf()) { |
| 631 | 637 | Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream()); |
| 632 | - if (streamReady) { | |
| 638 | + if (streamReady != null && streamReady) { | |
| 633 | 639 | // 自平台内容 |
| 634 | 640 | SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, |
| 635 | 641 | gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp()); |
| ... | ... | @@ -661,7 +667,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 661 | 667 | |
| 662 | 668 | } else { |
| 663 | 669 | // 不在线 拉起 |
| 664 | - notifyStreamOnline(evt, request,gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, | |
| 670 | + notifyStreamOnline(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, | |
| 665 | 671 | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| 666 | 672 | } |
| 667 | 673 | |
| ... | ... | @@ -671,6 +677,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 671 | 677 | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| 672 | 678 | } |
| 673 | 679 | } |
| 680 | + | |
| 674 | 681 | /** |
| 675 | 682 | * 通知流上线 |
| 676 | 683 | */ |
| ... | ... | @@ -688,7 +695,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 688 | 695 | String stream = responseJSON.getString("stream"); |
| 689 | 696 | logger.info("[上级点播]拉流代理已经就绪, {}/{}", app, stream); |
| 690 | 697 | dynamicTask.stop(callIdHeader.getCallId()); |
| 691 | - pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive, | |
| 698 | + pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive, | |
| 692 | 699 | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| 693 | 700 | }); |
| 694 | 701 | dynamicTask.startDelay(callIdHeader.getCallId(), () -> { |
| ... | ... | @@ -707,7 +714,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 707 | 714 | } |
| 708 | 715 | |
| 709 | 716 | |
| 710 | - | |
| 711 | 717 | } else if ("push".equals(gbStream.getStreamType())) { |
| 712 | 718 | if (!platform.isStartOfflinePush()) { |
| 713 | 719 | // 平台设置中关闭了拉起离线的推流则直接回复 |
| ... | ... | @@ -811,7 +817,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 811 | 817 | // 发送redis消息 |
| 812 | 818 | redisGbPlayMsgListener.sendMsg(streamPushItem.getServerId(), streamPushItem.getMediaServerId(), |
| 813 | 819 | streamPushItem.getApp(), streamPushItem.getStream(), addressStr, port, ssrc, requesterId, |
| 814 | - channelId, mediaTransmissionTCP, platform.isRtcp(),null, responseSendItemMsg -> { | |
| 820 | + channelId, mediaTransmissionTCP, platform.isRtcp(), null, responseSendItemMsg -> { | |
| 815 | 821 | SendRtpItem sendRtpItem = responseSendItemMsg.getSendRtpItem(); |
| 816 | 822 | if (sendRtpItem == null || responseSendItemMsg.getMediaServerItem() == null) { |
| 817 | 823 | logger.warn("服务器端口资源不足"); |
| ... | ... | @@ -836,7 +842,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 836 | 842 | sendRtpItem.setCallId(callIdHeader.getCallId()); |
| 837 | 843 | |
| 838 | 844 | sendRtpItem.setFromTag(request.getFromTag()); |
| 839 | - SIPResponse response = sendStreamAck(responseSendItemMsg.getMediaServerItem(), request,sendRtpItem, platform, evt); | |
| 845 | + SIPResponse response = sendStreamAck(responseSendItemMsg.getMediaServerItem(), request, sendRtpItem, platform, evt); | |
| 840 | 846 | if (response != null) { |
| 841 | 847 | sendRtpItem.setToTag(response.getToTag()); |
| 842 | 848 | } |
| ... | ... | @@ -877,8 +883,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 877 | 883 | content.append("t=0 0\r\n"); |
| 878 | 884 | // 非严格模式端口不统一, 增加兼容性,修改为一个不为0的端口 |
| 879 | 885 | int localPort = sendRtpItem.getLocalPort(); |
| 880 | - if(localPort == 0) | |
| 881 | - { | |
| 886 | + if (localPort == 0) { | |
| 882 | 887 | localPort = new Random().nextInt(65535) + 1; |
| 883 | 888 | } |
| 884 | 889 | content.append("m=video " + localPort + " RTP/AVP 96\r\n"); |
| ... | ... | @@ -953,7 +958,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 953 | 958 | } |
| 954 | 959 | if (device != null) { |
| 955 | 960 | logger.info("收到设备" + requesterId + "的语音广播Invite请求"); |
| 956 | - String key = VideoManagerConstants.BROADCAST_WAITE_INVITE + device.getDeviceId() + broadcastCatch.getChannelId(); | |
| 961 | + String key = VideoManagerConstants.BROADCAST_WAITE_INVITE + device.getDeviceId() + broadcastCatch.getChannelId(); | |
| 957 | 962 | dynamicTask.stop(key); |
| 958 | 963 | try { |
| 959 | 964 | responseAck(request, Response.TRYING); |
| ... | ... | @@ -986,7 +991,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 986 | 991 | boolean mediaTransmissionTCP = false; |
| 987 | 992 | Boolean tcpActive = null; |
| 988 | 993 | for (int i = 0; i < mediaDescriptions.size(); i++) { |
| 989 | - MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i); | |
| 994 | + MediaDescription mediaDescription = (MediaDescription) mediaDescriptions.get(i); | |
| 990 | 995 | Media media = mediaDescription.getMedia(); |
| 991 | 996 | |
| 992 | 997 | Vector mediaFormats = media.getMediaFormats(false); |
| ... | ... | @@ -1022,7 +1027,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 1022 | 1027 | } |
| 1023 | 1028 | String addressStr = sdp.getOrigin().getAddress(); |
| 1024 | 1029 | logger.info("设备{}请求语音流,地址:{}:{},ssrc:{}, {}", requesterId, addressStr, port, ssrc, |
| 1025 | - mediaTransmissionTCP ? (tcpActive? "TCP主动":"TCP被动") : "UDP"); | |
| 1030 | + mediaTransmissionTCP ? (tcpActive ? "TCP主动" : "TCP被动") : "UDP"); | |
| 1026 | 1031 | |
| 1027 | 1032 | MediaServerItem mediaServerItem = broadcastCatch.getMediaServerItem(); |
| 1028 | 1033 | if (mediaServerItem == null) { |
| ... | ... | @@ -1036,7 +1041,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 1036 | 1041 | return; |
| 1037 | 1042 | } |
| 1038 | 1043 | logger.info("设备{}请求语音流, 收流地址:{}:{},ssrc:{}, {}, 对讲方式:{}", requesterId, addressStr, port, ssrc, |
| 1039 | - mediaTransmissionTCP ? (tcpActive? "TCP主动":"TCP被动") : "UDP", sdp.getSessionName().getValue()); | |
| 1044 | + mediaTransmissionTCP ? (tcpActive ? "TCP主动" : "TCP被动") : "UDP", sdp.getSessionName().getValue()); | |
| 1040 | 1045 | |
| 1041 | 1046 | SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, |
| 1042 | 1047 | device.getDeviceId(), broadcastCatch.getChannelId(), |
| ... | ... | @@ -1076,7 +1081,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 1076 | 1081 | Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, broadcastCatch.getApp(), broadcastCatch.getStream()); |
| 1077 | 1082 | if (streamReady) { |
| 1078 | 1083 | sendOk(device, sendRtpItem, sdp, request, mediaServerItem, mediaTransmissionTCP, ssrc); |
| 1079 | - }else { | |
| 1084 | + } else { | |
| 1080 | 1085 | logger.warn("[语音通话], 未发现待推送的流,app={},stream={}", broadcastCatch.getApp(), broadcastCatch.getStream()); |
| 1081 | 1086 | try { |
| 1082 | 1087 | responseAck(request, Response.GONE); |
| ... | ... | @@ -1093,29 +1098,30 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 1093 | 1098 | } else { |
| 1094 | 1099 | logger.warn("来自无效设备/平台的请求"); |
| 1095 | 1100 | try { |
| 1096 | - responseAck(request, Response.BAD_REQUEST);; // 不支持的格式,发415 | |
| 1101 | + responseAck(request, Response.BAD_REQUEST); | |
| 1102 | + ; // 不支持的格式,发415 | |
| 1097 | 1103 | } catch (SipException | InvalidArgumentException | ParseException e) { |
| 1098 | 1104 | logger.error("[命令发送失败] invite 来自无效设备/平台的请求, {}", e.getMessage()); |
| 1099 | 1105 | } |
| 1100 | 1106 | } |
| 1101 | 1107 | } |
| 1102 | 1108 | |
| 1103 | - SIPResponse sendOk(Device device, SendRtpItem sendRtpItem, SessionDescription sdp, SIPRequest request, MediaServerItem mediaServerItem, boolean mediaTransmissionTCP, String ssrc){ | |
| 1109 | + SIPResponse sendOk(Device device, SendRtpItem sendRtpItem, SessionDescription sdp, SIPRequest request, MediaServerItem mediaServerItem, boolean mediaTransmissionTCP, String ssrc) { | |
| 1104 | 1110 | SIPResponse sipResponse = null; |
| 1105 | 1111 | try { |
| 1106 | 1112 | sendRtpItem.setStatus(2); |
| 1107 | 1113 | redisCatchStorage.updateSendRTPSever(sendRtpItem); |
| 1108 | 1114 | StringBuffer content = new StringBuffer(200); |
| 1109 | 1115 | content.append("v=0\r\n"); |
| 1110 | - content.append("o="+ config.getId() +" "+ sdp.getOrigin().getSessionId() +" " + sdp.getOrigin().getSessionVersion() + " IN IP4 "+mediaServerItem.getSdpIp()+"\r\n"); | |
| 1116 | + content.append("o=" + config.getId() + " " + sdp.getOrigin().getSessionId() + " " + sdp.getOrigin().getSessionVersion() + " IN IP4 " + mediaServerItem.getSdpIp() + "\r\n"); | |
| 1111 | 1117 | content.append("s=Play\r\n"); |
| 1112 | - content.append("c=IN IP4 "+mediaServerItem.getSdpIp()+"\r\n"); | |
| 1118 | + content.append("c=IN IP4 " + mediaServerItem.getSdpIp() + "\r\n"); | |
| 1113 | 1119 | content.append("t=0 0\r\n"); |
| 1114 | 1120 | |
| 1115 | 1121 | if (mediaTransmissionTCP) { |
| 1116 | - content.append("m=audio "+ sendRtpItem.getLocalPort()+" TCP/RTP/AVP 8\r\n"); | |
| 1117 | - }else { | |
| 1118 | - content.append("m=audio "+ sendRtpItem.getLocalPort()+" RTP/AVP 8\r\n"); | |
| 1122 | + content.append("m=audio " + sendRtpItem.getLocalPort() + " TCP/RTP/AVP 8\r\n"); | |
| 1123 | + } else { | |
| 1124 | + content.append("m=audio " + sendRtpItem.getLocalPort() + " RTP/AVP 8\r\n"); | |
| 1119 | 1125 | } |
| 1120 | 1126 | |
| 1121 | 1127 | content.append("a=rtpmap:8 PCMA/8000/1\r\n"); |
| ... | ... | @@ -1125,11 +1131,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 1125 | 1131 | content.append("a=connection:new\r\n"); |
| 1126 | 1132 | if (!sendRtpItem.isTcpActive()) { |
| 1127 | 1133 | content.append("a=setup:active\r\n"); |
| 1128 | - }else { | |
| 1134 | + } else { | |
| 1129 | 1135 | content.append("a=setup:passive\r\n"); |
| 1130 | 1136 | } |
| 1131 | 1137 | } |
| 1132 | - content.append("y="+ ssrc + "\r\n"); | |
| 1138 | + content.append("y=" + ssrc + "\r\n"); | |
| 1133 | 1139 | content.append("f=v/////a/1/8/1\r\n"); |
| 1134 | 1140 | |
| 1135 | 1141 | ParentPlatform parentPlatform = new ParentPlatform(); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.conf.DynamicTask; | |
| 4 | +import com.genersoft.iot.vmp.conf.UserSetting; | |
| 5 | +import com.genersoft.iot.vmp.gb28181.bean.Device; | |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | |
| 7 | +import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | |
| 8 | +import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; | |
| 9 | +import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; | |
| 10 | +import com.genersoft.iot.vmp.gb28181.utils.SipUtils; | |
| 11 | +import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; | |
| 12 | +import com.genersoft.iot.vmp.service.IDeviceChannelService; | |
| 13 | +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | |
| 14 | +import org.dom4j.DocumentException; | |
| 15 | +import org.dom4j.Element; | |
| 16 | +import org.slf4j.Logger; | |
| 17 | +import org.slf4j.LoggerFactory; | |
| 18 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 19 | +import org.springframework.stereotype.Component; | |
| 20 | + | |
| 21 | +import javax.sip.RequestEvent; | |
| 22 | +import javax.sip.header.FromHeader; | |
| 23 | +import java.util.*; | |
| 24 | +import java.util.concurrent.ConcurrentHashMap; | |
| 25 | +import java.util.concurrent.CopyOnWriteArrayList; | |
| 26 | + | |
| 27 | +/** | |
| 28 | + * SIP命令类型: NOTIFY请求中的目录请求处理 | |
| 29 | + */ | |
| 30 | +@Component | |
| 31 | +public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent { | |
| 32 | + | |
| 33 | + | |
| 34 | + private final static Logger logger = LoggerFactory.getLogger(NotifyRequestForCatalogProcessor.class); | |
| 35 | + | |
| 36 | + private final List<DeviceChannel> updateChannelOnlineList = new CopyOnWriteArrayList<>(); | |
| 37 | + private final List<DeviceChannel> updateChannelOfflineList = new CopyOnWriteArrayList<>(); | |
| 38 | + private final Map<String, DeviceChannel> updateChannelMap = new ConcurrentHashMap<>(); | |
| 39 | + | |
| 40 | + private final Map<String, DeviceChannel> addChannelMap = new ConcurrentHashMap<>(); | |
| 41 | + private final List<DeviceChannel> deleteChannelList = new CopyOnWriteArrayList<>(); | |
| 42 | + | |
| 43 | + | |
| 44 | + @Autowired | |
| 45 | + private UserSetting userSetting; | |
| 46 | + | |
| 47 | + @Autowired | |
| 48 | + private EventPublisher eventPublisher; | |
| 49 | + | |
| 50 | + @Autowired | |
| 51 | + private IRedisCatchStorage redisCatchStorage; | |
| 52 | + | |
| 53 | + @Autowired | |
| 54 | + private IDeviceChannelService deviceChannelService; | |
| 55 | + | |
| 56 | + @Autowired | |
| 57 | + private DynamicTask dynamicTask; | |
| 58 | + | |
| 59 | + private final static String talkKey = "notify-request-for-catalog-task"; | |
| 60 | + | |
| 61 | + public void process(RequestEvent evt) { | |
| 62 | + try { | |
| 63 | + long start = System.currentTimeMillis(); | |
| 64 | + FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); | |
| 65 | + String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader); | |
| 66 | + | |
| 67 | + Device device = redisCatchStorage.getDevice(deviceId); | |
| 68 | + if (device == null || device.getOnline() == 0) { | |
| 69 | + logger.warn("[收到目录订阅]:{}, 但是设备已经离线", (device != null ? device.getDeviceId():"" )); | |
| 70 | + return; | |
| 71 | + } | |
| 72 | + Element rootElement = getRootElement(evt, device.getCharset()); | |
| 73 | + if (rootElement == null) { | |
| 74 | + logger.warn("[ 收到目录订阅 ] content cannot be null, {}", evt.getRequest()); | |
| 75 | + return; | |
| 76 | + } | |
| 77 | + Element deviceListElement = rootElement.element("DeviceList"); | |
| 78 | + if (deviceListElement == null) { | |
| 79 | + return; | |
| 80 | + } | |
| 81 | + Iterator<Element> deviceListIterator = deviceListElement.elementIterator(); | |
| 82 | + if (deviceListIterator != null) { | |
| 83 | + | |
| 84 | + // 遍历DeviceList | |
| 85 | + while (deviceListIterator.hasNext()) { | |
| 86 | + Element itemDevice = deviceListIterator.next(); | |
| 87 | + Element channelDeviceElement = itemDevice.element("DeviceID"); | |
| 88 | + if (channelDeviceElement == null) { | |
| 89 | + continue; | |
| 90 | + } | |
| 91 | + Element eventElement = itemDevice.element("Event"); | |
| 92 | + String event; | |
| 93 | + if (eventElement == null) { | |
| 94 | + logger.warn("[收到目录订阅]:{}, 但是Event为空, 设为默认值 ADD", (device != null ? device.getDeviceId():"" )); | |
| 95 | + event = CatalogEvent.ADD; | |
| 96 | + }else { | |
| 97 | + event = eventElement.getText().toUpperCase(); | |
| 98 | + } | |
| 99 | + DeviceChannel channel = XmlUtil.channelContentHander(itemDevice, device, event); | |
| 100 | + | |
| 101 | + channel.setDeviceId(device.getDeviceId()); | |
| 102 | + logger.info("[收到目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId()); | |
| 103 | + switch (event) { | |
| 104 | + case CatalogEvent.ON: | |
| 105 | + // 上线 | |
| 106 | + logger.info("[收到通道上线通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); | |
| 107 | + updateChannelOnlineList.add(channel); | |
| 108 | + if (updateChannelOnlineList.size() > 300) { | |
| 109 | + executeSaveForOnline(); | |
| 110 | + } | |
| 111 | + if (userSetting.getDeviceStatusNotify()) { | |
| 112 | + // 发送redis消息 | |
| 113 | + redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), channel.getChannelId(), true); | |
| 114 | + } | |
| 115 | + | |
| 116 | + break; | |
| 117 | + case CatalogEvent.OFF : | |
| 118 | + // 离线 | |
| 119 | + logger.info("[收到通道离线通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); | |
| 120 | + if (userSetting.getRefuseChannelStatusChannelFormNotify()) { | |
| 121 | + logger.info("[收到通道离线通知] 但是平台已配置拒绝此消息,来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); | |
| 122 | + }else { | |
| 123 | + updateChannelOfflineList.add(channel); | |
| 124 | + if (updateChannelOfflineList.size() > 300) { | |
| 125 | + executeSaveForOffline(); | |
| 126 | + } | |
| 127 | + if (userSetting.getDeviceStatusNotify()) { | |
| 128 | + // 发送redis消息 | |
| 129 | + redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), channel.getChannelId(), false); | |
| 130 | + } | |
| 131 | + } | |
| 132 | + break; | |
| 133 | + case CatalogEvent.VLOST: | |
| 134 | + // 视频丢失 | |
| 135 | + logger.info("[收到通道视频丢失通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); | |
| 136 | + if (userSetting.getRefuseChannelStatusChannelFormNotify()) { | |
| 137 | + logger.info("[收到通道视频丢失通知] 但是平台已配置拒绝此消息,来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); | |
| 138 | + }else { | |
| 139 | + updateChannelOfflineList.add(channel); | |
| 140 | + if (updateChannelOfflineList.size() > 300) { | |
| 141 | + executeSaveForOffline(); | |
| 142 | + } | |
| 143 | + if (userSetting.getDeviceStatusNotify()) { | |
| 144 | + // 发送redis消息 | |
| 145 | + redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), channel.getChannelId(), false); | |
| 146 | + } | |
| 147 | + } | |
| 148 | + break; | |
| 149 | + case CatalogEvent.DEFECT: | |
| 150 | + // 故障 | |
| 151 | + logger.info("[收到通道视频故障通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); | |
| 152 | + if (userSetting.getRefuseChannelStatusChannelFormNotify()) { | |
| 153 | + logger.info("[收到通道视频故障通知] 但是平台已配置拒绝此消息,来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); | |
| 154 | + }else { | |
| 155 | + updateChannelOfflineList.add(channel); | |
| 156 | + if (updateChannelOfflineList.size() > 300) { | |
| 157 | + executeSaveForOffline(); | |
| 158 | + } | |
| 159 | + if (userSetting.getDeviceStatusNotify()) { | |
| 160 | + // 发送redis消息 | |
| 161 | + redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), channel.getChannelId(), false); | |
| 162 | + } | |
| 163 | + } | |
| 164 | + break; | |
| 165 | + case CatalogEvent.ADD: | |
| 166 | + // 增加 | |
| 167 | + logger.info("[收到增加通道通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); | |
| 168 | + // 判断此通道是否存在 | |
| 169 | + DeviceChannel deviceChannel = deviceChannelService.getOne(deviceId, channel.getChannelId()); | |
| 170 | + if (deviceChannel != null) { | |
| 171 | + channel.setId(deviceChannel.getId()); | |
| 172 | + updateChannelMap.put(channel.getChannelId(), channel); | |
| 173 | + if (updateChannelMap.keySet().size() > 300) { | |
| 174 | + executeSaveForUpdate(); | |
| 175 | + } | |
| 176 | + }else { | |
| 177 | + addChannelMap.put(channel.getChannelId(), channel); | |
| 178 | + if (addChannelMap.keySet().size() > 300) { | |
| 179 | + executeSaveForAdd(); | |
| 180 | + } | |
| 181 | + } | |
| 182 | + | |
| 183 | + break; | |
| 184 | + case CatalogEvent.DEL: | |
| 185 | + // 删除 | |
| 186 | + logger.info("[收到删除通道通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); | |
| 187 | + deleteChannelList.add(channel); | |
| 188 | + if (deleteChannelList.size() > 300) { | |
| 189 | + executeSaveForDelete(); | |
| 190 | + } | |
| 191 | + break; | |
| 192 | + case CatalogEvent.UPDATE: | |
| 193 | + // 更新 | |
| 194 | + logger.info("[收到更新通道通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); | |
| 195 | + // 判断此通道是否存在 | |
| 196 | + DeviceChannel deviceChannelForUpdate = deviceChannelService.getOne(deviceId, channel.getChannelId()); | |
| 197 | + if (deviceChannelForUpdate != null) { | |
| 198 | + channel.setId(deviceChannelForUpdate.getId()); | |
| 199 | + updateChannelMap.put(channel.getChannelId(), channel); | |
| 200 | + if (updateChannelMap.keySet().size() > 300) { | |
| 201 | + executeSaveForUpdate(); | |
| 202 | + } | |
| 203 | + }else { | |
| 204 | + addChannelMap.put(channel.getChannelId(), channel); | |
| 205 | + if (addChannelMap.keySet().size() > 300) { | |
| 206 | + executeSaveForAdd(); | |
| 207 | + } | |
| 208 | + } | |
| 209 | + break; | |
| 210 | + default: | |
| 211 | + logger.warn("[ NotifyCatalog ] event not found : {}", event ); | |
| 212 | + | |
| 213 | + } | |
| 214 | + // 转发变化信息 | |
| 215 | + eventPublisher.catalogEventPublish(null, channel, event); | |
| 216 | + | |
| 217 | + if (updateChannelMap.keySet().size() > 0 | |
| 218 | + || addChannelMap.keySet().size() > 0 | |
| 219 | + || updateChannelOnlineList.size() > 0 | |
| 220 | + || updateChannelOfflineList.size() > 0 | |
| 221 | + || deleteChannelList.size() > 0) { | |
| 222 | + | |
| 223 | + if (!dynamicTask.contains(talkKey)) { | |
| 224 | + dynamicTask.startDelay(talkKey, this::executeSave, 1000); | |
| 225 | + } | |
| 226 | + } | |
| 227 | + } | |
| 228 | + } | |
| 229 | + } catch (DocumentException e) { | |
| 230 | + logger.error("未处理的异常 ", e); | |
| 231 | + } | |
| 232 | + } | |
| 233 | + | |
| 234 | + private void executeSave(){ | |
| 235 | + System.out.println("定时存储数据"); | |
| 236 | + executeSaveForUpdate(); | |
| 237 | + executeSaveForDelete(); | |
| 238 | + executeSaveForOnline(); | |
| 239 | + executeSaveForOffline(); | |
| 240 | + dynamicTask.stop(talkKey); | |
| 241 | + } | |
| 242 | + | |
| 243 | + private void executeSaveForUpdate(){ | |
| 244 | + if (updateChannelMap.values().size() > 0) { | |
| 245 | + ArrayList<DeviceChannel> deviceChannels = new ArrayList<>(updateChannelMap.values()); | |
| 246 | + updateChannelMap.clear(); | |
| 247 | + deviceChannelService.batchUpdateChannel(deviceChannels); | |
| 248 | + } | |
| 249 | + | |
| 250 | + } | |
| 251 | + | |
| 252 | + private void executeSaveForAdd(){ | |
| 253 | + if (addChannelMap.values().size() > 0) { | |
| 254 | + ArrayList<DeviceChannel> deviceChannels = new ArrayList<>(addChannelMap.values()); | |
| 255 | + addChannelMap.clear(); | |
| 256 | + deviceChannelService.batchAddChannel(deviceChannels); | |
| 257 | + } | |
| 258 | + } | |
| 259 | + | |
| 260 | + private void executeSaveForDelete(){ | |
| 261 | + if (deleteChannelList.size() > 0) { | |
| 262 | + deviceChannelService.deleteChannels(deleteChannelList); | |
| 263 | + deleteChannelList.clear(); | |
| 264 | + } | |
| 265 | + } | |
| 266 | + | |
| 267 | + private void executeSaveForOnline(){ | |
| 268 | + if (updateChannelOnlineList.size() > 0) { | |
| 269 | + deviceChannelService.channelsOnline(updateChannelOnlineList); | |
| 270 | + updateChannelOnlineList.clear(); | |
| 271 | + } | |
| 272 | + } | |
| 273 | + | |
| 274 | + private void executeSaveForOffline(){ | |
| 275 | + if (updateChannelOfflineList.size() > 0) { | |
| 276 | + deviceChannelService.channelsOffline(updateChannelOfflineList); | |
| 277 | + updateChannelOfflineList.clear(); | |
| 278 | + } | |
| 279 | + } | |
| 280 | + | |
| 281 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java
| ... | ... | @@ -76,12 +76,17 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements |
| 76 | 76 | @Autowired |
| 77 | 77 | private IDeviceChannelService deviceChannelService; |
| 78 | 78 | |
| 79 | + @Autowired | |
| 80 | + private NotifyRequestForCatalogProcessor notifyRequestForCatalogProcessor; | |
| 81 | + | |
| 79 | 82 | private ConcurrentLinkedQueue<HandlerCatchData> taskQueue = new ConcurrentLinkedQueue<>(); |
| 80 | 83 | |
| 81 | 84 | @Qualifier("taskExecutor") |
| 82 | 85 | @Autowired |
| 83 | 86 | private ThreadPoolTaskExecutor taskExecutor; |
| 84 | 87 | |
| 88 | + private int maxQueueCount = 30000; | |
| 89 | + | |
| 85 | 90 | @Override |
| 86 | 91 | public void afterPropertiesSet() throws Exception { |
| 87 | 92 | // 添加消息处理的订阅 |
| ... | ... | @@ -91,43 +96,52 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements |
| 91 | 96 | @Override |
| 92 | 97 | public void process(RequestEvent evt) { |
| 93 | 98 | try { |
| 94 | - responseAck((SIPRequest) evt.getRequest(), Response.OK, null, null); | |
| 99 | + | |
| 100 | + if (taskQueue.size() >= userSetting.getMaxNotifyCountQueue()) { | |
| 101 | + responseAck((SIPRequest) evt.getRequest(), Response.BUSY_HERE, null, null); | |
| 102 | + logger.error("[notify] 待处理消息队列已满 {},返回486 BUSY_HERE,消息不做处理", userSetting.getMaxNotifyCountQueue()); | |
| 103 | + return; | |
| 104 | + }else { | |
| 105 | + responseAck((SIPRequest) evt.getRequest(), Response.OK, null, null); | |
| 106 | + } | |
| 107 | + | |
| 95 | 108 | }catch (SipException | InvalidArgumentException | ParseException e) { |
| 96 | 109 | logger.error("未处理的异常 ", e); |
| 97 | 110 | } |
| 98 | 111 | boolean runed = !taskQueue.isEmpty(); |
| 112 | + logger.info("[notify] 待处理消息数量: {}", taskQueue.size()); | |
| 99 | 113 | taskQueue.offer(new HandlerCatchData(evt, null, null)); |
| 100 | 114 | if (!runed) { |
| 101 | 115 | taskExecutor.execute(()-> { |
| 102 | - try { | |
| 103 | - while (!taskQueue.isEmpty()) { | |
| 104 | - try { | |
| 105 | - HandlerCatchData take = taskQueue.poll(); | |
| 106 | - Element rootElement = getRootElement(take.getEvt()); | |
| 107 | - if (rootElement == null) { | |
| 108 | - logger.error("处理NOTIFY消息时未获取到消息体,{}", take.getEvt().getRequest()); | |
| 109 | - continue; | |
| 110 | - } | |
| 111 | - String cmd = XmlUtil.getText(rootElement, "CmdType"); | |
| 112 | - | |
| 113 | - if (CmdType.CATALOG.equals(cmd)) { | |
| 114 | - logger.info("接收到Catalog通知"); | |
| 115 | - processNotifyCatalogList(take.getEvt()); | |
| 116 | - } else if (CmdType.ALARM.equals(cmd)) { | |
| 117 | - logger.info("接收到Alarm通知"); | |
| 118 | - processNotifyAlarm(take.getEvt()); | |
| 119 | - } else if (CmdType.MOBILE_POSITION.equals(cmd)) { | |
| 120 | - logger.info("接收到MobilePosition通知"); | |
| 121 | - processNotifyMobilePosition(take.getEvt()); | |
| 122 | - } else { | |
| 123 | - logger.info("接收到消息:" + cmd); | |
| 124 | - } | |
| 125 | - } catch (DocumentException e) { | |
| 126 | - logger.error("处理NOTIFY消息时错误", e); | |
| 116 | + while (!taskQueue.isEmpty()) { | |
| 117 | + try { | |
| 118 | + HandlerCatchData take = taskQueue.poll(); | |
| 119 | + if (take == null) { | |
| 120 | + continue; | |
| 121 | + } | |
| 122 | + Element rootElement = getRootElement(take.getEvt()); | |
| 123 | + if (rootElement == null) { | |
| 124 | + logger.error("处理NOTIFY消息时未获取到消息体,{}", take.getEvt().getRequest()); | |
| 125 | + continue; | |
| 126 | + } | |
| 127 | + String cmd = XmlUtil.getText(rootElement, "CmdType"); | |
| 128 | + | |
| 129 | + if (CmdType.CATALOG.equals(cmd)) { | |
| 130 | + logger.info("接收到Catalog通知"); | |
| 131 | +// processNotifyCatalogList(take.getEvt()); | |
| 132 | + notifyRequestForCatalogProcessor.process(take.getEvt()); | |
| 133 | + } else if (CmdType.ALARM.equals(cmd)) { | |
| 134 | + logger.info("接收到Alarm通知"); | |
| 135 | + processNotifyAlarm(take.getEvt()); | |
| 136 | + } else if (CmdType.MOBILE_POSITION.equals(cmd)) { | |
| 137 | + logger.info("接收到MobilePosition通知"); | |
| 138 | + processNotifyMobilePosition(take.getEvt()); | |
| 139 | + } else { | |
| 140 | + logger.info("接收到消息:" + cmd); | |
| 127 | 141 | } |
| 142 | + } catch (DocumentException e) { | |
| 143 | + logger.error("处理NOTIFY消息时错误", e); | |
| 128 | 144 | } |
| 129 | - }catch (Exception e) { | |
| 130 | - logger.error("处理NOTIFY消息时错误", e); | |
| 131 | 145 | } |
| 132 | 146 | }); |
| 133 | 147 | } |
| ... | ... | @@ -135,7 +149,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements |
| 135 | 149 | |
| 136 | 150 | /** |
| 137 | 151 | * 处理MobilePosition移动位置Notify |
| 138 | - * | |
| 152 | + * | |
| 139 | 153 | * @param evt |
| 140 | 154 | */ |
| 141 | 155 | private void processNotifyMobilePosition(RequestEvent evt) { |
| ... | ... | @@ -239,7 +253,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements |
| 239 | 253 | |
| 240 | 254 | /*** |
| 241 | 255 | * 处理alarm设备报警Notify |
| 242 | - * | |
| 256 | + * | |
| 243 | 257 | * @param evt |
| 244 | 258 | */ |
| 245 | 259 | private void processNotifyAlarm(RequestEvent evt) { |
| ... | ... | @@ -349,7 +363,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements |
| 349 | 363 | |
| 350 | 364 | /*** |
| 351 | 365 | * 处理catalog设备目录列表Notify |
| 352 | - * | |
| 366 | + * | |
| 353 | 367 | * @param evt |
| 354 | 368 | */ |
| 355 | 369 | private void processNotifyCatalogList(RequestEvent evt) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
| ... | ... | @@ -83,21 +83,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen |
| 83 | 83 | public void process(RequestEvent evt) { |
| 84 | 84 | try { |
| 85 | 85 | RequestEventExt evtExt = (RequestEventExt) evt; |
| 86 | - String requestAddress = evtExt.getRemoteIpAddress() + ":" + evtExt.getRemotePort(); | |
| 87 | - | |
| 88 | -// MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer(); | |
| 89 | -// QueryExp protocol = Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")); | |
| 90 | -//// ObjectName name = new ObjectName("*:type=Connector,*"); | |
| 91 | -// ObjectName name = new ObjectName("*:*"); | |
| 92 | -// Set<ObjectName> objectNames = beanServer.queryNames(name, protocol); | |
| 93 | -// for (ObjectName objectName : objectNames) { | |
| 94 | -// String catalina = objectName.getDomain(); | |
| 95 | -// if ("Catalina".equals(catalina)) { | |
| 96 | -// System.out.println(objectName.getKeyProperty("port")); | |
| 97 | -// } | |
| 98 | -// } | |
| 99 | - | |
| 100 | -// System.out.println(ServiceInfo.getServerPort()); | |
| 86 | + | |
| 101 | 87 | SIPRequest request = (SIPRequest)evt.getRequest(); |
| 102 | 88 | Response response = null; |
| 103 | 89 | boolean passwordCorrect = false; |
| ... | ... | @@ -107,12 +93,13 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen |
| 107 | 93 | AddressImpl address = (AddressImpl) fromHeader.getAddress(); |
| 108 | 94 | SipUri uri = (SipUri) address.getURI(); |
| 109 | 95 | String deviceId = uri.getUser(); |
| 110 | - logger.info("[注册请求] 设备:{}, 开始处理: {}", deviceId, requestAddress); | |
| 96 | + | |
| 111 | 97 | Device device = deviceService.getDevice(deviceId); |
| 112 | 98 | |
| 113 | 99 | RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, |
| 114 | 100 | userSetting.getSipUseSourceIpAsRemoteAddress()); |
| 115 | - | |
| 101 | + String requestAddress = remoteAddressInfo.getIp() + ":" + remoteAddressInfo.getPort(); | |
| 102 | + logger.info("[注册请求] 设备:{}, 开始处理: {}", deviceId, requestAddress); | |
| 116 | 103 | if (device != null && |
| 117 | 104 | device.getSipTransactionInfo() != null && |
| 118 | 105 | request.getCallIdHeader().getCallId().equals(device.getSipTransactionInfo().getCallId())) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/info/InfoRequestProcessor.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.info; |
| 2 | 2 | |
| 3 | -import com.genersoft.iot.vmp.common.StreamInfo; | |
| 3 | +import com.genersoft.iot.vmp.common.InviteInfo; | |
| 4 | +import com.genersoft.iot.vmp.common.InviteSessionType; | |
| 4 | 5 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 5 | 6 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 6 | 7 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| ... | ... | @@ -9,6 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| 9 | 10 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; |
| 10 | 11 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| 11 | 12 | import com.genersoft.iot.vmp.gb28181.utils.SipUtils; |
| 13 | +import com.genersoft.iot.vmp.service.IInviteStreamService; | |
| 12 | 14 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 13 | 15 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 14 | 16 | import gov.nist.javax.sip.message.SIPRequest; |
| ... | ... | @@ -17,10 +19,12 @@ import org.slf4j.LoggerFactory; |
| 17 | 19 | import org.springframework.beans.factory.InitializingBean; |
| 18 | 20 | import org.springframework.beans.factory.annotation.Autowired; |
| 19 | 21 | import org.springframework.stereotype.Component; |
| 22 | + | |
| 20 | 23 | import javax.sip.InvalidArgumentException; |
| 21 | 24 | import javax.sip.RequestEvent; |
| 22 | 25 | import javax.sip.SipException; |
| 23 | -import javax.sip.header.*; | |
| 26 | +import javax.sip.header.CallIdHeader; | |
| 27 | +import javax.sip.header.ContentTypeHeader; | |
| 24 | 28 | import javax.sip.message.Response; |
| 25 | 29 | import java.text.ParseException; |
| 26 | 30 | |
| ... | ... | @@ -44,6 +48,9 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I |
| 44 | 48 | private IRedisCatchStorage redisCatchStorage; |
| 45 | 49 | |
| 46 | 50 | @Autowired |
| 51 | + private IInviteStreamService inviteStreamService; | |
| 52 | + | |
| 53 | + @Autowired | |
| 47 | 54 | private IVideoManagerStorage storager; |
| 48 | 55 | |
| 49 | 56 | @Autowired |
| ... | ... | @@ -103,27 +110,30 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I |
| 103 | 110 | if ("Application".equalsIgnoreCase(contentType) && "MANSRTSP".equalsIgnoreCase(contentSubType)) { |
| 104 | 111 | SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, null, callIdHeader.getCallId()); |
| 105 | 112 | String streamId = sendRtpItem.getStream(); |
| 106 | - StreamInfo streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null); | |
| 107 | - if (null == streamInfo) { | |
| 113 | + InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(InviteSessionType.PLAYBACK, streamId); | |
| 114 | + if (null == inviteInfo) { | |
| 108 | 115 | responseAck(request, Response.NOT_FOUND, "stream " + streamId + " not found"); |
| 109 | 116 | return; |
| 110 | 117 | } |
| 111 | - Device device1 = storager.queryVideoDevice(streamInfo.getDeviceID()); | |
| 112 | - cmder.playbackControlCmd(device1,streamInfo,new String(evt.getRequest().getRawContent()),eventResult -> { | |
| 113 | - // 失败的回复 | |
| 114 | - try { | |
| 115 | - responseAck(request, eventResult.statusCode, eventResult.msg); | |
| 116 | - } catch (SipException | InvalidArgumentException | ParseException e) { | |
| 117 | - logger.error("[命令发送失败] 国标级联 录像控制: {}", e.getMessage()); | |
| 118 | - } | |
| 119 | - }, eventResult -> { | |
| 120 | - // 成功的回复 | |
| 121 | - try { | |
| 122 | - responseAck(request, eventResult.statusCode); | |
| 123 | - } catch (SipException | InvalidArgumentException | ParseException e) { | |
| 124 | - logger.error("[命令发送失败] 国标级联 录像控制: {}", e.getMessage()); | |
| 125 | - } | |
| 126 | - }); | |
| 118 | + Device device1 = storager.queryVideoDevice(inviteInfo.getDeviceId()); | |
| 119 | + if (inviteInfo.getStreamInfo() != null) { | |
| 120 | + cmder.playbackControlCmd(device1,inviteInfo.getStreamInfo(),new String(evt.getRequest().getRawContent()),eventResult -> { | |
| 121 | + // 失败的回复 | |
| 122 | + try { | |
| 123 | + responseAck(request, eventResult.statusCode, eventResult.msg); | |
| 124 | + } catch (SipException | InvalidArgumentException | ParseException e) { | |
| 125 | + logger.error("[命令发送失败] 国标级联 录像控制: {}", e.getMessage()); | |
| 126 | + } | |
| 127 | + }, eventResult -> { | |
| 128 | + // 成功的回复 | |
| 129 | + try { | |
| 130 | + responseAck(request, eventResult.statusCode); | |
| 131 | + } catch (SipException | InvalidArgumentException | ParseException e) { | |
| 132 | + logger.error("[命令发送失败] 国标级联 录像控制: {}", e.getMessage()); | |
| 133 | + } | |
| 134 | + }); | |
| 135 | + } | |
| 136 | + | |
| 127 | 137 | } |
| 128 | 138 | } |
| 129 | 139 | } catch (SipException e) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
| ... | ... | @@ -69,6 +69,7 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp |
| 69 | 69 | |
| 70 | 70 | RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress()); |
| 71 | 71 | if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort()) { |
| 72 | + logger.info("[心跳] 设备{}地址变化, 远程地址为: {}:{}", device.getDeviceId(), remoteAddressInfo.getIp(), remoteAddressInfo.getPort()); | |
| 72 | 73 | device.setPort(remoteAddressInfo.getPort()); |
| 73 | 74 | device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort()))); |
| 74 | 75 | device.setIp(remoteAddressInfo.getIp()); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd; |
| 2 | 2 | |
| 3 | -import com.genersoft.iot.vmp.common.StreamInfo; | |
| 3 | +import com.genersoft.iot.vmp.common.InviteInfo; | |
| 4 | +import com.genersoft.iot.vmp.common.InviteSessionType; | |
| 4 | 5 | import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; |
| 5 | 6 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 6 | 7 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| ... | ... | @@ -12,6 +13,10 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; |
| 12 | 13 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| 13 | 14 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; |
| 14 | 15 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; |
| 16 | +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; | |
| 17 | +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; | |
| 18 | +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; | |
| 19 | +import com.genersoft.iot.vmp.service.IInviteStreamService; | |
| 15 | 20 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 16 | 21 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 17 | 22 | import gov.nist.javax.sip.message.SIPRequest; |
| ... | ... | @@ -58,6 +63,15 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i |
| 58 | 63 | @Autowired |
| 59 | 64 | private VideoStreamSessionManager sessionManager; |
| 60 | 65 | |
| 66 | + @Autowired | |
| 67 | + private ZlmHttpHookSubscribe subscribe; | |
| 68 | + | |
| 69 | + @Autowired | |
| 70 | + private IInviteStreamService inviteStreamService; | |
| 71 | + | |
| 72 | + @Autowired | |
| 73 | + private VideoStreamSessionManager streamSession; | |
| 74 | + | |
| 61 | 75 | @Override |
| 62 | 76 | public void afterPropertiesSet() throws Exception { |
| 63 | 77 | notifyMessageHandler.addHandler(cmdType, this); |
| ... | ... | @@ -76,23 +90,24 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i |
| 76 | 90 | String NotifyType =getText(rootElement, "NotifyType"); |
| 77 | 91 | if ("121".equals(NotifyType)){ |
| 78 | 92 | logger.info("[录像流]推送完毕,收到关流通知"); |
| 79 | - // 查询是设备 | |
| 80 | - StreamInfo streamInfo = redisCatchStorage.queryDownload(null, null, null, callIdHeader.getCallId()); | |
| 81 | - if (streamInfo != null) { | |
| 82 | - // 设置进度100% | |
| 83 | - streamInfo.setProgress(1); | |
| 84 | - redisCatchStorage.startDownload(streamInfo, callIdHeader.getCallId()); | |
| 85 | - } | |
| 86 | 93 | |
| 87 | - // 先从会话内查找 | |
| 88 | - SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransaction(null, null, callIdHeader.getCallId(), null); | |
| 89 | - if (ssrcTransaction != null) { // 兼容海康 媒体通知 消息from字段不是设备ID的问题 | |
| 94 | + SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(null, null, callIdHeader.getCallId(), null); | |
| 95 | + if (ssrcTransaction != null) { | |
| 96 | + logger.info("[录像流]推送完毕,关流通知, device: {}, channelId: {}", ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId()); | |
| 97 | + InviteInfo inviteInfo = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream()); | |
| 98 | + if (inviteInfo.getStreamInfo() != null) { | |
| 99 | + inviteInfo.getStreamInfo().setProgress(1); | |
| 100 | + inviteStreamService.updateInviteInfo(inviteInfo); | |
| 101 | + } | |
| 90 | 102 | |
| 91 | 103 | try { |
| 92 | 104 | cmder.streamByeCmd(device, ssrcTransaction.getChannelId(), null, callIdHeader.getCallId()); |
| 93 | 105 | } catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) { |
| 94 | 106 | logger.error("[录像流]推送完毕,收到关流通知, 发送BYE失败 {}", e.getMessage()); |
| 95 | 107 | } |
| 108 | + // 去除监听流注销自动停止下载的监听 | |
| 109 | + HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcTransaction.getStream(), false, "rtsp", ssrcTransaction.getMediaServerId()); | |
| 110 | + subscribe.removeSubscribe(hookSubscribe); | |
| 96 | 111 | |
| 97 | 112 | // 如果级联播放,需要给上级发送此通知 TODO 多个上级同时观看一个下级 可能存在停错的问题,需要将点播CallId进行上下级绑定 |
| 98 | 113 | SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, ssrcTransaction.getChannelId(), null, null); |
| ... | ... | @@ -108,6 +123,8 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i |
| 108 | 123 | logger.error("[命令发送失败] 国标级联 录像播放完毕: {}", e.getMessage()); |
| 109 | 124 | } |
| 110 | 125 | } |
| 126 | + }else { | |
| 127 | + logger.info("[录像流]推送完毕,关流通知, 但是未找到对应的下载信息"); | |
| 111 | 128 | } |
| 112 | 129 | } |
| 113 | 130 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java
| ... | ... | @@ -18,6 +18,10 @@ import javax.sdp.SessionDescription; |
| 18 | 18 | import javax.sip.InvalidArgumentException; |
| 19 | 19 | import javax.sip.ResponseEvent; |
| 20 | 20 | import javax.sip.SipException; |
| 21 | +import javax.sip.InvalidArgumentException; | |
| 22 | +import javax.sip.ResponseEvent; | |
| 23 | +import javax.sip.SipException; | |
| 24 | +import javax.sip.SipFactory; | |
| 21 | 25 | import javax.sip.address.SipURI; |
| 22 | 26 | import javax.sip.message.Request; |
| 23 | 27 | import javax.sip.message.Response; |
| ... | ... | @@ -91,7 +95,7 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract { |
| 91 | 95 | } |
| 92 | 96 | // 查看是否是来自设备的,此是回复 |
| 93 | 97 | |
| 94 | - SipURI requestUri = sipLayer.getSipFactory().createAddressFactory().createSipURI(sdp.getOrigin().getUsername(), event.getRemoteIpAddress() + ":" + event.getRemotePort()); | |
| 98 | + SipURI requestUri = SipFactory.getInstance().createAddressFactory().createSipURI(sdp.getOrigin().getUsername(), event.getRemoteIpAddress() + ":" + event.getRemotePort()); | |
| 95 | 99 | Request reqAck = headerProvider.createAckRequest(response.getLocalAddress().getHostAddress(), requestUri, response); |
| 96 | 100 | |
| 97 | 101 | logger.info("[回复ack] {}-> {}:{} ", sdp.getOrigin().getUsername(), event.getRemoteIpAddress(), event.getRemotePort()); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java
| ... | ... | @@ -54,7 +54,7 @@ public class SipUtils { |
| 54 | 54 | return "z9hG4bK" + System.currentTimeMillis(); |
| 55 | 55 | } |
| 56 | 56 | |
| 57 | - public static UserAgentHeader createUserAgentHeader(SipFactory sipFactory, GitUtil gitUtil) throws PeerUnavailableException, ParseException { | |
| 57 | + public static UserAgentHeader createUserAgentHeader(GitUtil gitUtil) throws PeerUnavailableException, ParseException { | |
| 58 | 58 | List<String> agentParam = new ArrayList<>(); |
| 59 | 59 | agentParam.add("WVP-Pro "); |
| 60 | 60 | if (gitUtil != null ) { |
| ... | ... | @@ -66,7 +66,7 @@ public class SipUtils { |
| 66 | 66 | agentParam.add(gitUtil.getCommitTime()); |
| 67 | 67 | } |
| 68 | 68 | } |
| 69 | - return sipFactory.createHeaderFactory().createUserAgentHeader(agentParam); | |
| 69 | + return SipFactory.getInstance().createHeaderFactory().createUserAgentHeader(agentParam); | |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | 72 | public static String getNewFromTag(){ |
| ... | ... | @@ -153,8 +153,9 @@ public class SipUtils { |
| 153 | 153 | String remoteAddress; |
| 154 | 154 | int remotePort; |
| 155 | 155 | if (sipUseSourceIpAsRemoteAddress) { |
| 156 | - remoteAddress = request.getRemoteAddress().getHostAddress(); | |
| 157 | - remotePort = request.getRemotePort(); | |
| 156 | + remoteAddress = request.getPeerPacketSourceAddress().getHostAddress(); | |
| 157 | + remotePort = request.getPeerPacketSourcePort(); | |
| 158 | + | |
| 158 | 159 | }else { |
| 159 | 160 | // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息 |
| 160 | 161 | // 获取到通信地址等信息 |
| ... | ... | @@ -162,8 +163,8 @@ public class SipUtils { |
| 162 | 163 | remotePort = request.getTopmostViaHeader().getRPort(); |
| 163 | 164 | // 解析本地地址替代 |
| 164 | 165 | if (ObjectUtils.isEmpty(remoteAddress) || remotePort == -1) { |
| 165 | - remoteAddress = request.getTopmostViaHeader().getHost(); | |
| 166 | - remotePort = request.getTopmostViaHeader().getPort(); | |
| 166 | + remoteAddress = request.getPeerPacketSourceAddress().getHostAddress(); | |
| 167 | + remotePort = request.getPeerPacketSourcePort(); | |
| 167 | 168 | } |
| 168 | 169 | } |
| 169 | 170 | ... | ... |
src/main/java/com/genersoft/iot/vmp/jt1078/annotation/MsgId.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.jt1078.annotation; | |
| 2 | + | |
| 3 | +import java.lang.annotation.*; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * @author QingtaiJiang | |
| 7 | + * @date 2023/4/27 18:31 | |
| 8 | + * @email qingtaij@163.com | |
| 9 | + */ | |
| 10 | +@Target(ElementType.TYPE) | |
| 11 | +@Retention(RetentionPolicy.RUNTIME) | |
| 12 | +@Documented | |
| 13 | +public @interface MsgId { | |
| 14 | + String id(); | |
| 15 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/jt1078/cmd/JT1078Template.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.jt1078.cmd; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.jt1078.proc.entity.Cmd; | |
| 4 | +import com.genersoft.iot.vmp.jt1078.proc.response.*; | |
| 5 | +import com.genersoft.iot.vmp.jt1078.session.SessionManager; | |
| 6 | + | |
| 7 | +import java.util.Random; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * @author QingtaiJiang | |
| 11 | + * @date 2023/4/27 18:58 | |
| 12 | + * @email qingtaij@163.com | |
| 13 | + */ | |
| 14 | +public class JT1078Template { | |
| 15 | + | |
| 16 | + private final Random random = new Random(); | |
| 17 | + | |
| 18 | + private static final String H9101 = "9101"; | |
| 19 | + private static final String H9102 = "9102"; | |
| 20 | + private static final String H9201 = "9201"; | |
| 21 | + private static final String H9202 = "9202"; | |
| 22 | + private static final String H9205 = "9205"; | |
| 23 | + | |
| 24 | + private static final String H0001 = "0001"; | |
| 25 | + private static final String H1205 = "1205"; | |
| 26 | + | |
| 27 | + /** | |
| 28 | + * 开启直播视频 | |
| 29 | + * | |
| 30 | + * @param devId 设备号 | |
| 31 | + * @param j9101 开启视频参数 | |
| 32 | + */ | |
| 33 | + public String startLive(String devId, J9101 j9101, Integer timeOut) { | |
| 34 | + Cmd cmd = new Cmd.Builder() | |
| 35 | + .setDevId(devId) | |
| 36 | + .setPackageNo(randomInt()) | |
| 37 | + .setMsgId(H9101) | |
| 38 | + .setRespId(H0001) | |
| 39 | + .setRs(j9101) | |
| 40 | + .build(); | |
| 41 | + return SessionManager.INSTANCE.request(cmd, timeOut); | |
| 42 | + } | |
| 43 | + | |
| 44 | + /** | |
| 45 | + * 关闭直播视频 | |
| 46 | + * | |
| 47 | + * @param devId 设备号 | |
| 48 | + * @param j9102 关闭视频参数 | |
| 49 | + */ | |
| 50 | + public String stopLive(String devId, J9102 j9102, Integer timeOut) { | |
| 51 | + Cmd cmd = new Cmd.Builder() | |
| 52 | + .setDevId(devId) | |
| 53 | + .setPackageNo(randomInt()) | |
| 54 | + .setMsgId(H9102) | |
| 55 | + .setRespId(H0001) | |
| 56 | + .setRs(j9102) | |
| 57 | + .build(); | |
| 58 | + return SessionManager.INSTANCE.request(cmd, timeOut); | |
| 59 | + } | |
| 60 | + | |
| 61 | + /** | |
| 62 | + * 查询音视频列表 | |
| 63 | + * | |
| 64 | + * @param devId 设备号 | |
| 65 | + * @param j9205 查询音视频列表 | |
| 66 | + */ | |
| 67 | + public String queryBackTime(String devId, J9205 j9205, Integer timeOut) { | |
| 68 | + Cmd cmd = new Cmd.Builder() | |
| 69 | + .setDevId(devId) | |
| 70 | + .setPackageNo(randomInt()) | |
| 71 | + .setMsgId(H9205) | |
| 72 | + .setRespId(H1205) | |
| 73 | + .setRs(j9205) | |
| 74 | + .build(); | |
| 75 | + return SessionManager.INSTANCE.request(cmd, timeOut); | |
| 76 | + } | |
| 77 | + | |
| 78 | + /** | |
| 79 | + * 开启视频回放 | |
| 80 | + * | |
| 81 | + * @param devId 设备号 | |
| 82 | + * @param j9201 视频回放参数 | |
| 83 | + */ | |
| 84 | + public String startBackLive(String devId, J9201 j9201, Integer timeOut) { | |
| 85 | + Cmd cmd = new Cmd.Builder() | |
| 86 | + .setDevId(devId) | |
| 87 | + .setPackageNo(randomInt()) | |
| 88 | + .setMsgId(H9201) | |
| 89 | + .setRespId(H1205) | |
| 90 | + .setRs(j9201) | |
| 91 | + .build(); | |
| 92 | + return SessionManager.INSTANCE.request(cmd, timeOut); | |
| 93 | + } | |
| 94 | + | |
| 95 | + /** | |
| 96 | + * 视频回放控制 | |
| 97 | + * | |
| 98 | + * @param devId 设备号 | |
| 99 | + * @param j9202 控制视频回放参数 | |
| 100 | + */ | |
| 101 | + public String controlBackLive(String devId, J9202 j9202, Integer timeOut) { | |
| 102 | + Cmd cmd = new Cmd.Builder() | |
| 103 | + .setDevId(devId) | |
| 104 | + .setPackageNo(randomInt()) | |
| 105 | + .setMsgId(H9202) | |
| 106 | + .setRespId(H0001) | |
| 107 | + .setRs(j9202) | |
| 108 | + .build(); | |
| 109 | + return SessionManager.INSTANCE.request(cmd, timeOut); | |
| 110 | + } | |
| 111 | + | |
| 112 | + private Long randomInt() { | |
| 113 | + return (long) random.nextInt(1000) + 1; | |
| 114 | + } | |
| 115 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/jt1078/codec/decode/Jt808Decoder.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.jt1078.codec.decode; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.jt1078.proc.Header; | |
| 4 | +import com.genersoft.iot.vmp.jt1078.proc.factory.CodecFactory; | |
| 5 | +import com.genersoft.iot.vmp.jt1078.proc.request.Re; | |
| 6 | +import com.genersoft.iot.vmp.jt1078.proc.response.Rs; | |
| 7 | +import com.genersoft.iot.vmp.jt1078.session.Session; | |
| 8 | +import io.netty.buffer.ByteBuf; | |
| 9 | +import io.netty.buffer.ByteBufUtil; | |
| 10 | +import io.netty.buffer.CompositeByteBuf; | |
| 11 | +import io.netty.buffer.UnpooledByteBufAllocator; | |
| 12 | +import io.netty.channel.ChannelHandlerContext; | |
| 13 | +import io.netty.handler.codec.ByteToMessageDecoder; | |
| 14 | +import org.slf4j.Logger; | |
| 15 | +import org.slf4j.LoggerFactory; | |
| 16 | + | |
| 17 | +import java.util.ArrayList; | |
| 18 | +import java.util.List; | |
| 19 | + | |
| 20 | +/** | |
| 21 | + * @author QingtaiJiang | |
| 22 | + * @date 2023/4/27 18:10 | |
| 23 | + * @email qingtaij@163.com | |
| 24 | + */ | |
| 25 | +public class Jt808Decoder extends ByteToMessageDecoder { | |
| 26 | + private final static Logger log = LoggerFactory.getLogger(Jt808Decoder.class); | |
| 27 | + | |
| 28 | + @Override | |
| 29 | + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { | |
| 30 | + Session session = ctx.channel().attr(Session.KEY).get(); | |
| 31 | + log.info("> {} hex:{}", session, ByteBufUtil.hexDump(in)); | |
| 32 | + | |
| 33 | + try { | |
| 34 | + ByteBuf buf = unEscapeAndCheck(in); | |
| 35 | + | |
| 36 | + Header header = new Header(); | |
| 37 | + header.setMsgId(ByteBufUtil.hexDump(buf.readSlice(2))); | |
| 38 | + header.setMsgPro(buf.readUnsignedShort()); | |
| 39 | + if (header.is2019Version()) { | |
| 40 | + header.setVersion(buf.readUnsignedByte()); | |
| 41 | + String devId = ByteBufUtil.hexDump(buf.readSlice(10)); | |
| 42 | + header.setDevId(devId.replaceFirst("^0*", "")); | |
| 43 | + } else { | |
| 44 | + header.setDevId(ByteBufUtil.hexDump(buf.readSlice(6)).replaceFirst("^0*", "")); | |
| 45 | + } | |
| 46 | + header.setSn(buf.readUnsignedShort()); | |
| 47 | + | |
| 48 | + Re handler = CodecFactory.getHandler(header.getMsgId()); | |
| 49 | + if (handler == null) { | |
| 50 | + log.error("get msgId is null {}", header.getMsgId()); | |
| 51 | + return; | |
| 52 | + } | |
| 53 | + Rs decode = handler.decode(buf, header, session); | |
| 54 | + if (decode != null) { | |
| 55 | + out.add(decode); | |
| 56 | + } | |
| 57 | + } finally { | |
| 58 | + in.skipBytes(in.readableBytes()); | |
| 59 | + } | |
| 60 | + | |
| 61 | + | |
| 62 | + } | |
| 63 | + | |
| 64 | + | |
| 65 | + /** | |
| 66 | + * 转义与验证校验码 | |
| 67 | + * | |
| 68 | + * @param byteBuf 转义Buf | |
| 69 | + * @return 转义好的数据 | |
| 70 | + */ | |
| 71 | + public ByteBuf unEscapeAndCheck(ByteBuf byteBuf) throws Exception { | |
| 72 | + int low = byteBuf.readerIndex(); | |
| 73 | + int high = byteBuf.writerIndex(); | |
| 74 | + byte checkSum = 0; | |
| 75 | + int calculationCheckSum = 0; | |
| 76 | + | |
| 77 | + byte aByte = byteBuf.getByte(high - 2); | |
| 78 | + byte protocolEscapeFlag7d = 0x7d; | |
| 79 | + //0x7d转义 | |
| 80 | + byte protocolEscapeFlag01 = 0x01; | |
| 81 | + //0x7e转义 | |
| 82 | + byte protocolEscapeFlag02 = 0x02; | |
| 83 | + if (aByte == protocolEscapeFlag7d) { | |
| 84 | + byte b2 = byteBuf.getByte(high - 1); | |
| 85 | + if (b2 == protocolEscapeFlag01) { | |
| 86 | + checkSum = protocolEscapeFlag7d; | |
| 87 | + } else if (b2 == protocolEscapeFlag02) { | |
| 88 | + checkSum = 0x7e; | |
| 89 | + } else { | |
| 90 | + log.error("转义1异常:{}", ByteBufUtil.hexDump(byteBuf)); | |
| 91 | + throw new Exception("转义错误"); | |
| 92 | + } | |
| 93 | + high = high - 2; | |
| 94 | + } else { | |
| 95 | + high = high - 1; | |
| 96 | + checkSum = byteBuf.getByte(high); | |
| 97 | + } | |
| 98 | + List<ByteBuf> bufList = new ArrayList<>(); | |
| 99 | + int index = low; | |
| 100 | + while (index < high) { | |
| 101 | + byte b = byteBuf.getByte(index); | |
| 102 | + if (b == protocolEscapeFlag7d) { | |
| 103 | + byte c = byteBuf.getByte(index + 1); | |
| 104 | + if (c == protocolEscapeFlag01) { | |
| 105 | + ByteBuf slice = slice0x01(byteBuf, low, index); | |
| 106 | + bufList.add(slice); | |
| 107 | + b = protocolEscapeFlag7d; | |
| 108 | + } else if (c == protocolEscapeFlag02) { | |
| 109 | + ByteBuf slice = slice0x02(byteBuf, low, index); | |
| 110 | + bufList.add(slice); | |
| 111 | + b = 0x7e; | |
| 112 | + } else { | |
| 113 | + log.error("转义2异常:{}", ByteBufUtil.hexDump(byteBuf)); | |
| 114 | + throw new Exception("转义错误"); | |
| 115 | + } | |
| 116 | + index += 2; | |
| 117 | + low = index; | |
| 118 | + } else { | |
| 119 | + index += 1; | |
| 120 | + } | |
| 121 | + calculationCheckSum = calculationCheckSum ^ b; | |
| 122 | + } | |
| 123 | + | |
| 124 | + if (calculationCheckSum == checkSum) { | |
| 125 | + if (bufList.size() == 0) { | |
| 126 | + return byteBuf.slice(low, high); | |
| 127 | + } else { | |
| 128 | + bufList.add(byteBuf.slice(low, high - low)); | |
| 129 | + return new CompositeByteBuf(UnpooledByteBufAllocator.DEFAULT, false, bufList.size(), bufList); | |
| 130 | + } | |
| 131 | + } else { | |
| 132 | + log.info("{} 解析校验码:{}--计算校验码:{}", ByteBufUtil.hexDump(byteBuf), checkSum, calculationCheckSum); | |
| 133 | + throw new Exception("校验码错误!"); | |
| 134 | + } | |
| 135 | + } | |
| 136 | + | |
| 137 | + | |
| 138 | + private ByteBuf slice0x01(ByteBuf buf, int low, int sign) { | |
| 139 | + return buf.slice(low, sign - low + 1); | |
| 140 | + } | |
| 141 | + | |
| 142 | + private ByteBuf slice0x02(ByteBuf buf, int low, int sign) { | |
| 143 | + buf.setByte(sign, 0x7e); | |
| 144 | + return buf.slice(low, sign - low + 1); | |
| 145 | + } | |
| 146 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/jt1078/codec/encode/Jt808Encoder.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.jt1078.codec.encode; | |
| 2 | + | |
| 3 | + | |
| 4 | +import com.genersoft.iot.vmp.jt1078.proc.response.Rs; | |
| 5 | +import com.genersoft.iot.vmp.jt1078.session.Session; | |
| 6 | +import io.netty.buffer.ByteBuf; | |
| 7 | +import io.netty.buffer.ByteBufUtil; | |
| 8 | +import io.netty.channel.ChannelHandlerContext; | |
| 9 | +import io.netty.handler.codec.MessageToByteEncoder; | |
| 10 | +import org.slf4j.Logger; | |
| 11 | +import org.slf4j.LoggerFactory; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * @author QingtaiJiang | |
| 15 | + * @date 2023/4/27 18:10 | |
| 16 | + * @email qingtaij@163.com | |
| 17 | + */ | |
| 18 | +public class Jt808Encoder extends MessageToByteEncoder<Rs> { | |
| 19 | + private final static Logger log = LoggerFactory.getLogger(Jt808Encoder.class); | |
| 20 | + | |
| 21 | + @Override | |
| 22 | + protected void encode(ChannelHandlerContext ctx, Rs msg, ByteBuf out) throws Exception { | |
| 23 | + Session session = ctx.channel().attr(Session.KEY).get(); | |
| 24 | + | |
| 25 | + ByteBuf encode = Jt808EncoderCmd.encode(msg, session, session.nextSerialNo()); | |
| 26 | + if(encode!=null){ | |
| 27 | + log.info("< {} hex:{}", session, ByteBufUtil.hexDump(encode)); | |
| 28 | + out.writeBytes(encode); | |
| 29 | + } | |
| 30 | + } | |
| 31 | + | |
| 32 | + | |
| 33 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/jt1078/codec/encode/Jt808EncoderCmd.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.jt1078.codec.encode; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.jt1078.annotation.MsgId; | |
| 4 | +import com.genersoft.iot.vmp.jt1078.proc.Header; | |
| 5 | +import com.genersoft.iot.vmp.jt1078.proc.entity.Cmd; | |
| 6 | +import com.genersoft.iot.vmp.jt1078.proc.response.Rs; | |
| 7 | +import com.genersoft.iot.vmp.jt1078.session.Session; | |
| 8 | +import com.genersoft.iot.vmp.jt1078.util.Bin; | |
| 9 | +import io.netty.buffer.ByteBuf; | |
| 10 | +import io.netty.buffer.ByteBufUtil; | |
| 11 | +import io.netty.buffer.CompositeByteBuf; | |
| 12 | +import io.netty.buffer.Unpooled; | |
| 13 | +import io.netty.channel.ChannelHandlerContext; | |
| 14 | +import io.netty.handler.codec.MessageToByteEncoder; | |
| 15 | +import io.netty.util.ByteProcessor; | |
| 16 | +import org.slf4j.Logger; | |
| 17 | +import org.slf4j.LoggerFactory; | |
| 18 | +import org.springframework.util.StringUtils; | |
| 19 | + | |
| 20 | +import java.util.LinkedList; | |
| 21 | + | |
| 22 | +/** | |
| 23 | + * @author QingtaiJiang | |
| 24 | + * @date 2023/4/27 18:25 | |
| 25 | + * @email qingtaij@163.com | |
| 26 | + */ | |
| 27 | +public class Jt808EncoderCmd extends MessageToByteEncoder<Cmd> { | |
| 28 | + private final static Logger log = LoggerFactory.getLogger(Jt808EncoderCmd.class); | |
| 29 | + | |
| 30 | + @Override | |
| 31 | + protected void encode(ChannelHandlerContext ctx, Cmd cmd, ByteBuf out) throws Exception { | |
| 32 | + Session session = ctx.channel().attr(Session.KEY).get(); | |
| 33 | + Rs msg = cmd.getRs(); | |
| 34 | + ByteBuf encode = encode(msg, session, cmd.getPackageNo().intValue()); | |
| 35 | + if (encode != null) { | |
| 36 | + log.info("< {} hex:{}", session, ByteBufUtil.hexDump(encode)); | |
| 37 | + out.writeBytes(encode); | |
| 38 | + } | |
| 39 | + } | |
| 40 | + | |
| 41 | + | |
| 42 | + public static ByteBuf encode(Rs msg, Session session, Integer packageNo) { | |
| 43 | + String id = msg.getClass().getAnnotation(MsgId.class).id(); | |
| 44 | + if (!StringUtils.hasLength(id)) { | |
| 45 | + log.error("Not find msgId"); | |
| 46 | + return null; | |
| 47 | + } | |
| 48 | + | |
| 49 | + ByteBuf byteBuf = Unpooled.buffer(); | |
| 50 | + | |
| 51 | + byteBuf.writeBytes(ByteBufUtil.decodeHexDump(id)); | |
| 52 | + | |
| 53 | + ByteBuf encode = msg.encode(); | |
| 54 | + | |
| 55 | + Header header = msg.getHeader(); | |
| 56 | + if (header == null) { | |
| 57 | + header = session.getHeader(); | |
| 58 | + } | |
| 59 | + | |
| 60 | + if (header.is2019Version()) { | |
| 61 | + // 消息体属性 | |
| 62 | + byteBuf.writeShort(encode.readableBytes() | 1 << 14); | |
| 63 | + | |
| 64 | + // 版本号 | |
| 65 | + byteBuf.writeByte(header.getVersion()); | |
| 66 | + | |
| 67 | + // 终端手机号 | |
| 68 | + byteBuf.writeBytes(ByteBufUtil.decodeHexDump(Bin.strHexPaddingLeft(header.getDevId(), 20))); | |
| 69 | + } else { | |
| 70 | + // 消息体属性 | |
| 71 | + byteBuf.writeShort(encode.readableBytes()); | |
| 72 | + | |
| 73 | + byteBuf.writeBytes(ByteBufUtil.decodeHexDump(Bin.strHexPaddingLeft(header.getDevId(), 12))); | |
| 74 | + } | |
| 75 | + | |
| 76 | + // 消息体流水号 | |
| 77 | + byteBuf.writeShort(packageNo); | |
| 78 | + | |
| 79 | + // 写入消息体 | |
| 80 | + byteBuf.writeBytes(encode); | |
| 81 | + | |
| 82 | + // 计算校验码,并反转义 | |
| 83 | + byteBuf = escapeAndCheck0(byteBuf); | |
| 84 | + return byteBuf; | |
| 85 | + } | |
| 86 | + | |
| 87 | + | |
| 88 | + private static final ByteProcessor searcher = value -> !(value == 0x7d || value == 0x7e); | |
| 89 | + | |
| 90 | + //转义与校验 | |
| 91 | + public static ByteBuf escapeAndCheck0(ByteBuf source) { | |
| 92 | + | |
| 93 | + sign(source); | |
| 94 | + | |
| 95 | + int low = source.readerIndex(); | |
| 96 | + int high = source.writerIndex(); | |
| 97 | + | |
| 98 | + LinkedList<ByteBuf> bufList = new LinkedList<>(); | |
| 99 | + int mark, len; | |
| 100 | + while ((mark = source.forEachByte(low, high - low, searcher)) > 0) { | |
| 101 | + | |
| 102 | + len = mark + 1 - low; | |
| 103 | + ByteBuf[] slice = slice(source, low, len); | |
| 104 | + bufList.add(slice[0]); | |
| 105 | + bufList.add(slice[1]); | |
| 106 | + low += len; | |
| 107 | + } | |
| 108 | + | |
| 109 | + if (bufList.size() > 0) { | |
| 110 | + bufList.add(source.slice(low, high - low)); | |
| 111 | + } else { | |
| 112 | + bufList.add(source); | |
| 113 | + } | |
| 114 | + | |
| 115 | + ByteBuf delimiter = Unpooled.buffer(1, 1).writeByte(0x7e).retain(); | |
| 116 | + bufList.addFirst(delimiter); | |
| 117 | + bufList.addLast(delimiter); | |
| 118 | + | |
| 119 | + CompositeByteBuf byteBufLs = Unpooled.compositeBuffer(bufList.size()); | |
| 120 | + byteBufLs.addComponents(true, bufList); | |
| 121 | + return byteBufLs; | |
| 122 | + } | |
| 123 | + | |
| 124 | + public static void sign(ByteBuf buf) { | |
| 125 | + byte checkCode = bcc(buf); | |
| 126 | + buf.writeByte(checkCode); | |
| 127 | + } | |
| 128 | + | |
| 129 | + public static byte bcc(ByteBuf byteBuf) { | |
| 130 | + byte cs = 0; | |
| 131 | + while (byteBuf.isReadable()) | |
| 132 | + cs ^= byteBuf.readByte(); | |
| 133 | + byteBuf.resetReaderIndex(); | |
| 134 | + return cs; | |
| 135 | + } | |
| 136 | + | |
| 137 | + protected static ByteBuf[] slice(ByteBuf byteBuf, int index, int length) { | |
| 138 | + byte first = byteBuf.getByte(index + length - 1); | |
| 139 | + | |
| 140 | + ByteBuf[] byteBufList = new ByteBuf[2]; | |
| 141 | + byteBufList[0] = byteBuf.retainedSlice(index, length); | |
| 142 | + | |
| 143 | + if (first == 0x7d) { | |
| 144 | + byteBufList[1] = Unpooled.buffer(1, 1).writeByte(0x01); | |
| 145 | + } else { | |
| 146 | + byteBuf.setByte(index + length - 1, 0x7d); | |
| 147 | + byteBufList[1] = Unpooled.buffer(1, 1).writeByte(0x02); | |
| 148 | + } | |
| 149 | + return byteBufList; | |
| 150 | + } | |
| 151 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/jt1078/codec/netty/Jt808Handler.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.jt1078.codec.netty; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.jt1078.proc.response.Rs; | |
| 4 | +import com.genersoft.iot.vmp.jt1078.session.Session; | |
| 5 | +import com.genersoft.iot.vmp.jt1078.session.SessionManager; | |
| 6 | +import io.netty.channel.Channel; | |
| 7 | +import io.netty.channel.ChannelHandlerContext; | |
| 8 | +import io.netty.channel.ChannelInboundHandlerAdapter; | |
| 9 | +import io.netty.handler.timeout.IdleState; | |
| 10 | +import io.netty.handler.timeout.IdleStateEvent; | |
| 11 | +import org.slf4j.Logger; | |
| 12 | +import org.slf4j.LoggerFactory; | |
| 13 | + | |
| 14 | +/** | |
| 15 | + * @author QingtaiJiang | |
| 16 | + * @date 2023/4/27 18:14 | |
| 17 | + * @email qingtaij@163.com | |
| 18 | + */ | |
| 19 | +public class Jt808Handler extends ChannelInboundHandlerAdapter { | |
| 20 | + | |
| 21 | + private final static Logger log = LoggerFactory.getLogger(Jt808Handler.class); | |
| 22 | + | |
| 23 | + @Override | |
| 24 | + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { | |
| 25 | + if (msg instanceof Rs) { | |
| 26 | + ctx.writeAndFlush(msg); | |
| 27 | + } else { | |
| 28 | + ctx.fireChannelRead(msg); | |
| 29 | + } | |
| 30 | + } | |
| 31 | + | |
| 32 | + @Override | |
| 33 | + public void channelActive(ChannelHandlerContext ctx) { | |
| 34 | + Channel channel = ctx.channel(); | |
| 35 | + Session session = SessionManager.INSTANCE.newSession(channel); | |
| 36 | + channel.attr(Session.KEY).set(session); | |
| 37 | + log.info("> Tcp connect {}", session); | |
| 38 | + } | |
| 39 | + | |
| 40 | + @Override | |
| 41 | + public void channelInactive(ChannelHandlerContext ctx) { | |
| 42 | + Session session = ctx.channel().attr(Session.KEY).get(); | |
| 43 | + log.info("< Tcp disconnect {}", session); | |
| 44 | + ctx.close(); | |
| 45 | + } | |
| 46 | + | |
| 47 | + @Override | |
| 48 | + public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) { | |
| 49 | + Session session = ctx.channel().attr(Session.KEY).get(); | |
| 50 | + String message = e.getMessage(); | |
| 51 | + if (message.toLowerCase().contains("Connection reset by peer".toLowerCase())) { | |
| 52 | + log.info("< exception{} {}", session, e.getMessage()); | |
| 53 | + } else { | |
| 54 | + log.info("< exception{} {}", session, e.getMessage(), e); | |
| 55 | + } | |
| 56 | + | |
| 57 | + } | |
| 58 | + | |
| 59 | + @Override | |
| 60 | + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { | |
| 61 | + if (evt instanceof IdleStateEvent) { | |
| 62 | + IdleStateEvent event = (IdleStateEvent) evt; | |
| 63 | + IdleState state = event.state(); | |
| 64 | + if (state == IdleState.READER_IDLE || state == IdleState.WRITER_IDLE) { | |
| 65 | + Session session = ctx.channel().attr(Session.KEY).get(); | |
| 66 | + log.warn("< Proactively disconnect{}", session); | |
| 67 | + ctx.close(); | |
| 68 | + } | |
| 69 | + } | |
| 70 | + } | |
| 71 | + | |
| 72 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/jt1078/codec/netty/TcpServer.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.jt1078.codec.netty; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.jt1078.codec.decode.Jt808Decoder; | |
| 4 | +import com.genersoft.iot.vmp.jt1078.codec.encode.Jt808Encoder; | |
| 5 | +import com.genersoft.iot.vmp.jt1078.codec.encode.Jt808EncoderCmd; | |
| 6 | +import com.genersoft.iot.vmp.jt1078.proc.factory.CodecFactory; | |
| 7 | +import io.netty.bootstrap.ServerBootstrap; | |
| 8 | +import io.netty.buffer.ByteBuf; | |
| 9 | +import io.netty.buffer.Unpooled; | |
| 10 | +import io.netty.channel.ChannelFuture; | |
| 11 | +import io.netty.channel.ChannelInitializer; | |
| 12 | +import io.netty.channel.EventLoopGroup; | |
| 13 | +import io.netty.channel.nio.NioEventLoopGroup; | |
| 14 | +import io.netty.channel.socket.nio.NioChannelOption; | |
| 15 | +import io.netty.channel.socket.nio.NioServerSocketChannel; | |
| 16 | +import io.netty.channel.socket.nio.NioSocketChannel; | |
| 17 | +import io.netty.handler.codec.DelimiterBasedFrameDecoder; | |
| 18 | +import io.netty.handler.timeout.IdleStateHandler; | |
| 19 | +import io.netty.util.concurrent.Future; | |
| 20 | +import org.slf4j.Logger; | |
| 21 | +import org.slf4j.LoggerFactory; | |
| 22 | + | |
| 23 | +import java.util.concurrent.TimeUnit; | |
| 24 | + | |
| 25 | +/** | |
| 26 | + * @author QingtaiJiang | |
| 27 | + * @date 2023/4/27 18:01 | |
| 28 | + * @email qingtaij@163.com | |
| 29 | + */ | |
| 30 | + | |
| 31 | +public class TcpServer { | |
| 32 | + private final static Logger log = LoggerFactory.getLogger(TcpServer.class); | |
| 33 | + | |
| 34 | + private final Integer port; | |
| 35 | + private boolean isRunning = false; | |
| 36 | + private EventLoopGroup bossGroup = null; | |
| 37 | + private EventLoopGroup workerGroup = null; | |
| 38 | + | |
| 39 | + private final ByteBuf DECODER_JT808 = Unpooled.wrappedBuffer(new byte[]{0x7e}); | |
| 40 | + | |
| 41 | + public TcpServer(Integer port) { | |
| 42 | + this.port = port; | |
| 43 | + } | |
| 44 | + | |
| 45 | + private void startTcpServer() { | |
| 46 | + try { | |
| 47 | + CodecFactory.init(); | |
| 48 | + this.bossGroup = new NioEventLoopGroup(); | |
| 49 | + this.workerGroup = new NioEventLoopGroup(); | |
| 50 | + ServerBootstrap bootstrap = new ServerBootstrap(); | |
| 51 | + bootstrap.channel(NioServerSocketChannel.class); | |
| 52 | + bootstrap.group(bossGroup, workerGroup); | |
| 53 | + | |
| 54 | + bootstrap.option(NioChannelOption.SO_BACKLOG, 1024) | |
| 55 | + .option(NioChannelOption.SO_REUSEADDR, true) | |
| 56 | + .childOption(NioChannelOption.TCP_NODELAY, true) | |
| 57 | + .childHandler(new ChannelInitializer<NioSocketChannel>() { | |
| 58 | + @Override | |
| 59 | + public void initChannel(NioSocketChannel channel) { | |
| 60 | + channel.pipeline() | |
| 61 | + .addLast(new IdleStateHandler(10, 0, 0, TimeUnit.MINUTES)) | |
| 62 | + .addLast(new DelimiterBasedFrameDecoder(1024 * 2, DECODER_JT808)) | |
| 63 | + .addLast(new Jt808Decoder()) | |
| 64 | + .addLast(new Jt808Encoder()) | |
| 65 | + .addLast(new Jt808EncoderCmd()) | |
| 66 | + .addLast(new Jt808Handler()); | |
| 67 | + } | |
| 68 | + }); | |
| 69 | + ChannelFuture channelFuture = bootstrap.bind(port).sync(); | |
| 70 | + // 监听设备TCP端口是否启动成功 | |
| 71 | + channelFuture.addListener(future -> { | |
| 72 | + if (!future.isSuccess()) { | |
| 73 | + log.error("Binding port:{} fail! cause: {}", port, future.cause().getCause(), future.cause()); | |
| 74 | + } | |
| 75 | + }); | |
| 76 | + log.info("服务:JT808 Server 启动成功, port:{}", port); | |
| 77 | + channelFuture.channel().closeFuture().sync(); | |
| 78 | + } catch (Exception e) { | |
| 79 | + log.warn("服务:JT808 Server 启动异常, port:{},{}", port, e.getMessage(), e); | |
| 80 | + } finally { | |
| 81 | + stop(); | |
| 82 | + } | |
| 83 | + } | |
| 84 | + | |
| 85 | + /** | |
| 86 | + * 开启一个新的线程,拉起来Netty | |
| 87 | + */ | |
| 88 | + public synchronized void start() { | |
| 89 | + if (this.isRunning) { | |
| 90 | + log.warn("服务:JT808 Server 已经启动, port:{}", port); | |
| 91 | + return; | |
| 92 | + } | |
| 93 | + this.isRunning = true; | |
| 94 | + new Thread(this::startTcpServer).start(); | |
| 95 | + } | |
| 96 | + | |
| 97 | + public synchronized void stop() { | |
| 98 | + if (!this.isRunning) { | |
| 99 | + log.warn("服务:JT808 Server 已经停止, port:{}", port); | |
| 100 | + } | |
| 101 | + this.isRunning = false; | |
| 102 | + Future<?> future = this.bossGroup.shutdownGracefully(); | |
| 103 | + if (!future.isSuccess()) { | |
| 104 | + log.warn("bossGroup 无法正常停止", future.cause()); | |
| 105 | + } | |
| 106 | + future = this.workerGroup.shutdownGracefully(); | |
| 107 | + if (!future.isSuccess()) { | |
| 108 | + log.warn("workerGroup 无法正常停止", future.cause()); | |
| 109 | + } | |
| 110 | + log.warn("服务:JT808 Server 已经停止, port:{}", port); | |
| 111 | + } | |
| 112 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/jt1078/config/JT1078AutoConfiguration.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.jt1078.config; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.jt1078.cmd.JT1078Template; | |
| 4 | +import com.genersoft.iot.vmp.jt1078.codec.netty.TcpServer; | |
| 5 | +import org.springframework.beans.factory.annotation.Value; | |
| 6 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |
| 7 | +import org.springframework.context.annotation.Bean; | |
| 8 | +import org.springframework.context.annotation.Configuration; | |
| 9 | +import org.springframework.core.annotation.Order; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * @author QingtaiJiang | |
| 13 | + * @date 2023/4/27 19:35 | |
| 14 | + * @email qingtaij@163.com | |
| 15 | + */ | |
| 16 | +@Order(Integer.MIN_VALUE) | |
| 17 | +@Configuration | |
| 18 | +@ConditionalOnProperty(value = "jt1078.enable", havingValue = "true") | |
| 19 | +public class JT1078AutoConfiguration { | |
| 20 | + | |
| 21 | + @Bean(initMethod = "start", destroyMethod = "stop") | |
| 22 | + public TcpServer jt1078Server(@Value("${jt1078.port}") Integer port) { | |
| 23 | + return new TcpServer(port); | |
| 24 | + } | |
| 25 | + | |
| 26 | + @Bean | |
| 27 | + public JT1078Template jt1078Template() { | |
| 28 | + return new JT1078Template(); | |
| 29 | + } | |
| 30 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/jt1078/config/JT1078Controller.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.jt1078.config; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.jt1078.cmd.JT1078Template; | |
| 4 | +import com.genersoft.iot.vmp.jt1078.proc.response.*; | |
| 5 | +import com.genersoft.iot.vmp.vmanager.bean.WVPResult; | |
| 6 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |
| 7 | +import org.springframework.web.bind.annotation.GetMapping; | |
| 8 | +import org.springframework.web.bind.annotation.PathVariable; | |
| 9 | +import org.springframework.web.bind.annotation.RequestMapping; | |
| 10 | +import org.springframework.web.bind.annotation.RestController; | |
| 11 | + | |
| 12 | +import javax.annotation.Resource; | |
| 13 | + | |
| 14 | +/** | |
| 15 | + * curl http://localhost:18080/api/jt1078/start/live/18864197066/1 | |
| 16 | + * | |
| 17 | + * @author QingtaiJiang | |
| 18 | + * @date 2023/4/27 18:12 | |
| 19 | + * @email qingtaij@163.com | |
| 20 | + */ | |
| 21 | +@ConditionalOnProperty(value = "jt1078.enable", havingValue = "true") | |
| 22 | +@RestController | |
| 23 | +@RequestMapping("/api/jt1078") | |
| 24 | +public class JT1078Controller { | |
| 25 | + | |
| 26 | + @Resource | |
| 27 | + JT1078Template jt1078Template; | |
| 28 | + | |
| 29 | + /** | |
| 30 | + * jt1078Template 调用示例 | |
| 31 | + */ | |
| 32 | + @GetMapping("/start/live/{deviceId}/{channelId}") | |
| 33 | + public WVPResult<?> startLive(@PathVariable String deviceId, @PathVariable String channelId) { | |
| 34 | + J9101 j9101 = new J9101(); | |
| 35 | + j9101.setChannel(Integer.valueOf(channelId)); | |
| 36 | + j9101.setIp("192.168.1.1"); | |
| 37 | + j9101.setRate(1); | |
| 38 | + j9101.setTcpPort(7618); | |
| 39 | + j9101.setUdpPort(7618); | |
| 40 | + j9101.setType(0); | |
| 41 | + // TODO 分配ZLM,获取IP、端口 | |
| 42 | + String s = jt1078Template.startLive(deviceId, j9101, 6); | |
| 43 | + // TODO 设备响应成功后,封装拉流结果集 | |
| 44 | + WVPResult<String> wvpResult = new WVPResult<>(); | |
| 45 | + wvpResult.setCode(200); | |
| 46 | + wvpResult.setData(String.format("http://192.168.1.1/rtp/%s_%s.live.mp4", deviceId, channelId)); | |
| 47 | + return wvpResult; | |
| 48 | + } | |
| 49 | + | |
| 50 | +} | |
| 51 | + | ... | ... |
src/main/java/com/genersoft/iot/vmp/jt1078/proc/Header.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.jt1078.proc; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.jt1078.util.Bin; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * @author QingtaiJiang | |
| 7 | + * @date 2023/4/27 18:22 | |
| 8 | + * @email qingtaij@163.com | |
| 9 | + */ | |
| 10 | +public class Header { | |
| 11 | + // 消息ID | |
| 12 | + String msgId; | |
| 13 | + | |
| 14 | + // 消息体属性 | |
| 15 | + Integer msgPro; | |
| 16 | + | |
| 17 | + // 标识 | |
| 18 | + String devId; | |
| 19 | + | |
| 20 | + // 消息体流水号 | |
| 21 | + Integer sn; | |
| 22 | + | |
| 23 | + // 协议版本号 | |
| 24 | + Short version = -1; | |
| 25 | + | |
| 26 | + | |
| 27 | + public String getMsgId() { | |
| 28 | + return msgId; | |
| 29 | + } | |
| 30 | + | |
| 31 | + public void setMsgId(String msgId) { | |
| 32 | + this.msgId = msgId; | |
| 33 | + } | |
| 34 | + | |
| 35 | + public Integer getMsgPro() { | |
| 36 | + return msgPro; | |
| 37 | + } | |
| 38 | + | |
| 39 | + public void setMsgPro(Integer msgPro) { | |
| 40 | + this.msgPro = msgPro; | |
| 41 | + } | |
| 42 | + | |
| 43 | + public String getDevId() { | |
| 44 | + return devId; | |
| 45 | + } | |
| 46 | + | |
| 47 | + public void setDevId(String devId) { | |
| 48 | + this.devId = devId; | |
| 49 | + } | |
| 50 | + | |
| 51 | + public Integer getSn() { | |
| 52 | + return sn; | |
| 53 | + } | |
| 54 | + | |
| 55 | + public void setSn(Integer sn) { | |
| 56 | + this.sn = sn; | |
| 57 | + } | |
| 58 | + | |
| 59 | + public Short getVersion() { | |
| 60 | + return version; | |
| 61 | + } | |
| 62 | + | |
| 63 | + public void setVersion(Short version) { | |
| 64 | + this.version = version; | |
| 65 | + } | |
| 66 | + | |
| 67 | + /** | |
| 68 | + * 判断是否是2019的版本 | |
| 69 | + * | |
| 70 | + * @return true 2019后的版本。false 2013 | |
| 71 | + */ | |
| 72 | + public boolean is2019Version() { | |
| 73 | + return Bin.get(msgPro, 14); | |
| 74 | + } | |
| 75 | + | |
| 76 | +} | ... | ... |