mediasoup-cluster横向扩容机制

基于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 = arrBroadcasterAddr0 + 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 = pipeTransports0

remotePipeTransport = pipeTransports1

})

.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

相关推荐
草根大哥5 小时前
08-横向扩容与突发高并发:加机器到底买到了什么
运维·webrtc·srt·横向扩容·whip·自建cdn
zhoupenghui16821 天前
Redis 集群的安装配置与服务交互
redis·cluster·redis集群
@大吉7 个月前
【思维导图】一图了解WebRTC通信流程,以及SFU和MediaSoup
webrtc·mediasoup
没有bug.的程序员8 个月前
分布式缓存深潜:Redis Cluster 物理内核、数据分片算法博弈与高并发实战指南
redis·分布式·缓存·高并发·cluster·数据分片
短剑重铸之日9 个月前
《7天学会Redis》Day 5 - Redis Cluster集群架构
数据库·redis·后端·缓存·架构·cluster
李昊哲小课1 年前
Ubuntu 24.04 安装开源WebRTC信令服务器
服务器·ubuntu·mediasoup·janus·信令服务器
鼠鼠我捏,要死了捏1 年前
Redis 集群模式读写分离与分片策略方案对比分析与实践指南
redis·cache·cluster
helloyaren1 年前
Docker Desktop里搭建Redis 8.2.1集群的保姆级教程
redis·学习·集群·cluster
中草药z1 年前
【Redis】哨兵机制和集群
数据库·redis·缓存·集群·cluster·哨兵·数据分区算法
XingYuyu_Coder2 年前
企业级NoSQL数据库Redis
redis·sentinel·cluster·主从复制