설치

npm install @stomp/stompjs sockjs-client

npm install --save-dev @types/sockjs-client

에러

Uncaught ReferenceError: global is not defined →브라우저 환경에서 sockjs-client를 사용할 때 발생하는 Node.js 전역 객체 global이 정의되지 않았다는 오류

원인

sockjs-client 라이브러리 내부에서 global 변수를 사용하는데, 이는 Node.js 전역 객체이고 브라우저에서는 존재하지 않아 발생하는 문제야. 보통 이런 문제는 Vite + React 프로젝트에서 번들링 시 발생할 수 있어. 최근 Vite, Rollup, Webpack 5+에선 Node 전역 객체들을 자동으로 polyfill하지 않기 때문에 이런 문제가 생길 수 있어.

해결 방법

vite.config.ts에서 define: { global: 'globalThis' } 설정 추가

// vite.config.ts

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  define: {
    global: 'globalThis' // ✅ global 참조를 globalThis로 대체
  }
})

1️⃣WebSocket 연결 및 채팅 방 생성

Ver1.

목적 위치 설명
채팅방 생성 chatService.ts POST /api/chat/rooms
웹소켓 연결/구독 useChatSocket.ts 채팅방 입장 시 사용
채팅 상태 chatStore.ts 상태 관리용 zustand
채팅 시작 버튼 BoardDetailPage.tsx 클릭 시 채팅방 생성 + 이동

1.. 채팅방 생성 API - chatService.ts

// features/chat/services/chatService.ts
import axios from 'axios'

export const createChatRoom = async (boardId: number) => {
  const response = await axios.post('/api/chat/rooms', { boardId })
  return response.data.data.roomId
}
  1. Zustand Store - chatStore.ts
// store/chatStore.ts
import { create } from 'zustand'

interface ChatStore {
  connected: boolean
  setConnected: (status: boolean) => void
}

export const useChatStore = create<ChatStore>((set) => ({
  connected: false,
  setConnected: (status) => set({ connected: status }),
}))
  1. WebSocket 연결 & 구독 훅 - useChatSocket.ts
// features/chat/hooks/useChatSocket.ts
import { Client, IMessage } from '@stomp/stompjs'
import SockJS from 'sockjs-client'
import { useEffect, useRef } from 'react'
import { useChatStore } from '@/store/chatStore'

export const useChatSocket = (roomId: string, onMessage: (msg: any) => void) => {
  const clientRef = useRef<Client | null>(null)
  const setConnected = useChatStore((state) => state.setConnected)

  useEffect(() => {
    const socket = new SockJS('/ws')
    const client = new Client({
      webSocketFactory: () => socket,
      connectHeaders: {
        // 인증 필요 시 Authorization 헤더 추가
      },
      debug: (str) => console.log('[STOMP]', str),
      onConnect: () => {
        setConnected(true)

        // 채팅방 메시지 구독
        client.subscribe(`/topic/chat/room/${roomId}`, (message: IMessage) => {
          const body = JSON.parse(message.body)
          onMessage(body)
        })

        // 개인 메시지 구독
        client.subscribe('/user/queue/messages', (message: IMessage) => {
          const body = JSON.parse(message.body)
          console.log('개인 메시지 수신', body)
        })

        // 입장 알림
        client.publish({
          destination: '/app/chat.enter',
          body: JSON.stringify({ roomId }),
        })
      },
      onDisconnect: () => {
        setConnected(false)
      },
      reconnectDelay: 5000,
    })

    client.activate()
    clientRef.current = client

    return () => {
      client.deactivate()
    }
  }, [roomId, onMessage])
}
  1. 채팅방 생성 → 이동 로직 - BoardDetailPage.tsx