Skip to content

Commit 4e91a55

Browse files
committed
fix: 테스트 클라이언트 변경
1 parent 52e5cf6 commit 4e91a55

File tree

1 file changed

+136
-14
lines changed

1 file changed

+136
-14
lines changed

test-clients/test-client.html

Lines changed: 136 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,24 @@
129129
box-shadow: 0 2px 6px rgba(76, 175, 80, 0.3);
130130
}
131131

132+
#login-btn:hover {
133+
background: #1976d2;
134+
transform: translateY(-1px);
135+
box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);
136+
}
137+
138+
#login-btn:active {
139+
transform: translateY(0);
140+
box-shadow: 0 2px 6px rgba(33, 150, 243, 0.3);
141+
}
142+
143+
#login-btn:disabled {
144+
background: #cccccc;
145+
cursor: not-allowed;
146+
transform: none;
147+
box-shadow: none;
148+
}
149+
132150
#audio-player {
133151
display: none;
134152
}
@@ -140,13 +158,24 @@
140158
<div id="status">
141159
<div style="display: flex; justify-content: space-between; align-items: center;">
142160
<div style="display: flex; align-items: center; gap: 1em;">
143-
<span>WebSocket 상태: <span id="ws-status">초기화 대기 중</span></span>
161+
<span>로그인: <span id="login-status">대기 중</span></span>
162+
<span style="color: #6c757d; font-size: 0.85em;">| WebSocket: <span id="ws-status">대기 중</span></span>
144163
<span style="color: #6c757d; font-size: 0.85em;">| 세션: <span id="session-id">없음</span></span>
145164
</div>
146165
<span style="color: #6c757d; font-size: 0.85em;">서버: <span id="server-info"></span></span>
147166
</div>
148167
</div>
149168

169+
<div id="login-section">
170+
<div style="display: flex; align-items: center; gap: 1em; margin-bottom: 1em;">
171+
<input id="guest-id" type="text" placeholder="게스트 ID를 입력하세요" value="test-guest-123"
172+
style="flex: 1; padding: 0.75em; border-radius: 8px; border: 1px solid #c8e6c9; font-size: 1em;" />
173+
<button id="login-btn" style="background: #2196f3; color: white; border: none; padding: 0.75em 1.5em; border-radius: 8px; font-size: 1em; cursor: pointer; font-weight: 500;">
174+
게스트 로그인
175+
</button>
176+
</div>
177+
</div>
178+
150179
<div class="top-row">
151180
<select id="character-select">
152181
<option value="44444444-4444-4444-4444-444444444444">제로</option>
@@ -182,13 +211,17 @@
182211
const ENDPOINT = `${currentHost}:${serverPort}`;
183212
const WS_URL = `ws://${ENDPOINT}/ws`;
184213
const HTTP_URL = `http://${ENDPOINT}/api/v1/chat`;
214+
const LOGIN_URL = `http://${ENDPOINT}/api/auth/guest-login`;
185215
const SERVER_MESSAGE_TYPE = "json";
186216
let sessionId = null;
187217
let ws = null;
188218
let reconnectAttempts = 0;
189219
const MAX_RECONNECT = 3;
220+
let authToken = null;
221+
let isLoggedIn = false;
190222

191223
const statusBox = document.getElementById('status');
224+
const loginStatus = document.getElementById('login-status');
192225
const wsStatus = document.getElementById('ws-status');
193226
const sessionIdDisplay = document.getElementById('session-id');
194227
const serverInfo = document.getElementById('server-info');
@@ -197,6 +230,9 @@
197230
const sendBtn = document.getElementById('send-btn');
198231
const audioPlayer = document.getElementById('audio-player');
199232
const characterSelect = document.getElementById('character-select');
233+
const guestIdInput = document.getElementById('guest-id');
234+
const loginBtn = document.getElementById('login-btn');
235+
const loginSection = document.getElementById('login-section');
200236

201237
const audioQueue = [];
202238
let isPlayingAudio = false;
@@ -212,11 +248,65 @@
212248
if (response.ok) {
213249
serverConfig = await response.json();
214250
console.log("서버 설정:", serverConfig);
215-
setStatus(`연결됨`);
216251
}
217252
} catch (e) {
218253
console.warn("서버 설정 확인 실패:", e);
219-
setStatus("연결됨 (설정 확인 실패)");
254+
}
255+
}
256+
257+
// Guest 로그인 함수
258+
async function guestLogin() {
259+
const guestId = guestIdInput.value.trim();
260+
if (!guestId) {
261+
appendLog('<span style="color:red">[로그인 오류] 게스트 ID를 입력하세요</span>');
262+
return;
263+
}
264+
265+
setLoginStatus('로그인 중...', false);
266+
loginBtn.disabled = true;
267+
loginBtn.textContent = '로그인 중...';
268+
269+
try {
270+
const response = await fetch(LOGIN_URL, {
271+
method: 'POST',
272+
headers: {
273+
'Content-Type': 'application/json'
274+
},
275+
body: JSON.stringify({
276+
guestId: guestId
277+
})
278+
});
279+
280+
if (response.ok) {
281+
const data = await response.json();
282+
if (data.success && data.tokens) {
283+
authToken = data.tokens.accessToken;
284+
isLoggedIn = true;
285+
setLoginStatus('로그인 성공', false);
286+
updateOverallStatus();
287+
288+
appendLog(`<b>[로그인 성공]</b> 게스트 ID: ${guestId}`);
289+
appendLog(`<small>사용자: ${data.user.username} (${data.user.email})</small>`);
290+
291+
loginSection.style.display = 'none';
292+
293+
// 로그인 성공 후 WebSocket 연결 시작
294+
connectWebSocket();
295+
} else {
296+
throw new Error(data.message || '로그인 실패');
297+
}
298+
} else {
299+
const errorData = await response.json();
300+
throw new Error(errorData.message || `HTTP ${response.status}`);
301+
}
302+
} catch (error) {
303+
console.error('로그인 오류:', error);
304+
setLoginStatus('로그인 실패', true);
305+
updateOverallStatus();
306+
appendLog(`<span style="color:red">[로그인 오류] ${error.message}</span>`);
307+
} finally {
308+
loginBtn.disabled = false;
309+
loginBtn.textContent = '게스트 로그인';
220310
}
221311
}
222312

