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 = 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

相关推荐
Shenqi Lotus15 天前
Redis-“自动分片、一定程度的高可用性”(sharding水平拆分、failover故障转移)特性(Sentinel、Cluster)
redis·sentinel·cluster·failover·sharding·自动分片·水平拆分
old-six-programmer4 个月前
深入浅出mediasoup—WebRtcTransport
音视频·webrtc·实时音视频·mediasoup
old-six-programmer4 个月前
深入浅出mediasoup—通信框架
webrtc·mediasoup·libuv
old-six-programmer4 个月前
深入浅出mediasoup—协议交互
webrtc·sdp·mediasoup·ortc
webrtc&ffmpeg_study5 个月前
mediasoup源码分析(二)--worker启动
实时音视频·mediasoup·流媒体服务
webrtc&ffmpeg_study5 个月前
mediasoup源码分析--channel创建及信令交互
实时音视频·mediasoup·流媒体服务
bryant_meng5 个月前
【python】Sklearn—Cluster
开发语言·python·cluster·聚类·sklearn
webrtc&ffmpeg_study6 个月前
mediasoup基础概览
实时音视频·mediasoup·流媒体服务
最笨的羊羊8 个月前
海豚调度系列之:集群部署(Cluster)
cluster·集群部署·海豚调度系列
iini10 个月前
Matter开发,看这一篇就够了
cluster·endpoint·nrf connect sdk·matter开发·matter认证·matter commission·zap使用·dac证书·cd烧写·matter sdk·nrf7002·windows matter开发·matter lock·homepod mini