[RAPID-fix] REST API 메시지 전송 시 Socket.IO broadcast 추가

- socketManager.ts 모듈 생성 (io 전역 공유)
- sendMessage 컨트롤러에서 io.to(room).emit('new_message') broadcast
- 상대방 말풍선 너비 고정 수정 (items-start 추가)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-31 09:54:49 +09:00
parent 0be75f2f41
commit 3f142f2184
4 changed files with 22 additions and 1 deletions

View File

@@ -416,10 +416,12 @@ const server = app.listen(PORT, HOST, async () => {
try {
const { Server: SocketIOServer } = await import("socket.io");
const { initMessengerSocket } = await import("./socket/messengerSocket");
const { setIo } = await import("./socket/socketManager");
const io = new SocketIOServer(server, {
cors: { origin: "*", methods: ["GET", "POST"] },
path: "/socket.io",
});
setIo(io);
initMessengerSocket(io);
logger.info("💬 Socket.IO messenger initialized");
} catch (error) {

View File

@@ -1,6 +1,7 @@
import { Request, Response } from 'express';
import { messengerService } from '../services/messengerService';
import { AuthenticatedRequest } from '../types/auth';
import { getIo } from '../socket/socketManager';
import path from 'path';
class MessengerController {
@@ -69,6 +70,13 @@ class MessengerController {
}
const message = await messengerService.sendMessage(roomId, user.userId, user.companyCode!, content, messageType, parentId);
// Broadcast to all room participants via Socket.IO
const io = getIo();
if (io) {
io.to(`${user.companyCode}:${roomId}`).emit('new_message', message);
}
res.json({ success: true, data: message });
} catch (error) {
const err = error as Error;

View File

@@ -0,0 +1,11 @@
import { Server } from 'socket.io';
let _io: Server | null = null;
export function setIo(io: Server) {
_io = io;
}
export function getIo(): Server | null {
return _io;
}

View File

@@ -53,7 +53,7 @@ export function MessageItem({ message, isOwn, showAvatar }: MessageItemProps) {
<div className="w-7" />
)}
<div className={cn("flex flex-col max-w-[70%]", isOwn && "items-end")}>
<div className={cn("flex flex-col max-w-[70%]", isOwn ? "items-end" : "items-start")}>
{showAvatar && !isOwn && (
<span className="text-xs font-medium text-muted-foreground mb-0.5">
{message.senderName}