채팅 테스트 #2

CJB_ny·2022년 3월 4일
0

Unity_Server

목록 보기
46/55
post-thumbnail

Dummy클라를 보면은

이런식으로 한번만 "접속"을 하고있었다.

그래서 일단 더미 클라에

SessionManager를 만들어 주자 이렇게

이녀석은 서버의 세션메니저와는 하는 역할이 다르다.

그리고 더미클라의

Program에서 이렇게 retrun 하는 부분

이렇게 바꿔주도록 하자.

그리고 connect를 한번만 하고있었는데

여러번 할 수 있게 해야되니까

Connector.cs > Connect에 인자를 하나 더 넣어주도록 하자.

그래서 옵션으로 count를 넘겨준다음에 (그냥 초기값을 1로 한 것임)

for문 안에 원래 코드를 넣어 주도록 하자.

그럼 이제 다시 더미클라 > Program으로 가서

클라가 몇개를 접속이 가능하게 할 것인지 옵션으로 넣어줄 수 있는데

이렇게 10을 넣어준다. 10개의 클라가 접속이 가능하도록.

그다음 ServerSession >

이부분 다 날려주도록 하자.

그리고 이부분 PacketSession을 상속받도록 변경해준다.

그리고

OnRecv 부분

이렇게 수정을 해주도록 하자.


그리고 더미클라 > Program으로 가면은

10개의 세션을 만들고 try안에서 뭐 아무것도 안하고 있었는데

try안에서 뭔가 채팅패킷을 쏘도록 강제로 만들어보도록 하자.

그래서 SendForEach라는 인터페이스를 만들어 주면되고

250ms로 한 이유는 보통 이동패킷을 1초에 4번정도 보내기 때문에 이렇게 한 것임

그래서 SessionManager로 와가지고

SendForEach를 만들어 주는데

chatPacket.Write에서 추출한 것을 segment에 박아놓고

Send로 segment를 보낸다.

이렇게하면

10명이 접속을 해가지고

