|
|
@@ -1,6 +1,7 @@
|
|
|
package com.jttserver.service.publisher;
|
|
|
|
|
|
import com.jttserver.relay.StreamRelay;
|
|
|
+import com.jttserver.utils.CommUtils;
|
|
|
|
|
|
import java.net.InetSocketAddress;
|
|
|
import java.util.ArrayList;
|
|
|
@@ -51,9 +52,11 @@ public class WebsockServer extends PublishServer {
|
|
|
}
|
|
|
|
|
|
|
|
|
- // 维护 streamId(sim+logic) 与 原始视频 channelId 的映射(注意是jtt1078设备的ChannelId)
|
|
|
- private final Map<String, String> streamIdToChannelId = new ConcurrentHashMap<>();
|
|
|
- private final Map<String, String> channelIdToStreamId = new ConcurrentHashMap<>();
|
|
|
+ // 维护 streamId(sim+logic) 与 原始视频 channelId 的映射(注意是jtt1078设备的ChannelId),带有路径前缀
|
|
|
+ // streamIdToChannelId key=(streamID,prefix), value=channelId
|
|
|
+ private final Map<CommUtils.InfoItem,String> streamIdToChannelId = new ConcurrentHashMap<>();
|
|
|
+ // channelIdToStreamId key=channelId, value=(streamID,prefix)
|
|
|
+ private final Map<String, CommUtils.InfoItem> channelIdToStreamId = new ConcurrentHashMap<>();
|
|
|
|
|
|
// 订阅数据结构
|
|
|
// 按照streamId 为 key,ChannelGroup(包含多个channel) 为 value
|
|
|
@@ -90,7 +93,7 @@ public class WebsockServer extends PublishServer {
|
|
|
// 使用配置开启前缀匹配,允许 /realtime/{streamId}
|
|
|
ch.pipeline().addLast(new WebSocketServerProtocolHandler(
|
|
|
WebSocketServerProtocolConfig.newBuilder()
|
|
|
- .websocketPath("/realtime")
|
|
|
+ .websocketPath("/")
|
|
|
.subprotocols(null)
|
|
|
.allowExtensions(true)
|
|
|
.checkStartsWith(true)
|
|
|
@@ -169,12 +172,12 @@ public class WebsockServer extends PublishServer {
|
|
|
* 维护 streamId(sim卡号+逻辑通道号) 与 随机 channelId 的对应关系
|
|
|
*/
|
|
|
@Override
|
|
|
- public void mapStreamToChannel(String streamId, String channelId) {
|
|
|
+ public void mapStreamToChannel(String streamId, String channelId, String prefix) {
|
|
|
if (streamId == null || streamId.isEmpty() || channelId == null || channelId.isEmpty()) {
|
|
|
return;
|
|
|
}
|
|
|
- streamIdToChannelId.put(streamId, channelId);
|
|
|
- channelIdToStreamId.put(channelId, streamId);
|
|
|
+ streamIdToChannelId.put(new CommUtils.InfoItem(streamId, prefix), channelId);
|
|
|
+ channelIdToStreamId.put(channelId, new CommUtils.InfoItem(streamId, prefix));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -185,24 +188,24 @@ public class WebsockServer extends PublishServer {
|
|
|
if (channelId == null || channelId.isEmpty()) {
|
|
|
return;
|
|
|
}
|
|
|
- String sid = channelIdToStreamId.remove(channelId);
|
|
|
- if (sid != null) {
|
|
|
- streamIdToChannelId.remove(sid);
|
|
|
+ CommUtils.InfoItem infoItem = channelIdToStreamId.remove(channelId);
|
|
|
+ if (infoItem != null) {
|
|
|
+ streamIdToChannelId.remove(infoItem);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取channelId对应的streamId方法
|
|
|
*/
|
|
|
- public String getStreamIdByChannelId(String channelId) {
|
|
|
+ public CommUtils.InfoItem getStreamIdByChannelId(String channelId) {
|
|
|
return channelIdToStreamId.get(channelId);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取streamId对应的channelId方法
|
|
|
*/
|
|
|
- public String getChannelIdByStreamId(String streamId) {
|
|
|
- return streamIdToChannelId.get(streamId);
|
|
|
+ public String getChannelIdByStreamId(String streamId, String prefix) {
|
|
|
+ return streamIdToChannelId.get(new CommUtils.InfoItem(streamId, prefix));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -261,9 +264,10 @@ public class WebsockServer extends PublishServer {
|
|
|
logger.info("FLVWebSocket 握手完成 - 请求路径: {}, 流ID: {}", uri, streamId);
|
|
|
if (!streamId.isEmpty() && relay != null) {
|
|
|
// 在注册订阅前,初始化发送该类型需要的数据
|
|
|
- String channelId = server.getChannelIdByStreamId(streamId);
|
|
|
-
|
|
|
- relay.initChannelConn(channelId, ctx.channel());
|
|
|
+ String channelId = server.getChannelIdByStreamId(streamId, currPrefix);
|
|
|
+ if (channelId != null && !channelId.isEmpty()) {
|
|
|
+ relay.initChannelConn(channelId, ctx.channel());
|
|
|
+ }
|
|
|
server.registerChannel(streamId, ctx.channel(), relay);
|
|
|
}
|
|
|
}
|
|
|
@@ -300,19 +304,23 @@ public class WebsockServer extends PublishServer {
|
|
|
if (g.isEmpty()) {
|
|
|
streamGroups.remove(sid);
|
|
|
// 移除流与通道映射
|
|
|
- String channelId = getChannelIdByStreamId(sid);
|
|
|
- if (channelId != null) {
|
|
|
+ StreamRelay relay = channelRelayMap.remove(ch.id());
|
|
|
+ String currPrefix = relay.getPrefix();
|
|
|
+ // 获取recv服务器的对应channelId
|
|
|
+ String channelId = getChannelIdByStreamId(sid, currPrefix);
|
|
|
+ if (channelId != null && !channelId.isEmpty()) {
|
|
|
logger.info("流 {} 已无订阅者,channel已移除{}", sid, channelId);
|
|
|
|
|
|
// destroy
|
|
|
- StreamRelay relay = channelRelayMap.remove(ch.id());
|
|
|
+
|
|
|
if (relay != null) {
|
|
|
relay.destroyChannelDisconn(channelId);
|
|
|
}
|
|
|
-
|
|
|
// 移除通道与流映射
|
|
|
removeChannelMapping(channelId);
|
|
|
|
|
|
+ }else {
|
|
|
+ logger.warn("无对应的channelId,无需关闭视频通道,streamId: {}, prefix: {}", sid, currPrefix);
|
|
|
}
|
|
|
}
|
|
|
}
|