대략 2주만에 포스팅이다..
현재 프로젝트에서 크게 남은 과정은 2가지다.
1. 캐릭터 통계 제공
- Flutter의 경우는 크게 어려울 것이 없지만 서버쪽에서 캐릭터별 통계를 저장하는 부분에서 다소 난이도가 있다고 판단됨, 다만 어느정도 어느 부분에서 비동기, 동기로 코드를 돌릴 것인지에 대한 구상은 끝내둔 상태라 생각보다는 어려움이 적을 것 같음
2. 웹 소켓을 이용한 채팅
개인적으로 1번의 경우는 어려운것도 어려운것이지만 어느정도의 고생이 예상되서 그냥 하기가 조금은 꺼려졌다;;; 따라서 2번을 먼저 진행하였다. (업무였다면 이러지 않았겠지만 혼자하는 개인프로젝트에 어차피 둘다 내가 다 구현할껀데 그냥 원하는거 먼저하면서 스트레스를 받고싶지는 않았다.)
구현한 화면은 2가지로 채팅방 목록과 채팅방이다.
채팅방 목록 부분에서 신경쓴 부분은 최신 메시지, 인원 수에 대한 부분이 변화가 있으면 실시간으로 갱신되는 부분이다.
해당 부분을 구현하면서 발생하였던 문제는 채팅방에서 방목록 화면으로 돌아왔을 때 Flutter에서 웹소켓 코드가 자동으로 해제되어 재수신을 받을 수 없다는 것이였다.
일단 해당 문제의 경우 웹소켓이 해제 되지 않게 해당 코드를 전역하는 방식으로 해결하였다.
다만 이 경우 채팅방 목록, 채팅방에 대한 웹소캣이 각각 연결되어 개인적으로 매우 불편하다...;;;
차후 개선하고 싶은 부분 1번이다.
io.on("connection", (socket) => {
console.log("새로운 사용자가 연결되었습니다.");
socket.on("room list", () => {
socket.emit("room list", roomList);
});
socket.on("join room", async (roomName, nickName) => {
socket.join(roomName);
console.log(`사용자 ${socket.id}가 ${nickName} 방에 참여하였습니다.`);
await Message.find({ roomName })
.sort({ createdAt: -1 })
.limit(10)
.then((messages) => {
io.to(roomName).emit("chat message", messages);
});
io.to(roomName).emit("chat message", {
type: "system",
text: `${nickName}님이 참여했습니다.`,
roomName,
createdAt: new Date().toISOString(),
numberOfPeople: ++roomList[roomName].numberOfPeople,
});
io.emit("room list", roomList);
});
전역 함수를 사용한 덕에 서버쪽에서도 새로운 입장이 있으면 '모든' 클라이언트에게 roomList를 전송하였다.
본 프로젝트는 회원가입을 하지않고 지정된 모든 톡방에 접근 가능하도록 했기 때문에 roomList에 갱신이 필요 할때
모든 사용자에게 새로운 데이터를 보내야 하는게 맞을지도 모르지만, 실제 메신저의 경우에는 해당 사용자가 속한 톡방에 대한 정보만을 갱신 받는 것이 맞을 것이다. (이 부분은 차후 비슷한 구현을 하게된다면 반드시 해결하고싶다)
채팅방의 메시지는 Type에 따라서 사용자메시지, 시스템 메시지에 따라서 다른 UI를 사용하여 표시하도록하였다.
채팅창의 경우는 비회원으로 진행되기 때문에 User의 식별자 값 '웹 소켓의 ID'로 설정하였다. 따라서 문제는 없었으나
채팅방에 입장 할 때마다 내가 기존에 입력한 메시지를 타인의 메시지로 인식하는 사소한 문제가 있었다.
해당 문제의 경우는 사용자가 앱을 설치하고 웹 소켓에 처음 연결하였을 때 서버에서 DB를 조회하여 유니크한 ID값을 내려주고 이후 해당 ID값을 사용자 로컬에 저장하여 계속 사용한다면 해결 할 수 있는 문제라고 판단된다. 해당 문제의 경우는 우선순위나 재미, 구현난이도가 낮다고 생각하여 기능 추가를 하지는 않을 것 같다.
추가적으로 웹 소켓 연결이 끊어 졌을 때 해당 채팅방에 사용자수를 빼줘야하는데 이 부분에 대해서 고민중이다.
단순히 생각하면 Map<String, String> 을 사용하여 data['사용자ID'] : 속한 채팅방 꼴로 저장하여 해당 채팅방 숫자를 빼주는 것이 간단하겠지만 뭔가 비효율적이라고 생각되어 조금 더 좋은 방법이 없을지 고민중이다.
채팅방 관련 데이터 저장 및 조회도 어느정도 완료했다고 생각되기 때문에 아마 다음 포스팅은 다시 캐릭터 통계쪽을 진행하지 않을까 싶다.