: 그룹 채팅방에서 실시간 채팅을 할 수 있는 기능을 구현하고자 한다. 한 사용자가 메세지를 송신하면 채팅방에 있는 다른 사용자들이 메세지를 수신할 수 있어야 한다. 실시간으로 이것이 가능하게 하려면 어떤식으로 흐름을 구성해야 하는지 정리해보고자 한다.
고려사항
: 현재의 기획은 단일 서버를 전제로 한다. 따라서 서버가 여러 대일 경우 서로 다른 서버에서 관리되고 있는 웹소켓 세션에 대한 공유가 이뤄져야 한다. 이러한 사항에 대해서는 우선 단일 서버를 전제로 한 구현이 완료된 후에 고도화 작업에서 고려하여 수정해보고자 한다.
사용 기술
- WebSocket
- MySQL
흐름 설명
사용자 로그인한다.
사용자가 특정한 채팅방에 입장한다.
채팅방 입장과 동시에 WebSocket 연결 및 WebSocketSession 생성이 진행된다.
WebSocketSession의 역할은 다음과 같다.
클라이언트 - 서버 연결 상태 추적
연결된 클라이언트 식별
메세지 전송
연결 열거나 종료
Map의 키 값은 채팅방의 아이디를 value 값은 Set<WebSocketSession>으로 받게 하여 세션을 저장한다.
roomId가 1인 채팅방에 사용자 a, b, c가 접속 중이라면 이 사용자들의 연결 여부를 확인해주는 세션 객체 세 개가 Set<WebSocketSession>에 담기고 roomId인 1이 Key, Set이 Value가 되어 Map에 저장된다고 보시면 된다.
채팅방에 접속한 후 사용자가 해당 채팅방의 멤버인지 여부를 확인하고 아닌 경우 채팅방 참여자를 저장하는 테이블에 저장한다.
멤버인 경우 저장 로직을 넘깁니다.
메세지 송신 발생 시 데이터 베이스에 저장 후 채팅방에 접속 중인 사용자에게 전달된다.
이때 WebSocketSession이 사용된다.
Set에 저장된 WebSocketSession 전체에 메세지를 전달하는 방식이다. 이때 전체를 순회하면서 각 세션이 유효한지 확인 후 유효한 경우에만 메세지를 전달한다. 이는 Set에는 저장되어 있더라도 실제로는 어떠한 이유에 의해 연결이 끊겨있을 수 있다는 가능성을 고려한 것이다.
데이터베이스에 저장 후 사용자에게 메세지를 전달하는 이유는 메세지가 소실될 가능성을 염두한 것이다. 다른 클라이언트에게 메세지가 전달됐는데 데이터베이스에는 해당 메세지가 없는 것은 문제가 될 것이다.
접속 중이 아닌 경우 접속 시 DB에서 불러오는 방식으로 조회한다.
접속 중이 아닌 경우 메시지를 받을 수 없다.
다시 접속한 경우 웹소켓에 의해 메세지를 받는 것은 불가능하나 기존에 주고받은 메세지가 데이터베이스에 저장되어 있기 때문에 이를 조회하는 방식으로 전의 메세지를 확인할 수 있다.
채팅방에서 퇴장 시 Set에서 삭제한다.
이때 ‘퇴장’은 채팅방의 멤버이기를 그만한다는 뜻이 아니라 채팅방에 접속중이지 않은 상태가 되는 것을 의미한다.
채팅방에 접속중이지 않다는 것은 서버와의 연결을 종료한다는 것이기 때문에 WebSocketSession을 Set에서 삭제한다.
채팅방에 접속 중인 인원 없을 시 key 값이 해당 roomId인 데이터 삭제한다.
채팅방에 접속 중인 인원이 없으면 WebSocketSession을 담아서 저장할 데이터가 필요 없어진다.
Set<WebSocketSession>이 빈 상태가 되면 해당 채팅방의 roomId를 키 값으로 가진 데이터를 Map에서 삭제한다.
function 함수명(){
let fruits = ['사과','배','감','귤','수박'];
$("#q1").empty();
let a = fruits[0];
let temp = `<p>${a}</p>` /*반드시 키보드의 숫자 1 옆의 ` 사용*/
$('#id값').append(temp);
}
4. toggle(): 껐다 켜기
function openclose(){
$("#postingbox").toggle();
}
5. val(): 값을 가져오기
function makecard(){
let image = $("#image").val();
alert(image);
}