이번 강의에서의 핵심은,클라이언트와 서버가 주고받는 패킷은 지금까지 구현했던 방식으로는 O(n^2)의 복잡도를 가지면서 처리되고 있을것이다.
클라이언트의 수가 점점 많이지면 그 주고받는 패킷의 양도 시간복잡도를 따라서 많이질텐데,
멀티 스레드 환경을 고려해서 lock을 사용해 작업을 처리하고있으니, 매우 많은 패킷이 처리되야함에도 불구하고 계속해서 처리가 밀리게되어 스레드들이 계속 기다릴 뿐만아니라, 작업이 잘 처리되지않는다고 판단되어 불필요한 스레드를 추가로 만들어 버린다.
그래서 강의에서 Command 패턴을 소개하며, 불필요한 스레드 생성을 막아준다.
큰 그림은 다음과 같다.
어차피 lock을 잡아 한 스레드 밖에 작업을 못하면 JobQueue에 해야할 행동만 넣고 다른 스레드는 또다른 작업을 하게 하는 방식으로 스레드가 대기하는 현상을 막는것이다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ServerCore
{
public interface IJobQueue
{
void Push(Action job);
}
public class JobQueue : IJobQueue
{
Queue<Action> _jobQeue = new Queue<Action>();
object _lock = new object();
bool _flush = false;
public void Push(Action job)
{
bool flush = false;
lock (_lock)
{
_jobQeue.Enqueue(job);
if (_flush == false)
flush = _flush = true;
}
if (flush)
Flush();
}
void Flush()
{
while (true)
{
Action action = Pop();
if (action == null)
return;
action.Invoke();
}
}
Action Pop()
{
lock (_lock)
{
if (_jobQeue.Count == 0)
{
_flush = false;
return null;
}
return _jobQeue.Dequeue();
}
}
}
}
여기서 주의할 점은 해야할 "행동"을 넣어 놓았기때문에 사전에 필요한 정보들을 같이 넣어주게되는데,
public override void OnDisconnected(EndPoint endPoint)
{
SessionManager.Instance.Remove(this);
if (Room != null)
{
Room.Push(() => Room.Leave(this));
Room = null;
}
Console.WriteLine($" OnDisconnected: {endPoint}");
}
기존 코드는 Room을 밀어넣고 null로 바꿔줬는데, 이러면 클라이언트에서 강제로 연결을 끊어버렸을때 해야할 "행동"에 넣어줬던 참조값도 강제로 없애버리기 때문에 크래시가 난다.
그래서 대안으로 값을 복사해주고 넣어주는 방식으로 수정했다.
public override void OnDisconnected(EndPoint endPoint)
{
SessionManager.Instance.Remove(this);
if (Room != null)
{
GameRoom room = Room;
room.Push(() => room.Leave(this));
Room = null;
}
Console.WriteLine($" OnDisconnected: {endPoint}");
}
'서버 공부' 카테고리의 다른 글
| [서버 공부] 미니 프로젝트: 채팅 방 만들기 2편 (0) | 2025.02.02 |
|---|---|
| [서버 공부] 미니 프로젝트: 채팅 방 만들기 1편 (0) | 2025.01.30 |
| [서버 공부]18. Packet Generator 3,4,5,6 (0) | 2025.01.27 |
| [서버 공부]17.Packet Generator 1,2 (0) | 2025.01.24 |
| [서버 공부]16.PacketSession (0) | 2025.01.16 |