diff --git a/config/chatSocket.ts b/config/chatSocket.ts index 93f2706..c6f40bc 100644 --- a/config/chatSocket.ts +++ b/config/chatSocket.ts @@ -11,4 +11,7 @@ const resolveChatSocketUrl = (raw?: string): string => { } export const CHAT_SOCKET_URL = resolveChatSocketUrl(process.env.NEXT_PUBLIC_API_URL) +/** Socket.IO namespace (logical channel). */ export const CHAT_SOCKET_NAMESPACE = '/chat' +/** Engine.IO transport path — appears as `wss://host/chat/...` (not `/socket.io`). */ +export const CHAT_SOCKET_PATH = '/chat' diff --git a/hooks/useAdminChatSocket.ts b/hooks/useAdminChatSocket.ts index 6c618a6..5690c85 100644 --- a/hooks/useAdminChatSocket.ts +++ b/hooks/useAdminChatSocket.ts @@ -3,7 +3,7 @@ import { useEffect, useRef, useState } from 'react' import { io } from 'socket.io-client' -import { CHAT_SOCKET_NAMESPACE, CHAT_SOCKET_URL } from '@/config/chatSocket' +import { CHAT_SOCKET_NAMESPACE, CHAT_SOCKET_PATH, CHAT_SOCKET_URL } from '@/config/chatSocket' import useAuth from '@/hooks/useAuth' import { reportBrowserEvent } from '@/lib/observability/client' import type { AdminChatMessage } from '@/services/adminChat' @@ -34,6 +34,7 @@ const useAdminChatSocket = (conversationId: string, onMessage: (message: AdminCh let disconnectTimer: ReturnType | undefined let retryTimer: ReturnType | undefined const socket = io(`${CHAT_SOCKET_URL}${CHAT_SOCKET_NAMESPACE}`, { + path: CHAT_SOCKET_PATH, transports: ['websocket'], autoConnect: true, auth: { token: user.accessToken }, diff --git a/next.config.js b/next.config.js index 81fb8b4..ace8c32 100644 --- a/next.config.js +++ b/next.config.js @@ -140,8 +140,12 @@ const nextConfig = { destination: `${apiProxyTarget}/api/v1/:path*`, }, { - source: '/socket.io/:path*', - destination: `${apiProxyTarget}/socket.io/:path*`, + source: '/chat', + destination: `${apiProxyTarget}/chat`, + }, + { + source: '/chat/:path*', + destination: `${apiProxyTarget}/chat/:path*`, }, ] }, diff --git a/proxy.ts b/proxy.ts index 72ce3f8..4e55937 100644 --- a/proxy.ts +++ b/proxy.ts @@ -83,7 +83,7 @@ export default function proxy(request: NextRequest) { const { pathname, searchParams } = request.nextUrl - if (pathname === '/api' || pathname.startsWith('/api/') || pathname === '/socket.io' || pathname.startsWith('/socket.io/')) { + if (pathname === '/api' || pathname.startsWith('/api/') || pathname === '/chat' || pathname.startsWith('/chat/')) { if (!shouldStripForwardedBrowserOrigin()) { return NextResponse.next() } @@ -163,5 +163,5 @@ export default function proxy(request: NextRequest) { } export const config = { - matcher: ['/api/:path*', '/socket.io/:path*', '/((?!_next|_vercel|.*\\..*).*)'], + matcher: ['/api/:path*', '/chat', '/chat/:path*', '/((?!_next|_vercel|.*\\..*).*)'], }