diff --git a/src/index.tsx b/src/index.tsx index 3c78b3e..8d90365 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,8 +1,8 @@ import { createBrowserRouter, RouterProvider } from 'react-router-dom'; import Onboarding from './pages/onboarding/Onboarding'; -import Chat from './pages/chat/Chat'; import App from './App'; import HomePage from './pages/HomePage'; +import ChatPageTest from './pages/chat/ChatPageTest'; const router = createBrowserRouter([ { @@ -17,9 +17,10 @@ const router = createBrowserRouter([ path: 'onboarding', element: , }, + { - path: 'chat', - element: , + path: 'test', + element: , }, ], }, diff --git a/src/main.tsx b/src/main.tsx index c1fd642..02b76d1 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,10 +1,11 @@ -import { StrictMode } from 'react'; +// import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import './index.css'; import Router from './index.tsx'; createRoot(document.getElementById('root')!).render( - - - , + // + // + // , + , ); diff --git a/src/pages/chat/ChatPageTest.tsx b/src/pages/chat/ChatPageTest.tsx new file mode 100644 index 0000000..bbf5414 --- /dev/null +++ b/src/pages/chat/ChatPageTest.tsx @@ -0,0 +1,132 @@ +import { useEffect, useRef, useState } from 'react'; + +export default function ChatPageTest() { + const [output, setOutput] = useState(''); + const [input, setInput] = useState(''); + const [sessionId, setSessionId] = useState(null); + const socketRef = useRef(null); + const outputRef = useRef(null); + + const mountedRef = useRef(false); + + useEffect(() => { + if (mountedRef.current) return; + mountedRef.current = true; + + const socket = new WebSocket('wss://backendbase.site/ws/chat'); + socketRef.current = socket; + + socket.onopen = () => { + console.log('Connected'); + setOutput((prev) => prev + 'Connected\n'); + }; + + socket.onmessage = (event) => { + // bedrock stream done 메시지는 콘솔에만 표시 + if (event.data.includes('[bedrock stream done]')) { + console.log('Stream done:', event.data); + return; + } + + try { + const json = JSON.parse(event.data); + if (json.type === 'session') { + setSessionId(json.session_id); + setOutput((prev) => prev + `[세션 ID: ${json.session_id}]\n`); + return; + } + } catch { + /* not JSON */ + } + setOutput((prev) => prev + event.data + '\n'); + }; + + socket.onerror = (error) => { + console.error('WebSocket Error:', error); + setOutput((prev) => prev + 'Error occurred\n'); + }; + + socket.onclose = (event) => { + console.log('Disconnected:', event.code, event.reason); + setOutput((prev) => prev + `Disconnected: ${event.code}\n`); + }; + + return () => { + socket.close(); + }; + }, []); + + // 자동 스크롤 + useEffect(() => { + if (outputRef.current) { + outputRef.current.scrollTop = outputRef.current.scrollHeight; + } + }, [output]); + + const sendMessage = () => { + const text = input.trim(); + if (!text || !socketRef.current) return; + + if (socketRef.current.readyState === WebSocket.OPEN) { + socketRef.current.send(JSON.stringify({ role: 'user', content: text })); + setInput(''); + } else { + setOutput((prev) => prev + 'WebSocket이 연결되지 않음\n'); + } + }; + + const handleKeyPress = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + sendMessage(); + } + }; + + return ( +
+

Chat Test

+ {sessionId &&

세션 ID: {sessionId}

} +