mediasoup-cluster横向扩容机制
最佳答案 问答题库638位专家为你答疑解惑
基于mediasoup实现类似RTMP-CDN的回源机制,从而实现cluster-node的横向扩容。
mediasoup worker实现了PipeTransport机制。
pipeTransport代表了一个RTP通信对,可以实现同一台机器或者多台机器之间的通信。
A pipe transport represents a network path through which RTP, RTCP (optionally secured with SRTP) and SCTP (DataChannel) is transmitted.
Pipe transports are intented to intercommunicate two Router instances collocated on the same host or on separate hosts.
基于这个机制,可以实现从源节点pipe video到多个不同edge节点的功能。
源节点作为socket server工作,等候edgeNode连接请求。
function OriginSvrListener (ioSvr) {
ioSvr.on('connection', (socket) => {
socket.routerIds = new Map()
viewerEndpoints.set(socket.id, socket)
roomList.forEach(async (room) => {
const roomId = room.id
//向edgenode请求用作pipe的routerId。
const { remoteRouterId } = await socket.emit('getRemoteRouterInfo', { roomId })
//建立本地room与多个edgenode的映射表
socket.routerIds.set(roomId, remoteRouterId)
//获得本地producers,然后pipe to remote router.
const producers = room.getProducers()
producers.forEach(({ producer, router }) => {
room.pipeToRemoteRouter({ router, remoteRouterId, roomId, producer, socket })
})
})
})
}
边缘节点作为socket client工作。
async function edgeSocketClient (params = { channelName: undefined, arrBroadcasterAddr: [] }) {
let broadcasterAddr = arrBroadcasterAddr[0] + config.NAMESPACE
const edgeSocket = ioClient.connect(broadcasterAddr, { transports: ['websocket'] })
edgeSocket.on('createRemotePipeTransport', async ({ roomId, routerId }, callback) => {
const params = await room.createRemotePipeTransport({ routerId })
})
edgeSocket.on('connectRemotePipeTransport', async ({ roomId, routerId, ip, port, srtpParameters }) => {
const remotePipeTransport = room.pipe.transports.get(routerId)
await remotePipeTransport.connect({ ip, port, srtpParameters })
})
//响应源节点要求创建pipeProducer
edgeSocket.on('createPipeProducer', async ({ roomId, routerId, id, kind, rtpParameters, paused, appData }) => {
await room.createPipeProducer({ routerId, id, kind, rtpParameters, paused, appData, edgeSocket })
})
//响应源节点要求创建room
edgeSocket.on('getRemoteRouterInfo', async ({ roomId }, callback = doNothing) => {
let room = roomList.get(roomId)
try {
if (!room) {
room = await createRoom({ roomId })
}
response.remoteRouterId = room.getPrimaryRouterId()
callback(response)
} catch (error) {
console.error(error.stack || error.toString())
response.error = error
callback(response)
}
})
}
mediasoup提供关键函数。//注释里的本地指originNode, 对端指edgeNode。
async pipeToRemoteRouter ({ socket, router, remoteRouterId, roomId, producer }) {
try {
pipeTransportPairPromise = new Promise((resolve, reject) => {
Promise.all([
//本地创建pipeTransport
router.createPipeTransport({...config.mediasoup.pipeTransport, listenIp:config.GetWebrtcListenIP()}),
//通知对端创建pipeTransport
socket.promisedEmit('createRemotePipeTransport', {roomId, routerId: router.id}) ])
.then((pipeTransports) => {
localPipeTransport = pipeTransports[0]
remotePipeTransport = pipeTransports[1]
})
.then(() => {
return Promise.all([
//本地pipeTransport进行连接
localPipeTransport.connect({
ip: remotePipeTransport.tuple.localIp,
port: remotePipeTransport.tuple.localPort,
srtpParameters: remotePipeTransport.srtpParameters
}),
//通知对端进行pipeTransport连接。
socket.emit('connectRemotePipeTransport', {
roomId,
routerId: router.id,
ip: localPipeTransport.tuple.localIp,
port: localPipeTransport.tuple.localPort,
srtpParameters: localPipeTransport.srtpParameters
})
]).catch((error) => { throw error })
})
})
}
let pipeConsumer
try {
//pipeConsumer的消费对象是本地的producer。
pipeConsumer = await localPipeTransport.consume({
producerId: producer.id
})
//向对端发出创建pipeProducer的event。edgeNode作为producer工作。pipe传输时,consumer与producer角色是反的。
socket.emit('createPipeProducer', {
roomId,
routerId: router.id,
id: producer.id,
kind: pipeConsumer.kind,
rtpParameters: pipeConsumer.rtpParameters,
paused: pipeConsumer.producerPaused,
appData: producer.appData
})
return { pipeConsumer }
} catch (error) {
throw error
}
} catch (error) {
console.error(error.stack || error.toString())
}
}
测试过程:
[17:20:08.077] [DEBUG] [pid:2385785}] [server/app.js:1479] - edge-EP received event: getRemoteRouterInfo
[17:20:08.079] [DEBUG] [pid:2385785}] [server/app.js:1404] - edge-EP received event: createRemotePipeTransport
[17:20:08.080] [DEBUG] [pid:2385785}] [server/app.js:1419] - edge-EP received event: connectRemotePipeTransport
[17:20:08.081] [DEBUG] [pid:2385785}] [server/app.js:1424] - remotePipeTransport connected {"room":"ch-11","broadcaster":{"ip":"122.248.233.61","port":10304}}
[17:20:08.082] [DEBUG] [pid:2385785}] [server/app.js:1448] - edge-EP received event: createPipeProducer
[17:20:08.083] [INFO] [pid:2385785}] [server/Room.js:629] - {"event":"createPipeProducer","name":"xiaoming","room":"ch-11","kind":"audio","codec":{"mimeType":"audio/opus","clockRate":48000,"channels":2,"payloadType":100,"parameters":{"minptime":10,"sprop-stereo":1,"usedtx":1,"useinbandfec":1}}}
[17:20:08.083] [DEBUG] [pid:2385785}] [server/Room.js:648] - pipeProducer created. broadcasting newProducers to ms-worker thread.
[17:20:08.130] [DEBUG] [pid:2385785}] [server/app.js:1479] - edge-EP received event: getRemoteRouterInfo
[17:20:08.132] [DEBUG] [pid:2385785}] [server/app.js:1448] - edge-EP received event: createPipeProducer
[17:20:08.132] [INFO] [pid:2385785}] [server/Room.js:629] - {"event":"createPipeProducer","name":"Greg","room":"ch-11","kind":"video","codec":{"mimeType":"video/h264","clockRate":90000,"payloadType":105,"parameters":{"packetizationMode":1,"profileLevelId":"42e01f"}}}
参考文档:https://mediasoup.org/documentation/v3/mediasoup/api/#PipeTransportOptions
99%的人还看了
相似问题
- 〖大前端 - 基础入门三大核心之JS篇㊲〗- DOM改变元素节点的css样式、HTML属性
- Java 算法篇-链表的经典算法:判断回文链表、判断环链表与寻找环入口节点(“龟兔赛跑“算法实现)
- 代码随想录二刷 | 链表 | 删除链表的倒数第N个节点
- 节点导纳矩阵
- bhosts 显示节点 “unreach“ 状态
- 电子电器架构 —— 车载网关边缘节点总线转换
- 〖大前端 - 基础入门三大核心之JS篇㊳〗- DOM访问元素节点
- 第四天||24. 两两交换链表中的节点 ● 19.删除链表的倒数第N个节点 ● 面试题 02.07. 链表相交 ● 142.环形链表II
- CS224W5.1——消息传递和节点分类
- Vue报错解决Error in v-on handler: “Error: 无效的节点选择器:#div1“
猜你感兴趣
版权申明
本文"mediasoup-cluster横向扩容机制":http://eshow365.cn/6-32970-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!