Commit d67f0a1ea403fbebfff70e7eaf4fe4870be2a1b8
1 parent
874a5738
解决使用redis集群时获取发送端口失败的问题
Showing
2 changed files
with
58 additions
and
15 deletions
src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java
| ... | ... | @@ -30,7 +30,7 @@ public class SendRtpPortManager { |
| 30 | 30 | |
| 31 | 31 | private final String KEY = "VM_MEDIA_SEND_RTP_PORT_"; |
| 32 | 32 | |
| 33 | - public int getNextPort(MediaServerItem mediaServer) { | |
| 33 | + public synchronized int getNextPort(MediaServerItem mediaServer) { | |
| 34 | 34 | if (mediaServer == null) { |
| 35 | 35 | logger.warn("[发送端口管理] 参数错误,mediaServer为NULL"); |
| 36 | 36 | return -1; |
| ... | ... | @@ -50,17 +50,15 @@ public class SendRtpPortManager { |
| 50 | 50 | String sendRtpPortRange = mediaServer.getSendRtpPortRange(); |
| 51 | 51 | int startPort; |
| 52 | 52 | int endPort; |
| 53 | - if (sendRtpPortRange == null) { | |
| 54 | - logger.warn("{}未设置发送端口默认值,自动使用40000-50000作为端口范围", mediaServer.getId()); | |
| 53 | + if (sendRtpPortRange != null) { | |
| 55 | 54 | String[] portArray = sendRtpPortRange.split(","); |
| 56 | 55 | if (portArray.length != 2 || !NumberUtils.isParsable(portArray[0]) || !NumberUtils.isParsable(portArray[1])) { |
| 57 | - logger.warn("{}发送端口配置格式错误,自动使用40000-50000作为端口范围", mediaServer.getId()); | |
| 56 | + logger.warn("{}发送端口配置格式错误,自动使用50000-60000作为端口范围", mediaServer.getId()); | |
| 58 | 57 | startPort = 50000; |
| 59 | 58 | endPort = 60000; |
| 60 | 59 | }else { |
| 61 | - | |
| 62 | 60 | if ( Integer.parseInt(portArray[1]) - Integer.parseInt(portArray[0]) < 1) { |
| 63 | - logger.warn("{}发送端口配置错误,结束端口至少比开始端口大一,自动使用40000-50000作为端口范围", mediaServer.getId()); | |
| 61 | + logger.warn("{}发送端口配置错误,结束端口至少比开始端口大一,自动使用50000-60000作为端口范围", mediaServer.getId()); | |
| 64 | 62 | startPort = 50000; |
| 65 | 63 | endPort = 60000; |
| 66 | 64 | }else { |
| ... | ... | @@ -69,6 +67,7 @@ public class SendRtpPortManager { |
| 69 | 67 | } |
| 70 | 68 | } |
| 71 | 69 | }else { |
| 70 | + logger.warn("{}未设置发送端口默认值,自动使用50000-60000作为端口范围", mediaServer.getId()); | |
| 72 | 71 | startPort = 50000; |
| 73 | 72 | endPort = 60000; |
| 74 | 73 | } |
| ... | ... | @@ -76,10 +75,35 @@ public class SendRtpPortManager { |
| 76 | 75 | logger.warn("{}获取redis连接信息失败", mediaServer.getId()); |
| 77 | 76 | return -1; |
| 78 | 77 | } |
| 78 | +// RedisAtomicInteger redisAtomicInteger = new RedisAtomicInteger(sendIndexKey , redisTemplate.getConnectionFactory()); | |
| 79 | +// return redisAtomicInteger.getAndUpdate((current)->{ | |
| 80 | +// return getPort(current, startPort, endPort, checkPort-> !sendRtpItemMap.containsKey(checkPort)); | |
| 81 | +// }); | |
| 82 | + return getSendPort(startPort, endPort, sendIndexKey, sendRtpItemMap); | |
| 83 | + } | |
| 84 | + | |
| 85 | + private synchronized int getSendPort(int startPort, int endPort, String sendIndexKey, Map<Integer, SendRtpItem> sendRtpItemMap){ | |
| 79 | 86 | RedisAtomicInteger redisAtomicInteger = new RedisAtomicInteger(sendIndexKey , redisTemplate.getConnectionFactory()); |
| 80 | - return redisAtomicInteger.getAndUpdate((current)->{ | |
| 81 | - return getPort(current, startPort, endPort, checkPort-> !sendRtpItemMap.containsKey(checkPort)); | |
| 82 | - }); | |
| 87 | + if (redisAtomicInteger.get() < startPort) { | |
| 88 | + redisAtomicInteger.set(startPort); | |
| 89 | + return startPort; | |
| 90 | + }else { | |
| 91 | + int port = redisAtomicInteger.getAndIncrement(); | |
| 92 | + if (port > endPort) { | |
| 93 | + redisAtomicInteger.set(startPort); | |
| 94 | + if (sendRtpItemMap.containsKey(startPort)) { | |
| 95 | + return getSendPort(startPort, endPort, sendIndexKey, sendRtpItemMap); | |
| 96 | + }else { | |
| 97 | + return startPort; | |
| 98 | + } | |
| 99 | + } | |
| 100 | + if (sendRtpItemMap.containsKey(port)) { | |
| 101 | + return getSendPort(startPort, endPort, sendIndexKey, sendRtpItemMap); | |
| 102 | + }else { | |
| 103 | + return port; | |
| 104 | + } | |
| 105 | + } | |
| 106 | + | |
| 83 | 107 | } |
| 84 | 108 | |
| 85 | 109 | interface CheckPortCallback{ | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java
| ... | ... | @@ -16,7 +16,6 @@ import com.genersoft.iot.vmp.service.IMediaServerService; |
| 16 | 16 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| 17 | 17 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 18 | 18 | import com.genersoft.iot.vmp.vmanager.bean.OtherPsSendInfo; |
| 19 | -import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo; | |
| 20 | 19 | import io.swagger.v3.oas.annotations.Operation; |
| 21 | 20 | import io.swagger.v3.oas.annotations.Parameter; |
| 22 | 21 | import io.swagger.v3.oas.annotations.tags.Tag; |
| ... | ... | @@ -200,9 +199,9 @@ public class PsController { |
| 200 | 199 | callId); |
| 201 | 200 | MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer(); |
| 202 | 201 | String key = VideoManagerConstants.WVP_OTHER_SEND_PS_INFO + userSetting.getServerId() + "_" + callId; |
| 203 | - OtherRtpSendInfo sendInfo = (OtherRtpSendInfo)redisTemplate.opsForValue().get(key); | |
| 202 | + OtherPsSendInfo sendInfo = (OtherPsSendInfo)redisTemplate.opsForValue().get(key); | |
| 204 | 203 | if (sendInfo == null) { |
| 205 | - sendInfo = new OtherRtpSendInfo(); | |
| 204 | + sendInfo = new OtherPsSendInfo(); | |
| 206 | 205 | } |
| 207 | 206 | sendInfo.setPushApp(app); |
| 208 | 207 | sendInfo.setPushStream(stream); |
| ... | ... | @@ -221,7 +220,7 @@ public class PsController { |
| 221 | 220 | param.put("dst_port", dstPort); |
| 222 | 221 | String is_Udp = isUdp ? "1" : "0"; |
| 223 | 222 | param.put("is_udp", is_Udp); |
| 224 | - param.put("src_port", sendInfo.getSendLocalPortForAudio()); | |
| 223 | + param.put("src_port", sendInfo.getSendLocalPort()); | |
| 225 | 224 | param.put("use_ps", "0"); |
| 226 | 225 | param.put("only_audio", "1"); |
| 227 | 226 | |
| ... | ... | @@ -248,7 +247,7 @@ public class PsController { |
| 248 | 247 | }, 10000); |
| 249 | 248 | |
| 250 | 249 | // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 |
| 251 | - OtherRtpSendInfo finalSendInfo = sendInfo; | |
| 250 | + OtherPsSendInfo finalSendInfo = sendInfo; | |
| 252 | 251 | hookSubscribe.removeSubscribe(hookSubscribeForStreamChange); |
| 253 | 252 | hookSubscribe.addSubscribe(hookSubscribeForStreamChange, |
| 254 | 253 | (mediaServerItemInUse, response)->{ |
| ... | ... | @@ -280,7 +279,7 @@ public class PsController { |
| 280 | 279 | public void closeSendRTP(String callId) { |
| 281 | 280 | logger.info("[第三方PS服务对接->关闭发送流] callId->{}", callId); |
| 282 | 281 | String key = VideoManagerConstants.WVP_OTHER_SEND_PS_INFO + userSetting.getServerId() + "_" + callId; |
| 283 | - OtherRtpSendInfo sendInfo = (OtherRtpSendInfo)redisTemplate.opsForValue().get(key); | |
| 282 | + OtherPsSendInfo sendInfo = (OtherPsSendInfo)redisTemplate.opsForValue().get(key); | |
| 284 | 283 | if (sendInfo == null){ |
| 285 | 284 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "未开启发流"); |
| 286 | 285 | } |
| ... | ... | @@ -300,4 +299,24 @@ public class PsController { |
| 300 | 299 | redisTemplate.delete(key); |
| 301 | 300 | } |
| 302 | 301 | |
| 302 | + | |
| 303 | + @GetMapping(value = "/getTestPort") | |
| 304 | + @ResponseBody | |
| 305 | + public int getTestPort() { | |
| 306 | + MediaServerItem defaultMediaServer = mediaServerService.getDefaultMediaServer(); | |
| 307 | + | |
| 308 | +// for (int i = 0; i <300; i++) { | |
| 309 | +// new Thread(() -> { | |
| 310 | +// int nextPort = sendRtpPortManager.getNextPort(defaultMediaServer); | |
| 311 | +// try { | |
| 312 | +// Thread.sleep((int)Math.random()*10); | |
| 313 | +// } catch (InterruptedException e) { | |
| 314 | +// throw new RuntimeException(e); | |
| 315 | +// } | |
| 316 | +// System.out.println(nextPort); | |
| 317 | +// }).start(); | |
| 318 | +// } | |
| 319 | + | |
| 320 | + return sendRtpPortManager.getNextPort(defaultMediaServer); | |
| 321 | + } | |
| 303 | 322 | } | ... | ... |