Connector

CJB_ny·2022년 2월 22일
0

Unity_Server

목록 보기
29/55
post-thumbnail

오늘은 Listener의 반대 역할을 하는

Connector를 만들 것이다.

1. Connector 필요한 이유

더미클라에서 Connect하는 부분을

이렇게 블로킹으로 사용을 하고 있었다.

(온라인 게임에서는 이런 블로킹함수를 사용하는 것을 최대한 "지양"해야됨)

이런 부분을 담당하는 애가 되겠다.


일단 이렇게 만들어 주고

만들기에 앞서서

서버는

이렇게 대기 상태로 손님을 기다리는 것이 "서버"인데

왜 굳이 연결해주는 애가 필요하냐?

하면 크게 두가지 이유가 있는데

1) ServerCore의 함수중에 Send, Receive 이런것들을 공용으로 사용하면 좋을 거 같아서

2) 서버를 하나로 만들것인지 아니면 분산처리를 해가지고 서버를 여러개를 만들 수도 있기 때문이다. (NPC만 담당하는 서버, 이런식으로)

-> 분산 되어있다면, 이것들을 결국에는 연결을 한번씩은 해줘야 하기 때문에

그래서 분산서버일 경우 서버끼리 연결을 하기위해서는 한쪽은 Listener, 한쪽은 Send, 한쪽은 Connector 이런식으로 되기는 해야한다.

결국, 서버끼리 통신을 하기 위해서 Connector같은 애가 필수적이다.


더미 클라보면

이런 IPEndPoint로 결국

이렇게 소켓을 만들어 준다음에

소켓에서 연결을 해주었었다.


Connector부분

오른쪽에 있는 부분 똑같이 복붙 해주자.

그리고 이전에 했던것과 마찬가지로

이렇게 만들어 주자.

근데, Connect에 AsyncEvent부터 만들어 주자!

이렇게 만들어 주고

그렇다면 결국 연결을 하는 부분은 "상대방"의 주소를 넣어 줘야된다.


그리고 이제

이 socket을 RegisterConnect에다가 넘겨주고 싶은데

지난 번에 배웠던

UserToken

사용하여 넘겨주도록 하자.

그래서 UserToken으로 socket을 넘겨주고

RegisterConnect에 얼규먼트 넘겨준다.

-> Register에서 받아온 UserToken이 objecct타입이기 때문에 Socket으로 형변환하고 socket으로 받아준다.


멤버 변수로 받지 않는 이유는

나중에 유저가 몇백명씩오면

여기서 이렇게 받으면 한번만 받고 끝내는게 아니라 여러번 받을 수 있게

(재사용 느낌과 비슷한듯...?? 아니면말고)

그래서 그냥 Event를 통해서 인자를 넘겨주고 있는 것이다.

그래서 이렇게 pending 체크를 해서 바로 연결이 되었다면

OnCompletedConnect에 넘겨주면 될 것이다.

그리고 OnConnectCompleted에서는

이전과 같이 성공과 에러 여부를 체크를 해주자.

그리고 if 안에서 어떤 Session이 필요할지 모르기 때문에

이렇게 할 수 없어서

지난시간에 _sessionFactory를 만들어서 어떤 세션을 만들어 줄까?를 인자로 받았었다.

Connector도 똑같이 만들어 준다음에

이녀석 에다가 인자로 넘겨주게 되는 것이다.

그래서 이렇게 Func< Session > 을 Connect하는 순간에

어떤식으로 만들어 줄까? (누구로 만들어줄까?)

여기 인자로 넘겨준 것이다.

이렇게 저장을 하고

그래서 여기서 new가 아니라

Invoke를 해가지고 컨텐츠 딴에서 요구한 방식대로 Session을 만들어 줄 것이다.

그래서 이까지 왔다는 것은

소켓만들어주고 == 휴대폰 만들어주고,

문지기한테 Connect까지하고

이제

이 단계로 넘어오게 된 것이다.

그래서 args.ConnectSocket이라는게 있을 것인데

애당초 session.Start()를 하기 위해서는

Session을 가보면

소켓을 인자로 받아줘야지만

(37번째줄) 나중에 RegisterRecv()를 할 때


가보면

Async로 한번 예약을 해준것을 알 수 있다.

기본적으로 Session을 사용을 하려면 소켓이 연결 되있어야하는데

그 소켓이 바로 인자로 넘겨준

ConnectSocket이 될 것이다.

그래서 Start()까지하면 자동으로 RecvEvent가 등록이 된 상태 일 것이고

그 다음으로 해야 할것은 OnConnected를 해주면 될 것이다.

그래서 이렇게보면 거의 Listener와 대칭적으로 만들어 준 것을 알 수 있다.


그래서 이까지 했으면 테스트를 함 해봐야 할것이다.

그런데, 자세히 살펴보면은

우리가 작업을 하고있던 ServerCore의 경우

"서버"용도로 사용 하고있었고

실제로 클라 역할을 하는 것은 "Dummy Client"이다.

(복사해서 Dummy 클라에 넣는거는 세련되지 않으니까)

지금 Connector를 Dummy Client에서 사용할 수 없으니까

