File size: 1,357 Bytes
00a912e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import { EVENTS, LIMITS, ERROR_CODE, chatMessageSchema } from '@music-together/shared'
import { RateLimiterMemory } from 'rate-limiter-flexible'
import * as chatService from '../services/chatService.js'
import { createWithRoom } from '../middleware/withRoom.js'
import type { TypedServer, TypedSocket } from '../middleware/types.js'

const chatLimiter = new RateLimiterMemory({
  points: LIMITS.CHAT_RATE_LIMIT_PER_SECOND,
  duration: 1, // 1 second
})

export function registerChatController(io: TypedServer, socket: TypedSocket) {
  const withRoom = createWithRoom(io)

  socket.on(
    EVENTS.CHAT_MESSAGE,
    withRoom(async (ctx, raw) => {
      // Rate limit check
      try {
        await chatLimiter.consume(ctx.socket.id)
      } catch {
        ctx.socket.emit(EVENTS.ROOM_ERROR, { code: ERROR_CODE.RATE_LIMITED, message: '发送过于频繁,请稍后再试' })
        return
      }

      const parsed = chatMessageSchema.safeParse(raw)
      if (!parsed.success) {
        ctx.socket.emit(EVENTS.ROOM_ERROR, { code: ERROR_CODE.INVALID_INPUT, message: '消息格式无效' })
        return
      }

      const trimmed = parsed.data.content.trim()
      if (trimmed.length === 0) return

      const message = chatService.createMessage(ctx.roomId, ctx.user, trimmed)
      io.to(ctx.roomId).emit(EVENTS.CHAT_MESSAGE, message)
    }),
  )
}