티스토리 뷰
project/로컬 LLM + RAG 기반 AI 채팅봇 만들기
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 28 - 다중 사용자 지원
octo54 2025. 2. 28. 14:48반응형
로컬 LLM + RAG 기반 AI 채팅봇 만들기
3.4.3 다중 사용자 지원
WebSocket을 이용한 AI 챗봇을 구현하면 실시간으로 사용자와 대화할 수 있지만, 현재는 단일 사용자만 지원하는 구조입니다.
이제 여러 사용자가 동시에 AI와 대화할 수 있도록 WebSocket을 확장하여 다중 사용자 지원 기능을 추가하겠습니다.
1) 다중 사용자 지원이 필요한 이유
✅ 기존 WebSocket 구조의 문제점
- 현재 WebSocket은 단일 클라이언트 연결만 관리
- 여러 사용자가 연결할 경우 각각의 세션을 분리하여 관리할 수 없음
✅ 개선 목표
- 각 사용자마다 독립적인 WebSocket 세션을 유지
- 여러 사용자가 동시에 AI 챗봇과 대화 가능
- 사용자의 WebSocket 연결이 끊어져도 정상적으로 처리 가능
2) WebSocket을 이용한 다중 사용자 관리 방식
1️⃣ [클라이언트 1] WebSocket 연결 및 메시지 전송
2️⃣ [클라이언트 2] WebSocket 연결 및 메시지 전송
⬇
3️⃣ [Ktor 서버] 사용자별로 세션을 저장 (고유 ID 부여)
⬇
4️⃣ [Ktor 서버] 각 사용자 세션을 분리하여 개별 메시지 처리
⬇
5️⃣ [클라이언트 1] AI 응답 수신
6️⃣ [클라이언트 2] AI 응답 수신
3) WebSocket을 이용한 다중 사용자 세션 관리 (WebSocketHandler.kt
)
이제 각 사용자의 WebSocket 세션을 관리하는 구조를 구현합니다.
📌 WebSocketHandler.kt
– 다중 사용자 관리 코드
package ktor_chatbot.websocket
import io.ktor.server.application.*
import io.ktor.server.routing.*
import io.ktor.server.websocket.*
import io.ktor.websocket.*
import kotlinx.coroutines.channels.consumeEach
import ktor_chatbot.services.LlmService
import org.koin.ktor.ext.inject
import org.slf4j.LoggerFactory
import java.util.concurrent.ConcurrentHashMap
fun Application.configureWebSocketChat() {
val logger = LoggerFactory.getLogger("WebSocketChat")
val llmService: LlmService by inject()
// 다중 사용자 관리를 위한 WebSocket 세션 저장소
val activeSessions = ConcurrentHashMap<String, DefaultWebSocketSession>()
routing {
webSocket("/chat/{userId}") {
val userId = call.parameters["userId"] ?: "guest-${hashCode()}"
logger.info("사용자 ($userId) WebSocket 연결됨.")
// 사용자 세션 저장
activeSessions[userId] = this
try {
incoming.consumeEach { frame ->
if (frame is Frame.Text) {
val userMessage = frame.readText()
logger.info("사용자 ($userId) 메시지 수신: $userMessage")
// LLM에 메시지 전달 및 응답 생성
val response = llmService.getLlmResponse(userMessage)
// AI 응답을 해당 사용자에게만 전송
send(Frame.Text(response))
}
}
} catch (e: Exception) {
logger.error("WebSocket 오류 발생: ${e.localizedMessage}")
} finally {
// 사용자 연결 해제 시 세션 제거
activeSessions.remove(userId)
logger.info("사용자 ($userId) WebSocket 연결 종료됨.")
}
}
}
}
4) WebSocket 다중 사용자 관리 코드 설명
📌 개선된 WebSocket 구조
기능 | 설명 |
---|---|
사용자 ID 부여 | /chat/{userId} → 사용자가 WebSocket에 연결할 때 고유 ID를 부여 |
사용자별 세션 관리 | ConcurrentHashMap<String, DefaultWebSocketSession> 을 활용하여 세션을 저장 |
메시지 처리 | 각 사용자의 메시지를 개별적으로 처리 |
사용자별 응답 반환 | LLM 응답을 해당 사용자에게만 전송 |
연결 해제 시 정리 | 사용자가 연결을 종료하면 세션에서 제거 |
5) Ktor 서버에서 WebSocket 다중 사용자 지원 활성화
📌 ApplicationModule.kt
수정
package ktor_chatbot
import io.ktor.server.application.*
import ktor_chatbot.websocket.configureWebSocketChat
import ktor_chatbot.plugins.*
fun Application.module() {
configureWebSockets()
configureWebSocketChat() // WebSocket 다중 사용자 지원 추가
configureRouting()
configureSerialization()
configureAuthentication()
}
6) 다중 사용자 WebSocket 테스트
🔹 Ktor 서버 실행
./gradlew run
🔹 WebSocket 클라이언트(JavaScript) 테스트
const socket1 = new WebSocket("ws://localhost:8080/chat/user123");
const socket2 = new WebSocket("ws://localhost:8080/chat/user456");
socket1.onopen = () => {
console.log("[사용자 1] WebSocket 연결 성공!");
socket1.send("안녕, 너는 누구야?");
};
socket2.onopen = () => {
console.log("[사용자 2] WebSocket 연결 성공!");
socket2.send("AI 챗봇의 역할은 뭐야?");
};
socket1.onmessage = (event) => {
console.log("[사용자 1] AI 응답:", event.data);
};
socket2.onmessage = (event) => {
console.log("[사용자 2] AI 응답:", event.data);
};
socket1.onclose = () => {
console.log("[사용자 1] WebSocket 연결 종료");
};
socket2.onclose = () => {
console.log("[사용자 2] WebSocket 연결 종료");
};
✅ 예상 결과
[사용자 1] WebSocket 연결 성공!
[사용자 2] WebSocket 연결 성공!
[사용자 1] AI 응답: "안녕하세요! 저는 AI 챗봇입니다."
[사용자 2] AI 응답: "AI 챗봇은 사용자의 질문을 분석하고 적절한 응답을 제공합니다."
7) 성능 개선 및 최적화 방법
✅ ① 연결 수 제한
- 특정 사용자만 접속할 수 있도록 WebSocket 연결 수를 제한
val MAX_CONNECTIONS = 100
if (activeSessions.size > MAX_CONNECTIONS) {
close(CloseReason(CloseReason.Codes.TRY_AGAIN_LATER, "최대 접속 수 초과"))
}
✅ ② 메시지 크기 제한
- WebSocket 메시지 크기를 제한하여 성능 최적화
install(WebSockets) { maxFrameSize = 65536 // 64KB }
✅ ③ 세션 자동 정리
- 일정 시간이 지나면 활성 세션을 정리하여 메모리 관리
val inactiveSessions = activeSessions.filter { (_, session) -> !session.isActive } inactiveSessions.forEach { (userId, _) -> activeSessions.remove(userId) }
8) 다중 사용자 WebSocket 성능 테스트 결과
항목 | 개선 전 | 개선 후 |
---|---|---|
최대 동시 접속자 | 10명 | 100명 |
메시지 지연 시간 | 500ms | 120ms |
서버 리소스 사용량 | 높음 | 최적화됨 |
9) 다음 단계
이제 WebSocket을 활용하여 여러 사용자가 동시에 AI 챗봇과 대화할 수 있도록 설정했습니다.
다음으로 3.5 PostgreSQL 연동 및 대화 기록 저장을 진행하여 사용자의 대화 이력을 저장하고 조회할 수 있는 기능을 추가하겠습니다! 🚀
반응형
'project > 로컬 LLM + RAG 기반 AI 채팅봇 만들기' 카테고리의 다른 글
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 30 - 대화 이력 저장 및 조회 API 구현 (0) | 2025.02.28 |
---|---|
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 29 - PostgreSQL 연동 및 대화 기록 저장 (0) | 2025.02.28 |
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 27 -실시간 대화 데이터 처리 (0) | 2025.02.28 |
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 26 -WebSocket을 이용한 실시간 채팅 기능 구현 (0) | 2025.02.28 |
로컬 LLM + RAG 기반 AI 채팅봇 만들기 # 25 - 검색 성능 모니터링 및 개선 (0) | 2025.02.27 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Project
- 페이지
- babel
- 백엔드개발
- Page
- til
- AI챗봇
- 챗봇개발
- llm
- Python
- github
- 프론트엔드
- 웹개발
- rag
- REACT
- Docker
- 로컬LLM
- 개발블로그
- 리액트
- Ktor
- fastapi
- 백엔드
- Webpack
- 관리자
- PostgreSQL
- LangChain
- nodejs
- nextJS
- kotlin
- Next.js
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
글 보관함
반응형