이번 편에서 구현한 사항
1."/현황"을 입력하면 각 방의 정보 리스트를 담은 패킷을 보냄

2."/입장[방 번호]"를 입력했을때에 대한 처리들
1)존재하지 않은 방번호 입력시

2)존재하는 방이나 방이 꽉찼을때

3)방 입장에 성공하였을때 -> 클라 세션을 채팅방의 세션 리스트에다가 넣어줌

보완해야하는 점
1.아직 다른 방에 입장해있을때 다른 방으로 입장 시도를 막아 놓지 않앗음 -> Enum으로 메인로비 =0 채팅방들 = 1로 정해놓고 같은 번호끼리는 이동하지 못하게 막아놔야함
2.거절 메시지를 전송하는 함수를 다 따로만들어놧는데 Enum으로 유형을 분류해놓은후 매개변수로 받아서 하나의 함수에서 처리하는게 효율적일거 같음
3.현재 Read에 직접적으로 클라이언트에서 온 내용을 받고 판단하고있는데 이것도 채팅내용, 플레이어 아이디만 따로 빼서 함수화 시키는게 코드가 더 깔끔해 보일듯 PacketHandler클래스를 만들어서 받은 패킷처리에 대한 동작을 정의해줄 예정
4.앞으로 많은 함수들이 추가될텐데 중간에 멀티스레드를 고려해서 lock을 잡아야하는지 말아야하는지는 아직 감이 잘안잡힌다. 전부 완성하고 나서 DummyClient를 많이 복제해서 테스트하는게 중요해보인다.
public void Read(ArraySegment<byte> segment)
{
ushort count = 0;
ReadOnlySpan<byte> s = new ReadOnlySpan<byte>(segment.Array, segment.Offset, segment.Count);
ushort size = BitConverter.ToUInt16(s.Slice(count, s.Length));
count += sizeof(ushort); ;
Console.WriteLine($"패킷 사이즈 : {size}");
ushort ID = BitConverter.ToUInt16(s.Slice(count, s.Length - count));
count += sizeof(ushort); ;
Console.WriteLine($"패킷 아이디 : {ID}");
this.playerid = BitConverter.ToInt32(s.Slice(count, s.Length - count));
count += sizeof(int);
Console.WriteLine($"플레이어 아이디 : {this.playerid}");
ushort chatLen = BitConverter.ToUInt16(s.Slice(count, s.Length - count));
count += sizeof(ushort);
Console.WriteLine($"채팅 길이 : {chatLen}");
this.message = Encoding.Unicode.GetString(s.Slice(count, chatLen));
count += chatLen;
Console.WriteLine($"채팅 내용 : {this.message}");
if (this.message[0] == '/')
{
if(this.message == "/현황")
{
//메인로비에 있는지 확인
if (MainLobby.Instance.Find(SessionManager.Instance._sessions[this.playerid]))
{
List<int[]> roomsStatus = RoomManager.Instance.GetRoomsStatus();
//현황 패킷 보내기
Server_Packet packet = new Server_Packet();
packet.playerid = SessionManager.Instance._sessions[this.playerid].sessionID;
for(int i = 0; i < roomsStatus.Count; i++)
{
packet.message += $"\n방 번호: {roomsStatus[i][0]} {roomsStatus[i][1]} / {roomsStatus[i][2]}";
}
packet.message += $"\n입장을 원하실 경우 \"/입장[방 번호]\"를 입력해주세요";
ArraySegment<byte> segmenta = packet.GeneralWrite();
SessionManager.Instance._sessions[this.playerid].Send(segmenta);
}
//메인로비에 없는데 "/현황"을 친거면 거절
else
{
SessionManager.Instance.RejectRequest(SessionManager.Instance._sessions[this.playerid]);
}
}
else if(this.message.Substring(0,3) == "/입장")
{
//명령어 길이 확인 후 그 채팅방이 존재하는지 확인
if(this.message.Length == 4)
{
int roomNumber = this.message[3] - '0';
//존재하는 방이면
if (RoomManager.Instance.FindRoomByNumber(roomNumber))
{
//입장시도 후 성공
if (RoomManager.Instance.TryEnterByNumber(roomNumber, SessionManager.Instance._sessions[this.playerid]))
{
SessionManager.Instance.AcceptRoomEnter(SessionManager.Instance._sessions[this.playerid], roomNumber);
}
//꽉차서 못받음
else
{
SessionManager.Instance.RejectRoomEnterIsFull(SessionManager.Instance._sessions[this.playerid]);
}
}
//존재하지 않은 방
else
{
SessionManager.Instance.RejectRoomEnterNotExist(SessionManager.Instance._sessions[this.playerid]);
}
}
}
}
else
{
if (MainLobby.Instance.Find(SessionManager.Instance._sessions[this.playerid]))
{
//메인로비에서 메세지를 보냈으니 거절 패킷을 보냄
SessionManager.Instance.RejectRequest(SessionManager.Instance._sessions[this.playerid]);
}
else
{
//해당 채팅방에있는 모든 유저에게 BroadCast해줌
}
}
}'서버 공부' 카테고리의 다른 글
| [서버 공부]미니 프로젝트 채팅 방 만들 5편 (0) | 2025.02.13 |
|---|---|
| [서버 공부]미니 프로젝트 채팅 방 만들 3편 (0) | 2025.02.11 |
| [서버 공부] 미니 프로젝트: 채팅 방 만들기 2편 (0) | 2025.02.02 |
| [서버 공부] 미니 프로젝트: 채팅 방 만들기 1편 (0) | 2025.01.30 |
| [서버 공부]19. Job Queue1,2 (0) | 2025.01.28 |