@@ -275,11 +365,20 @@
275365
}
276366
}
277367

278-
function setStatus(message, isError = false) {
368+
function setLoginStatus(message, isError = false) {
369+
loginStatus.textContent = message;
370+
loginStatus.style.color = isError ? '#dc3545' : '#2e7d32';
371+
}
372+
373+
function setWSStatus(message, isError = false) {
279374
wsStatus.textContent = message;
280375
wsStatus.style.color = isError ? '#dc3545' : '#2e7d32';
281-
statusBox.style.background = isError ? '#ffebee' : '#e8f5e8';
282-
statusBox.style.borderColor = isError ? '#ffcdd2' : '#c8e6c9';
376+
}
377+
378+
function updateOverallStatus() {
379+
const hasError = loginStatus.style.color === 'rgb(220, 53, 69)' || wsStatus.style.color === 'rgb(220, 53, 69)';
380+
statusBox.style.background = hasError ? '#ffebee' : '#e8f5e8';
381+
statusBox.style.borderColor = hasError ? '#ffcdd2' : '#c8e6c9';
283382
}
284383

285384
function updateSessionId(sessionId) {
@@ -336,11 +435,21 @@
336435
}
337436

338437
function connectWebSocket() {
438+
if (!isLoggedIn) {
439+
setWSStatus("로그인 필요", true);
440+
updateOverallStatus();
441+
return;
442+
}
443+
444+
setWSStatus("연결 중...", false);
445+
updateOverallStatus();
446+
339447
ws = new WebSocket(sessionId ? `${WS_URL}?sessionId=${sessionId}` : WS_URL);
340448
ws.binaryType = "arraybuffer";
341449

342450
ws.onopen = () => {
343-
setStatus("연결됨");
451+
setWSStatus("연결됨", false);
452+
updateOverallStatus();
344453
reconnectAttempts = 0;
345454
checkServerConfig();
346455
};
@@ -528,14 +637,16 @@
528637
};
529638

530639
ws.onclose = () => {
531-
setStatus("연결 종료됨", true);
640+
setWSStatus("연결 종료됨", true);
641+
updateOverallStatus();
532642
updateSessionId(null);
533643
appendLog("<b>[WebSocket 연결 종료]</b>");
534-
tryReconnect();
644+
if (isLoggedIn) tryReconnect();
535645
};
536646

537647
ws.onerror = () => {
538-
setStatus("오류 발생", true);
648+
setWSStatus("오류 발생", true);
649+
updateOverallStatus();
539650
updateSessionId(null);
540651
appendLog("<b>[WebSocket 오류]</b>");
541652
};
@@ -544,10 +655,12 @@
544655
function tryReconnect() {
545656
if (reconnectAttempts < MAX_RECONNECT) {
546657
reconnectAttempts++;
547-
setStatus(`재연결 시도 중... (${reconnectAttempts}/${MAX_RECONNECT})`, true);
658+
setWSStatus(`재연결 시도 중... (${reconnectAttempts}/${MAX_RECONNECT})`, true);
659+
updateOverallStatus();
548660
setTimeout(connectWebSocket, 1000 * reconnectAttempts);
549661
} else {
550-
setStatus("재연결 실패. 새로고침 해주세요.", true);
662+
setWSStatus("재연결 실패. 새로고침 해주세요.", true);
663+
updateOverallStatus();
551664
}
552665
}
553666

@@ -566,9 +679,14 @@
566679
};
567680
if (sessionId) payload.session_id = sessionId;
568681

682+
const headers = { "Content-Type": "application/json" };
683+
if (authToken) {
684+
headers["Authorization"] = `Bearer ${authToken}`;
685+
}
686+
569687
fetch(HTTP_URL, {
570688
method: "POST",
571-
headers: { "Content-Type": "application/json" },
689+
headers: headers,
572690
body: JSON.stringify(payload)
573691
})
574692
.then(res => {
@@ -589,14 +707,18 @@
589707

590708
sendBtn.onclick = sendChat;
591709
userInput.onkeydown = (e) => { if (e.key === "Enter") sendChat(); };
710+
711+
loginBtn.onclick = guestLogin;
712+
guestIdInput.onkeydown = (e) => { if (e.key === "Enter") guestLogin(); };
592713

593714
characterSelect.onchange = () => {
594715
userInput.value = "";
595716
chatLog.innerHTML = "";
596717
appendLog(`<i>[캐릭터 변경됨: ${characterSelect.options[characterSelect.selectedIndex].text}]</i>`);
597718
};
598719

599-
connectWebSocket();
720+
// 초기화 - 로그인을 기다림
721+
appendLog('<b>[시작]</b> 게스트 ID를 입력하고 로그인하세요.');
600722
</script>
601723
</body>
602724

0 commit comments

Comments
 (0)