NetServer(Chatting Server)

2022. 5. 3. 19:56게임서버/namespace univ_dev

320x100
안녕하세요 대학생개발자입니다.
여전히 저는 할일이 많이 남았습니다.

사실 요샌 거의 이론보단 실제 개발에 치중해 있다보니 블로그 글을 쓸 일이 크게 없는것 같습니다.

 

예전에 LanServer, LanClient

서버와 서버간의 연결에서의 서버, 클라이언트 역할을 하게될 두개의 클래스에 대한 소개를 했었습니다.

 

이제 시작할 부분은 실제 유저인 클라이언트와 연결을 담당할 외부로 노출될 서버를 개발하게 되었습니다.

뭐... 이름이 바뀌었다고 해서 기능이 크게 달라지진 않았습니다.

 

대부분의 기능은 LanServer와 동일할겁니다.

뭐... 컨텐츠 쪽의 로직이 많이 달라지겠지만 그건 지금 네트워크 라이브러리에게 중요한것은 아닙니다.

 

우리가 중요하게 여겨야 할 부분은

네트워크를 타고 흐르는 패킷에 대한 보안입니다.

 

무슨 보안을 말씀하시는지..?

대부분의 사람들이 공유기를 많이 사용하실텐데요

당장 공유기에서 포트하나만 포워딩을 하셔도 어떤 나라인지... 어딘지 모르는 곳에서 마구잡이로 패킷들이 들어오는 모습을 확인할 수 있을겁니다.

 

저도 제 서버가 하나있는데요... 얘를 열어두면 이벤트로그에 가끔 Administrator, Admin, User,.. 와 같은 id를 통해 remote desktop을 연결하려는 시도가 간혹있습니다...(물론 그외에도 많습니다) 물론 비밀번호가 매우 길고 유저아이디도 바꿧기때문에 저 문제에서는 자유롭겠지만 이상한 패킷은 언제든지 들어올 수 있습니다.

 

그리고 당연히 연결도 되기 전에는 우리는 이 패킷이 정상적인 유저의 클라이언트 프로그램에서 보낸것인지 그냥 아무 쓰잘데기 없는 패킷인지 알 수 없을겁니다.

 

연결되기 이전의 패킷이 문제가 된다고 했지만 사실 그건 연결이 된 이후에도 마찬가지일겁니다.

연결이 되었다고 해서 그 패킷이 유저의 클라이언트 프로그램에서 보낸 정상적인 패킷인지... 조작되거나 아무 쓰잘데기 없는 패킷인지 여전히 알 수 없을겁니다.

이건 확실히 안전하다고 확신하는 사설망이 아니라면 언제든지 발생가능한 상황이죠.

 

우린 그럼 이런 상황에 모든 패킷을 컨텐츠로 올려줘야 하는가입니다.

아니 그전에 우린 이런상황에서 어떻게 확인할 수 있을까를 고민해봐야 합니다.

 

당연히 네트워크 라이브러리 선에서 거를 수 있다면 최대한 거르고 주는게 좋다고 생각합니다.

네트워크 라이브러리는 대부분의 시간을 IO혹은 Blocking되어 소모하고 그렇게 CPU사용율또한 높지 않을겁니다.

그에 비해서 반대로 게임 월드를 돌리는 작업을 처리하는 스레드는 상당시간 거의 대부분 연산자로 이루어진 로직을 돌리기 때문에 항시 바쁠뿐더러 IO Thread에 비해서 현저히 부족한 스레드 갯수로 월드를 돌려야 하다보니 당연하게도 이부분까지 전담하게 된다면 부담이 꽤나 있을것으로 생각됩니다.

 

그렇기 때문에 외부와 연결되는 서버의 네트워크 라이브러리는 패킷의 헤더에는 암호화, 복호화를 가능하게할 것들과 그리고 체크섬에 대한 정보가 들어갈것입니다.

 

 

LanServer와의 차이는 이게 다입니다.

하지만 이제 시작이죠.

NetServer라는 녀석을 이용해서 저는 채팅서버를 만들건데요.

고민해야될 부분은 다음과 같이 있을겁니다.

첫번째로는 쓰레드 디자인이고 두번째로는 쓰레드 디자인이 끝났다면 채팅서버는 어떤 로직을 담고있느냐입니다.

 

우선은 지금 채팅서버는 싱글스레드 서버입니다.

제가 지금 만든 서버는 여러개의 IO를 처리하는 WorkerThread들과 하나의 Update를 담당하는 스레드가 뽑혀있는 상태입니다. 그리고 WorkerThread와 UpdateThread간에는 LockFreeQueue를 사용해 데이터를 큐잉하고 하나씩 뽑아서 사용하는 형태의 구조가 되어있습니다.

 

UpdateThread를 멀티스레드로 뺄수도 있지만 우선은 가장 간단하고 구현이 심플한 싱글스레드 구조로 하고 추후에 멀티스레드에서 고민해야할 부분에 대한 언급을 하도록 하겠습니다.

 

그럼 스레드 디자인은 여기까지만 보고 채팅 서버에 대한 얘기를 해보도록 하겠습니다.

뭐... 다양한 로직이 있겠지만 아주 기본적인 요소들만 한번 담아보도록 하겠습니다

1. 로그인 요청
2. 섹터의 이동
3. 채팅메시지 발송

우선 1번은 로그인서버를 만들지 않았기 때문에 추후로 미뤄서 고민을 해보도록 하겠습니다.

 

먼저 두번째 사안인 섹터의 이동입니다.

섹터라는 개념은 아마 예전의 TCP fighter에 대한 얘기를 할 때 충분히 언급을 드렸었습니다.

