Mediasoup 관련파일이 3개긴 한데 일단 정리해봅니다.
async function createWorkers() {
let { numWorkers } = config.mediasoup
for (let i = 0; i < numWorkers; i++) {
let worker = await mediasoup.createWorker({
logLevel: config.mediasoup.worker.logLevel,
logTags: config.mediasoup.worker.logTags,
rtcMinPort: config.mediasoup.worker.rtcMinPort,
rtcMaxPort: config.mediasoup.worker.rtcMaxPort
})
worker.on('died', () => {
console.error('mediasoup worker died, exiting in 2 seconds... [pid:%d]', worker.pid)
setTimeout(() => process.exit(1), 2000)
})
workers.push(worker)
}
}
config.mediasoup
에서 사용할 cpu의 갯수를 받음
cpu하나 당 하나의 worker가 생성
io.on('connection', (socket) => {
socket.on('createRoom', async ({ room_id }, callback) => {
if (roomList.has(room_id)) {
callback('already exists')
} else {
console.log('Created room', { room_id: room_id })
let worker = await getMediasoupWorker()
roomList.set(room_id, new Room(room_id, worker, io))
callback(room_id)
}
})
}
socket을 사용하는 이유
실시간 시그널링
양방향 통신이 필요
위의 두개의 특징은 http로 하기 힘듦
Room 관리와 같은 실시간 이벤트 처리가 필요 (참가자 입장/퇴장, 스트림 상태 변경 등)
예제코드에서는 roundRobin
방식으로 워커에 할당 (getMediasoupWorker()함수
)
roomList
에 넣어줌 (Map 자료구조로 되어있음).constructor(room_id, worker, io) {
this.id = room_id
const mediaCodecs = config.mediasoup.router.mediaCodecs
worker
.createRouter({
mediaCodecs
})
.then(
function (router) {
this.router = router
}.bind(this)
)
this.peers = new Map()
this.io = io
}
//config.js
router: {
mediaCodecs: [
{
kind: 'audio',
mimeType: 'audio/opus',
clockRate: 48000,
channels: 2
},
{
kind: 'video',
mimeType: 'video/VP8',
clockRate: 90000,
parameters: {
'x-google-start-bitrate': 1000
}
}
]
},
일반적으로 방마다 하나의 라우터
생성
방 하나에 라우터 여러개도 가능
Room
├── Router1 (Worker1)
├── Router2 (Worker2)
└── Router3 (Worker3)
this.createRoom(room_id).then(
async function () {
await this.join(name, room_id)
this.initSockets()
this._isOpen = true
successCallback()
}.bind(this)
)