151 lines
4.4 KiB
TypeScript
151 lines
4.4 KiB
TypeScript
import type {
|
|
ChadSocket,
|
|
ClientToServerEvents,
|
|
ExtractCallbackPayload,
|
|
SocketServer,
|
|
} from '../types/socket.ts'
|
|
import { consola } from 'consola'
|
|
import { channelPublicSelect } from '../dto/channel.dto.ts'
|
|
import prisma from '../prisma/client.ts'
|
|
import { socketToClient } from '../utils/socket-to-client.ts'
|
|
|
|
export default async function (io: SocketServer, socket: ChadSocket) {
|
|
// io.on('channel:join', async (cb) => {
|
|
// if (socket.data.joined) {
|
|
// consola.error('[WebRtc]', 'Already joined')
|
|
// cb({ error: 'Already joined' })
|
|
// return
|
|
// }
|
|
//
|
|
// socket.data.joined = true
|
|
// socket.data.rtpCapabilities = rtpCapabilities
|
|
//
|
|
// // Get current channel from Socket.IO rooms
|
|
// const currentChannelId = Array.from(socket.rooms).find(room => room !== socket.id) || 'default'
|
|
// const joinedSockets = await getJoinedSockets(socket.id, currentChannelId)
|
|
//
|
|
// cb(joinedSockets.map(socketToClient))
|
|
//
|
|
// for (const joinedSocket of joinedSockets) {
|
|
// for (const producer of joinedSocket.data.producers.values()) {
|
|
// createConsumer(
|
|
// socket,
|
|
// joinedSocket,
|
|
// producer,
|
|
// )
|
|
// }
|
|
// }
|
|
//
|
|
// // Broadcast only to same channel using Socket.IO room
|
|
// socket.to(currentChannelId).emit('newPeer', socketToClient(socket))
|
|
// })
|
|
|
|
socket.on('channel:join', async ({ channelId }, cb) => {
|
|
try {
|
|
cb(await handleJoin(channelId))
|
|
}
|
|
catch (e) {
|
|
cb(e)
|
|
}
|
|
})
|
|
|
|
await handleJoin('default')
|
|
|
|
const channels = await prisma.channel.findMany({
|
|
select: channelPublicSelect,
|
|
orderBy: { name: 'asc' },
|
|
})
|
|
|
|
type ChannelJoinCallback = ExtractCallbackPayload<ClientToServerEvents['channel:join']>
|
|
async function handleJoin(channelId: string): Promise<ChannelJoinCallback> {
|
|
try {
|
|
const channel = await prisma.channel.findUnique({
|
|
where: { id: channelId },
|
|
select: channelPublicSelect,
|
|
})
|
|
|
|
if (!channel) {
|
|
return { error: 'Channel not found' }
|
|
}
|
|
|
|
if (channel.maxClients) {
|
|
const socketsInChannel = await io.in(channelId).fetchSockets()
|
|
if (socketsInChannel.length >= channel.maxClients) {
|
|
return { error: 'Channel is full' }
|
|
}
|
|
}
|
|
|
|
const oldChannelId = Array.from(socket.rooms).find(room => room !== socket.id)
|
|
|
|
// for (const producer of socket.data.producers.values()) {
|
|
// producer.close()
|
|
// }
|
|
// socket.data.producers.clear()
|
|
//
|
|
// for (const consumer of socket.data.consumers.values()) {
|
|
// consumer.close()
|
|
// }
|
|
// socket.data.consumers.clear()
|
|
|
|
if (oldChannelId) {
|
|
await socket.leave(oldChannelId)
|
|
io.emit('channel:user-left', { channelId: oldChannelId, clientId: socket.id })
|
|
|
|
// // Auto-delete non-persistent empty channels
|
|
// if (isLeavingNonPersistentChannel) {
|
|
// const oldChannelSockets = await io.in(oldChannelId).fetchSockets()
|
|
//
|
|
// if (oldChannelSockets.length === 0) {
|
|
// const oldChannel = await prisma.channel.findUnique({
|
|
// where: { id: oldChannelId },
|
|
// select: { persistent: true, id: true },
|
|
// })
|
|
//
|
|
// if (oldChannel && !oldChannel.persistent) {
|
|
// await prisma.channel.delete({ where: { id: oldChannelId } })
|
|
// io.emit('channelDeleted', { channelId: oldChannelId })
|
|
// consola.info('[Channel]', `Auto-deleted empty non-persistent channel: ${oldChannelId}`)
|
|
// }
|
|
// }
|
|
// }
|
|
}
|
|
|
|
await socket.join(channelId)
|
|
|
|
// Get new channel members
|
|
// const newChannelSockets = await getJoinedSockets(socket.id, channelId)
|
|
//
|
|
// // Create consumers for existing producers in new channel
|
|
// for (const peer of newChannelSockets) {
|
|
// for (const producer of peer.data.producers.values()) {
|
|
// createConsumer(socket, peer, producer)
|
|
// }
|
|
// }
|
|
|
|
io.emit('channel:user-joined', {
|
|
channelId,
|
|
client: socketToClient(socket),
|
|
})
|
|
|
|
return {
|
|
channel,
|
|
clients: newChannelSockets.map(socketToClient),
|
|
}
|
|
}
|
|
catch (error) {
|
|
consola.error('[channel:join]', error)
|
|
|
|
if (error instanceof Error) {
|
|
return { error: error.message }
|
|
}
|
|
else {
|
|
return { error: 'Something went wrong' }
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
channels,
|
|
}
|
|
}
|