공부/인프런 - Rookiss

Part 4-5-1. Job Queue : 채팅 테스트 #1

셩잇님 2023. 12. 23. 00:27
반응형

 

 

Job Queue

 

 지난 시간에는 드디어 Packet Generator의 작업이 모두 끝났다. 🤯 자동화 과정이 조금 지루하긴 했지만, 코드 그 자체를 string 변수에 담아 패킷 별로 구분하여 {0}, {1}을 이용해 생성해주는 방식은 정말 듣도 보도 못한 과정이었다. 이걸 보니 취준생일 때 부터 지금까지 꾸준하게 날 가르쳐주고 있는 루키스님이 새삼 대단하고 느껴지네. 😂

 


 

⛳ 추가 개선

 

 예전에 작성해두었던 ServerCore 프로젝트 내  Session 클래스 안에 RegisterSend(), OnSendComplete() 메서드를 다시 확인해보자. 해당 메서드는 중간에 접속이 끊겼을 때에 대한 처리가 없어 위와 같이 진행된다면 틀림없이 문제가 생길 것이다.

 

🚦 RegisterSend()

 

 RegisterSend에 들어왔을 때 Disconnect() 실행 시 1로 변경해주는 _disconnected의 변수 값을 확인하여, 만약 값이 1이라면 멀티 쓰레드로 인한 오류가 발생한 것이므로 바로 return 시켜주도록 한다.

 

 

 이 후 소켓을 사용하는 _socket.SendAsync() 부분 역시 보다 안전한 처리를 위해 try ~ catch문을 이용하여 묶어서 처리한다. 

 

🚦 RegisterRecv()

 

 RegisterSend와 마찬가지로 동일한 처리를 진행하여 준다. 

 

 


 

🍕 Chat 예시

 

 여기까지 작업을 진행한다면 네트워크 상에서 서로 통신이 가능하고, 문제가 없다는 것을 알 수 있다. 그러나 이걸 어떻게 활용할 수 있는지에 대한 이해는 전혀 되지 않는다. 나 또한 그러하고... 🤦‍♀️ 따라서 채팅을 만들어보면서 일반 게임과 유사하게 패킷을 보내보고, 이를 다른 유저들에게 패킷을 뿌려주는 과정을 실제 게임과 비슷한 과정으로 처리하여 더욱 쉽게 이해해보자.

 

🐷 PDL 수정

 

 

 클아이언트에서 보낼 메시지 내용과, 서버에서는 어떠한 사람이 보낸것인지를 확인하기 위한 Id, 그리고 다시 뿌려줄 채팅 내용에 대한 변수 값들을 저장하여 준다.

 

🐷 GameRoom Class 생성

 

 게임 룸은 유저들이 어떠한 방(=채널)에 접속하고 나가는지를 관리하기 위한 클래스이다. 아래와 같이 Client Session 타입의 List를 만들어 유저가 방에 들어왔을 때 추가하고, 나갈 때 제거하는 코드를 작성해준다.

 

 

🐷 GameRoom Lock 처리

 

 들어가고 나갈 때에도 멀티쓰레드 환경에서 문제가 생길 수 있기 때문에 한 번에 하나씩만 처리 하도록 lock을 이용하여 처리한다. 

 

\


 

🖐 ClientSession

 

 ClientSession에서 어떠한 Room을 가지고 있는지 알려주기 위한 프로퍼티를 선언해준다.

 

class ClientSession : PacketSession
    {
        public int SessionId { get; set; } 
        public GameRoom Room { get; set; }
        
        ...
        
    }

 

 Server - Program Main 코드 동작 시 GameRoom을 인스턴스 해주고, static으로 선언하여 보다 편리하게 접근하도록 처리한다.

 

public static GameRoom Room = new GameRoom();

 


 

🎶 Session Manager 생성

 

 

 이제 기존처럼 ClientSession을 새로 생성해서 넘겨주는것이 아니라, Manager를 통해 이를 생성해주고, 어떠한 클라이언트가 몇 개가 존재하는 지 등을 관리하기 위한 구조로 변경할 것이다.

 

 

 싱글톤을 이용하여 SessionManager를 불러온다면 session이 생성되도록 구현할 수 있다. 이 때 필요한 생성, 찾기, 제거 등의 기능을 가지는 함수들도 제작하여 준다.

 

생성

 

 

찾기, 제거

 

 

위와 같이 제작한 SessionManager 클래스를 통해 Generate 함수를 통해 서버에서 listner가 동작할 때 새로 생성해주는 방식으로 변경되면서 어떠한 세션들이 생기는지 한눈에 확인하고 관리할 수 있게 된다. 😎

 

 

 어찌보면 유저들이 증가할수록 패킷에 따른 session들이 많이 필요해질테니, 위와같이 관리해줄 필요성이 있다.

 

제거 위치

 

 유저의 연결이 끊어지는 경우, 새롭게 작성한 Remove를 이용하여 해당 Session을 삭제하자.

 

 


 

🖐 ClientSession

 

ClientSession으로 다시 돌아와서 새로 생성한 Room에 현재 ClientSession을 연결해주며 방을 생성하고, 연결이 끊어지는 시점에 방을 나가도록 Manager에서 제작한 함수의 동작 위치를 지정해준다. 😁

 

 


 

🌍 BroadCast

 

 GameRoom 클래스로 다시 돌아와 같은 방에 있는 유저들에게 받은 메시지 패킷을 뿌려주는 함수를 제작한다.

 

 

 PDL을 맨 처음 이미지와 같이 수정해주고 실행할 경우 아래 이미지와 같은 변수타입이 생성되었을 텐데, 이를 새로 인스턴스 해주고 현재 Session의 Id값과 Chat의 내용을 담아서 Write를 해준다.

 

 

 위에서 만들어준 list 타입의 _sessions을 순회하며 패킷을 전송해준다.

 

BroadCast 동작 위치

 

 지난 시간에서 언급했던 것과 같이 PacketHandler는 각 패킷에 따라 모두 다르게 처리해야 하기 때문에 이번에도 Chat 형식으로 패킷을 변경하여 어떻게 처리할 것인지를 작성해주도록 한다.

 

 

 파라미터를 통해 받아온 값들을 원하는 타입으로 캐스팅 한 뒤, Room이 비어있지 않을 경우 BroadCast 메서드를 실행시켜 패킷을 뿌려주도록 한다. 

 


 

정리

 

 이번 시간에는 여기저기 프로젝트를 돌아다니며 작업을 진행하느라 내용이 매우 헷갈린다. 따라서 아래와 같이 가볍게 정리한다. 새롭게 추가된 클래스는 다음과 같으며 해당 클래스의 목적과 기능을 작성하는 것으로 포스팅 마무리한다. 👍

 

GameRoom
 방을 만들고, 방에 입장한 유저(Session)들을 List에 담아 관리한다.

기능
 입장, 나가기, 전송하기 (방에 존재한 다른 유저들에게 패킷을 뿌린다.)

 

SessionManager
 처음 서버와 연결될 때 세션을 생성해주고 이를 관리하기 위한 SessinManager이다.

기능
 생성, 찾기, 제거

 

 

 

반응형