97 lines
2.9 KiB
TypeScript
97 lines
2.9 KiB
TypeScript
import type { FastifyInstance } from 'fastify'
|
|
import { consola } from 'consola'
|
|
import { Channel } from './Channel.ts'
|
|
import { ChannelManager } from './ChannelManager.ts'
|
|
import { Client } from './Client.ts'
|
|
import { WebRtcGateway } from './Gateway.ts'
|
|
|
|
export default async function (fastify: FastifyInstance) {
|
|
const { io, bus, mediasoupRouter, prisma } = fastify
|
|
|
|
const channels = new ChannelManager(mediasoupRouter)
|
|
|
|
const dbChannels = await prisma.channel.findMany()
|
|
|
|
for (const dbChannel of dbChannels) {
|
|
const channel = await Channel.create(dbChannel.id, dbChannel.persistent, mediasoupRouter)
|
|
channels.create(channel)
|
|
setupChannelEvents(channel)
|
|
}
|
|
|
|
const defaultChannel = channels.get('default')!
|
|
|
|
io.on('connection', async (socket) => {
|
|
consola.info('[WebRtc]', 'Client connected', socket.id)
|
|
|
|
const client = new Client(socket.id, socket.data.user.username, mediasoupRouter)
|
|
|
|
defaultChannel.addClient(client)
|
|
socket.join(defaultChannel.id)
|
|
|
|
const _gateway = new WebRtcGateway(io, socket, client, channels)
|
|
|
|
socket.emit('initialized', {
|
|
rtpCapabilities: mediasoupRouter.rtpCapabilities,
|
|
channelId: client.channelId,
|
|
clients: channels.all.flatMap(c => c.clients).map(c => c.serialize()),
|
|
})
|
|
|
|
socket.broadcast.emit('new-client', client.serialize())
|
|
})
|
|
|
|
bus.on('channel:created', async (dbChannel) => {
|
|
io.emit('channel-created', dbChannel)
|
|
|
|
const channel = await Channel.create(dbChannel.id, dbChannel.persistent, mediasoupRouter)
|
|
|
|
channels.create(channel)
|
|
setupChannelEvents(channel)
|
|
})
|
|
|
|
bus.on('channel:removed', async (dbChannel) => {
|
|
io.emit('channel-removed', dbChannel.id)
|
|
|
|
const channel = channels.get(dbChannel.id)
|
|
|
|
if (!channel)
|
|
return
|
|
|
|
for (const client of channel.clients) {
|
|
channel.unwireClient(client)
|
|
client.clearConsumers()
|
|
|
|
const socket = io.sockets.sockets.get(client.socketId)
|
|
if (socket) {
|
|
socket.leave(dbChannel.id)
|
|
defaultChannel.addClient(client)
|
|
socket.join(defaultChannel.id)
|
|
await defaultChannel.wireClient(client)
|
|
io.emit('client-switched-channel', client.serialize())
|
|
}
|
|
}
|
|
|
|
channels.delete(dbChannel.id)
|
|
})
|
|
|
|
function setupChannelEvents(channel: Channel): void {
|
|
channel.on('speaking-peers', peers => io.to(channel.id).emit('speaking-clients', peers))
|
|
|
|
channel.on('silence', () => {
|
|
io.to(channel.id).emit('speaking-clients', [])
|
|
io.to(channel.id).emit('active-speaker', undefined)
|
|
})
|
|
|
|
channel.on('active-speaker', socketId => io.to(channel.id).emit('active-speaker', socketId))
|
|
|
|
channel.on('empty', async () => {
|
|
if (channel.persistent)
|
|
return
|
|
|
|
channels.delete(channel.id)
|
|
await prisma.channel.delete({ where: { id: channel.id } })
|
|
consola.info('[WebRtc]', `Non-persistent channel "${channel.id}" deleted`)
|
|
io.emit('channel-removed', channel.id)
|
|
})
|
|
}
|
|
}
|