새로운 방법 사용하도록 하자.

2. 연결 하는 새로운 방법

나중에가면은 DummyClient, Server, ServerCore 세개를 동시에 사용한다고 했었다.

ServerCore의 경우 실제로 실행되는 프로젝트는 아니고

"라이브러리"로만 사용할 예정이라고 했으니까,

이 부분을 셋팅을 해주도록 하겠다.

ServerCore > 속성 가면

이때까지는

"콘솔 애플리케이션"으로 만들고 있었는데

"클래스 라이브러리"로 변경을 하자.

그 다음

ServerCore > 시작프로젝트로 설정 하고 실행을 하면

에러가 나는 것을 볼 수 있다.

이제 이것은 라이브러리 이기때문에 독립적으로 사용할 수 없다는 얘기이다.

그래서 이제 다른애한테 기생해서 사용이 되어야 한다.

그래서 더미클라랑 Server에서 이녀석을 참조를 해서 사용을 하자.

Server > 추가 > 참조

이렇게 있는데

프로젝트 > ServerCore 체크 > 확인 하면된다.

마찬가지로 DummyClient도 똑같이 해주면된다.


3. DummyClient 연결

그러면 이제 뭘 할 수 있느냐?

ServerCore의 Program을 이전을 시켜 줄 것이다.

이부분 전체 다 오려내서 Server > Program에다가 옮길것이다.

이렇게 옮김.

using도 똑같이 이전을 해주고

못찾고 있어서 직접 using ServerCore를 해주면

그럴면 이제 찾기는 찾앗는데

보호수준 문제가 뜬다.

그래서 이제는 클래스 앞에 public으로 해준다.

(다른 프젝에서도 사용이 가능하도록 열어 주었다.)

Listener, connector 다 public 으로 열어주자.

그러면 이제 에러 안 뜬다.

그다음 이제 ServerCore > Program은 사용 안할꺼라 삭제 ㄱㄱ

그러면 이제

Server = Contents, ServerCore = Engine 딴이 되는 것이다.


그다음 솔루션 > 속성 간다음에

이렇게 설정을 해주면 모든 준비가 끝난 것이다.


그다음 다시

더미클라로 와가지고

우리가 방금 작업한 Connector를 여기다가 연결을 시켜 줄 것이다.

이런 블로킹방식 포함해서 이런 방식들을 Connector방식으로 바꿔 줄 것이다.

그런데 더미클라에서 Connector사용할려면

_sessionFactory를 하나 지정을 해줘야되고

_sessionFactory에서는 어떤식으로든 session을 하나 만들어 줘야한다.

그렇다는 것은

Server에서 사용하고 있던

이 GameSession부분을 거의 비슷하게 사용한다는 얘기이다.

그래서 DummyClient로 복붙 한다.

그런데 더미클라에서 조금 달라지는 부분은

더미클라의 밑부분에서

이런부분들을 옮길 필요가 생긴다.

보내는 작업을 여기서 하고있엇는데

OnConnected를 한다음에 여기서 해주면 된다.

위에 있는것들 다 지워주자.

그리고 Send의 경우 지금 GameSession은 Session을 상속 받았으니까

이렇게 바꿔주면 된다.


그 다음 이제

받는 부분, 쫒아내는 부분도 비슷하게 해주면된다.

더미클라에서 받을 때 보면은

블로킹 계열의 Receive를 하고있었는데,

recvBuff를 실시간으로 만들어서 Receive를 하고 있었다.

그런데 이부분 삭제를 해도되는게,

애당초 우리가

Session에서

recvBuff를 애당초 여기에서 연결을 해주고 있었다.

그래서 삭제해도 OK.

그리고 나머지는 이렇게 냅두도록 하겠다.


이제 그 다음에 해야되는 것은 GameSession은 만들어 줬으니까,

이제는 _listener를 사용했던것 처럼 Connector를 사용하도록 하겠다.

DummyClient > Program > Main

그 다음에 이녀석이 해야되는 것은

Connect에다가 우리가 연결할 endPoint주소를 넣어주고,

어떤 세션을 어떤식으로 만들어 줄까?를 일단 간단하게 람다로 만들어 주자.

그래서 Connect가 뭘하는 지보면은

밑에서 RegisterConnect를 해줄 것이고

성공적으로 ConnectAsync가 완료가 되면은

이부분이 호출이 될 것이다.

그래서 OnConnected로 갈 것이고 > 처음에 우리가 매핑했던 DummyClient의

이부분으로 올 것이다.

그리고 DummyClient의 이렇게 소켓을 만들고 입장을 하는 부분은 다 날려도 될 것이다.

이렇게 까지 해주면된다.

그리고 이제 세션을 하나만 만든체로 잘 동작하는 지 보도록 하겠다.

그래서 보내는 부분과 받는 부분까지 정상적으로 잘 되는 것을 확인하였다.

4. 정리

우리가 작업하던 ServerCore 라이브러리에서

Server && DummyClient를 라이브러리를 참조를 해서 만드는 부분까지 수정을 해보았다.

Plus Connector작업까지

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

0개의 댓글