하지만 이번 경우에는 조금 다릅니다.

채팅서버의 경우에는 이 서버가 주체적으로 캐릭터의 움직임을 관리하고 있지 않습니다.

그말은 무엇이냐, 다른 서버와의 통신을 통해(혹은 클라이언트와의 통신을통해) 섹터 정보를 받아들여야 한다는점입니다.

그럼 여기서 말씀드린것과 같이 두가지의 경우가 발생할 수 있겠습니다.

첫 번째는 게임서버와의 데이터 전송을 통해 섹터가 이동되었을때 섹터정보를 받아들인다.
두 번째는 클라이언트와의 데이터 전송을 통해 섹터가 이동되었을때 섹터정보를 받아들인다.

분명 둘의 장단점은 존재할겁니다.

 

첫번째 케이스의 경우에는 게임 서버와의 직접 연결을 통해 데이터를 주고받는만큼 데이터에대한 신뢰도가 있습니다.

그리고 물리적인 거리가 짧기때문에 당연히 딜레이가 줄어들겁니다.

하지만 분명 단점이 있습니다.

채팅서버야 그렇게 바쁜건 아니겠지만 게임서버는 안그래도 바쁜상태입니다.

그런 게임서버에게 채팅서버와의 싱크까지 맞춰주는 그런 연산은 조금 빠듯할 수 있습니다.

 

반면 두번째 케이스의 경우에는 조작의 가능성이 있다입니다.

물론 게임서버에서 게임컨텐츠에 대한 내용을 절대 클라이언트에게 받았을땐 신뢰하지 않습니다.

하지만 이경우는 채팅서버고 섹터의 이동에대한 건만입니다.

섹터의 경우에는 일반적으로 +-1씩만 이동할 수 있으며 이 이상 이동할시에는 조작이라고 판단할 수 있습니다.

그리고 채팅 서버에서 섹터의 이동을 조작한다고 해서 조작한 유저가 크게 얻을 수 있는 큰 이점이 없습니다

 

더군다나 위에서의 암호화와 복호화의 과정을 거쳐야 하기 때문에 풀어나가는데에 있어서 난해함도 존재하고요.

그에 비해서 게임서버의 부담을 줄일 수 있습니다.

서버개발자 입장에서는 크게 내주는 위험부담 없이 게임서버의 부담을 덜수있기 때문에 이 점은 분명히 장점으로 작용할겁니다.

 

채팅서버에서는 두번째 케이스를 선택했습니다.

클라이언트가 직접 좌표를 계산해서 섹터를 전달해주는 방식으로 작동하고 있습니다.(물론 게임서버와는 되어있지 않을겁니다)

당연히 이부분은 상황에따라 달라질수도 있을겁니다.

하지만... 일반적으로 봤을땐 클라이언트가 보내는 섹터의 위치를 현섹터의 위치와 계산해서 정상적인 범위안에 있다고 판단이 된다면 그 클라이언트의 위치를 신뢰하는 방식을 통해서 충분히 이점은 걸러낼 수 있다고 판단하기 때문에 이러한 방식을 많이 채택하고 있는것으로 알고있습니다.

 

 

다음으로 세번째 사안인 채팅 메시지 전송입니다.

채팅 메시지는 다음과 이전의 TCPfighter와 동일하게 주변 9개의 섹터에 데이터를 뿌리는것으로 처리했습니다.

크게 특이점은 없습니다만 참고하실점은 스레드의 디자인에따라 이 부분에서 구현이 달라질 수 있다는 점입니다.

달라질 구현부분은 스레드 디자인에 대한 언급을 하며 추가로 진행하도록 하겠습니다.

 

 

오랜만에 글을 남기느라 고민을 상당히 오래했습니다.

지금부터는 거의 개발보다는 거의 철학이나 디자인에 가까운 수준의 내용들만을 담고있는 글들이 많을텐데요...

이때까지 구현에 대한 부분을 세세하게 정리해놨던 것에 비하면 요새 글들이 많이 구현이 빠지고 거의 틀위주로 잡혀있다는걸 알게 되셨을겁니다.

음... 사실 네트워크 라이브러리라는게 코드수가 그렇게 길지 않습니다.

그리고 게임서버라는건 네트워크 라이브러리 위에 컨텐츠만 끼워넣은 그런 모습입니다.

그러다보니 코드가 생각보다 심플하고 해석하는것이 어렵지 않게 되어있습니다.

추가로 코드를 올리면 금방 따라 칠수있습니다.

하지만 중요한것은 중간중간 내가 쓴 코드로 인해 파생되는 문제에 대한 해결을 스스로가 겪어보고 그걸 해결하는 과정에서 본인 기술이 되는것이 훨씬더 좋은 스펙이 될겁니다.

그리고 이게 잘 녹아들어있는 코드는 여러분들의 훌륭한 포트폴리오가 될겁니다.

만약 제글을 처음부터 끝까지 정독하셨다면 이정도 내용은 충분히 다룰수 있을 것이라고 판단하고 있습니다.

 

다들 좋은 서버 개발자가 되시길 바랍니다.

그럼 오늘도 긴글 읽어주셔서 감사합니다.

다음 글에서는 더 좋은 내용으로 돌아오도록 하겠습니다.

안녕히계세요.

320x100

'게임서버 > namespace univ_dev' 카테고리의 다른 글

Login Server  (1) 2022.05.19
Chatting Server(Multi Thread)  (0) 2022.05.04
LockFreeStack Trouble Shooting  (2) 2022.03.28
DumpClass  (0) 2022.03.28
LockFree  (0) 2022.03.22