X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;ds=sidebyside;f=server%2Flib%2Fpeertube-socket.ts;h=0740e378e6f1d635b75d624d6e458420d75a2c83;hb=1a578165f9112fc2a9ebddea91d2258ebd1f6ae7;hp=1c7b09175720c287c74751a9a9f3042a334bd066;hpb=453e83ea5d81d203ba34bc43cd5c2c750ba40568;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/lib/peertube-socket.ts b/server/lib/peertube-socket.ts index 1c7b09175..0740e378e 100644 --- a/server/lib/peertube-socket.ts +++ b/server/lib/peertube-socket.ts @@ -1,43 +1,92 @@ +import { Server } from 'http' import * as SocketIO from 'socket.io' -import { authenticateSocket } from '../middlewares' +import { MVideo } from '@server/types/models' +import { UserNotificationModelForApi } from '@server/types/models/user' +import { LiveVideoEventPayload, LiveVideoEventType } from '@shared/models' import { logger } from '../helpers/logger' -import { Server } from 'http' -import { UserNotificationModelForApi } from '@server/typings/models/user' +import { authenticateSocket } from '../middlewares' +import { isIdValid } from '@server/helpers/custom-validators/misc' class PeerTubeSocket { private static instance: PeerTubeSocket - private userNotificationSockets: { [ userId: number ]: SocketIO.Socket } = {} + private userNotificationSockets: { [ userId: number ]: SocketIO.Socket[] } = {} + private liveVideosNamespace: SocketIO.Namespace private constructor () {} init (server: Server) { - const io = SocketIO(server) + const io = new SocketIO.Server(server) io.of('/user-notifications') .use(authenticateSocket) .on('connection', socket => { - const userId = socket.handshake.query.user.id + const userId = socket.handshake.auth.user.id logger.debug('User %d connected on the notification system.', userId) - this.userNotificationSockets[userId] = socket + if (!this.userNotificationSockets[userId]) this.userNotificationSockets[userId] = [] + + this.userNotificationSockets[userId].push(socket) socket.on('disconnect', () => { logger.debug('User %d disconnected from SocketIO notifications.', userId) - delete this.userNotificationSockets[userId] + this.userNotificationSockets[userId] = this.userNotificationSockets[userId].filter(s => s !== socket) + }) + }) + + this.liveVideosNamespace = io.of('/live-videos') + .on('connection', socket => { + socket.on('subscribe', ({ videoId }) => { + if (!isIdValid(videoId)) return + + /* eslint-disable @typescript-eslint/no-floating-promises */ + socket.join(videoId) + }) + + socket.on('unsubscribe', ({ videoId }) => { + if (!isIdValid(videoId)) return + + /* eslint-disable @typescript-eslint/no-floating-promises */ + socket.leave(videoId) }) }) } sendNotification (userId: number, notification: UserNotificationModelForApi) { - const socket = this.userNotificationSockets[userId] + const sockets = this.userNotificationSockets[userId] + if (!sockets) return + + logger.debug('Sending user notification to user %d.', userId) + + const notificationMessage = notification.toFormattedJSON() + for (const socket of sockets) { + socket.emit('new-notification', notificationMessage) + } + } + + sendVideoLiveNewState (video: MVideo) { + const data: LiveVideoEventPayload = { state: video.state } + const type: LiveVideoEventType = 'state-change' + + logger.debug('Sending video live new state notification of %s.', video.url, { state: video.state }) + + this.liveVideosNamespace + .in(video.id) + .emit(type, data) + } + + sendVideoViewsUpdate (video: MVideo) { + const data: LiveVideoEventPayload = { views: video.views } + const type: LiveVideoEventType = 'views-change' - if (!socket) return + logger.debug('Sending video live views update notification of %s.', video.url, { views: video.views }) - socket.emit('new-notification', notification.toFormattedJSON()) + this.liveVideosNamespace + .in(video.id) + .emit(type, data) } static get Instance () {