동일한 작업을 하게 될 것이다. ( 작업 == Hello Server!");

그리고 Handler에서 이름을 이렇게 바꿔 줘야한다.


그리고 이제

내가 채팅을 보내고 -> 서버에서 이것을 받아서

-> 다른 클라한테 뿌려 줘야하는데

-> 뿌렸을때 받는 클라의 "처리"를(어떻게 받을지를) 만들면

일단 PacketHandler로 가가지고

받아서 처리를 할 chat은 S_chat이다 왜냐하면

서버에서 보낸 것이니까

그리고 session -> ServerSession으로 형변환 해준것을

serverSession이라는 이름에 할당 ㄱㄱ.

그러면 이제 S_chatHandler가 무슨 메세지를 했는지 출력을 하면되는데

일반적인 채팅 프로그램이라면 그냥 출력을 하면되는데

우리는 지금 클라에 사람이 엄청 많을 수도 있다는 것을 가정을 하고 해야한다.

그런데 일단 너무 많이 출력될 수 있으니까

특별한 경우에만 출력을 해주도록 하자.

playerId가 1일 경우에만 출력을 해주면될 것이다.


Register 자동화

그런데 지금 실행하면 안될텐데

우리가 Server > ServerPacketManager에서

이렇게 Register로 수정을 해주고 Server > Program에다가

이렇게 등록을 해주었었다.

더미클라에서 이작업을 안했어가지고

에러가 날텐데

이작업을 까먹고 안할 수 있으니 이부분도 자동으로 되게끄름 해주도록 하자.

그래서 Server 에서 Register를 하는 부분 삭제를 한다음에

ServerPacketManager >

이부분의 PacketManager를 조금 수정을 하도록 하자.

이렇게 막바로 뱉어 준다음에

PacketManager의 생성자에서

이렇게 추가를 해주돌록 하자.

그리고 이작업이 잘 수행되기 위해서는

PacketGenerator > PacketFormat 에서 수정을 해줘야하는데

이렇게 관리를 하던 것을

이렇게 수정을 해주도록 하자.

이렇게하면 이제 자동화 처리가 될 것이다.

그다음 PacketGenerator 빌드 > 갱신 ㄱㄱ

다시 배치파일 실행 ㄱㄱ

이렇게 하니 잘 갱신이 되었다.

그리고 이상태에서 실행을 해보면

이런식으로 잘 받아 오고 있는 것을 볼 수 있다.


잘되기는 하는데

이것만으로는 모든 애들이 전송이 다 잘되는것인지 수상하니까

GameRoom -> 이렇게 수정

그리고 실행을 해보면 번호가 바뀌면서 실행이 잘되어지고 있다.

그런데 같은 번호가 10번씩 한번에 보내지고있는데

만약 10번이 Hello Server를 보냈다고 가정을 하면은

락을 걸어서 모든 클라들한테 이렇게 메세지를 보내고 잇었는데

그렇다는 것은 10명의 유저들이 각각 한개의 패킷을 보낸다고 하면은

10명의 유저들마다

이런식으로 10번을 반사를 해주고 있었으니까

10 * 10 즉 100번의 패킷을 우리가 지금 보내고 있는 것이다.

이부분이 굉장히 중요한데

"동접" 즉 어떤게임 MMO 서버에

동접자 5천명, 만명

이러는데

만명의 서버가 더 뛰어나보이지만 결국, mmo에서 가장 중요한것은

서버성능도 어느정도 연관성이 있겠지만

컨텐츠가 또 어떤식으로 구성이 되느냐도 굉장히 또 중요하다.

"특히나" 이런식으로

GameRoom같은데 옹기종기 모여 있어가지고

패킷을 BroadCast를 할 때

모든 유져들한테

이렇게 전송을 해야하는 상황이 가장 문제가 되는 것이고

이게 알고리즘 시간에 배운것으로 치면은

Order of n제곱의 시간 복잡도를 가진다.

왜냐하면 자기자신한테만 뿅하고 보내주는게 아니라

주변의 모든 애들한테 다 보내줘야 하니까

100명의 유져가있다면 실제로 100명이 다 움직이니까

100 * 100 이라 10000번의 패킷을 전송하는 것이다.


그래서 결국 MMO를 만들때 결정을 해야되는데

같은 공간에 모여있을 때

과연 몇명이 될 것인가??

롤같은 게임은 게임자체가 하나의 공간이 되겠지만

그게 아니라 MMO같은 경우에는 사실은

BroadCast해야되는 범위가 == "시야"가 될것이다.

내화면에 보이는 모든 유저들한테는 내가 움직이는 것을 뿌려야지만

내가 움직이는 것을 알 수 있을테니까

그래야 화면에 똑같이 출력이 가능하다.

그래서 결국,

나중에 복잡한 MMO를 만든다고 가정을 하면은

BroadCast하는 부분을 관리를 해줘야 한다는 것이다.


그래서 우리가 Generate를 할때 옵션으로 count = 10까지는 괜찮았는데

이것을 늘리면 어떤 문제가 발생할지 궁금하다!!

1. 클라 접속이 많을 경우

포트폴리오 만들 떄는 10명으로 하고 쿨하게 넘기면되는데

이런식으로 숫자를 점점 100, 500 이런식으로 늘리게되면은

서버가 힘들어 하게 될 것이다.

100까지는 실행이 되는데 메모리가 계속 올라가는 것은 좋은 징조는 아니다.

지금 이게 Send하는게 계속 밀려가지고

결국 쓰레드가 생성된다는

얘기가 되는데

GameRoom에서 BroadCast하는 부분에서 BreakPoint를 잡아보도록 하자.

여서 잡고 ㄱㄱ

그러면 아직은 잘되는데

쓰레드를 보면은

오마이갓!

지금 쓰레드들이 ㅈㄴ 많이 있다 엄청 안좋은 것이다.

이게 쓰레드들이 어디에있는지 보면은

거의 전부 여기에서 기다리고있다.

지금

이곳

여기에서부터

받아와서

BroadCast부분까지 가는 것인데

C_chat을 0.25초마다 100명이 계속 보내고있는데

그 100명을 하나씩 처리를 할때마다

그 100명한테

락을 잡고 뿌리는 작업을 하고있었다.

그러면 0.25초마다 10000번씩 -> 1초마다는 4만번씩 락을 잡고 실행 -> 락풀기

이것을 반복을 하는데

할일이 너무 많다.

그런데 지금 여기서 "lock"을 잡고있는게 가장 큰 문제가된다.

여기서 근데 밀려가지고 한녀석이 제때 처리가 되지 않으면은

쓰레드들이 회수가 안되어서

쓰레드 풀에서 새 쓰레드를 생성을 해서 보낸다.


식당 예제로 보면은

답도 없이 작은 주방이라 1명밖에 못들어가는 주방인데

직원 100명을 뽑아가지고 일을 시켰는데

일이 느리다고 직원을 더뽑아서 일을 시키는 셈이다.


그래서 서버는 모든 부분에서 락을 잡고 실행을 하면

어느곳에서 몰리게 될때

성능부화가 심해진다 -> 인게임에서는 렉이 걸린다.

( 간단한 포폴 같은 경우에는 ㄱㅊ)

그러면 실제 MMO에서는 도대체 어떻게 이것을 관리를 하는것일까??

이런식으로 락을 잡아서 모든 로직을 다 실행하는 것이 아니라

예를들어 GameRoom을 실행하는 녀석은 한명만 실행을 하도록 만들어 줘야한다.

쓰레드들은 그냥 "큐" 같은데 일감을 놔두고

GameRoom을 담당하는 녀석이 여유가 될 때 와가지고 밀린 일감들을 혼자 다 처리를 하는것이다.

쓰레드들은 그냥 "큐" 같은데 일감을 놔두고 GameRoom을 담당하는 녀석이 여유가 될 때 와가지고 밀린 일감들을 혼자 다 처리를 하는것이다.

이게 핵심이다.

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글