기본적으로는 C#의 Socket을 사용해서 서버를 연결합니다.
패킷의 구성
패킷은 Sequence, PacketID, BodySize, Body 등으로 나뉘어져 있습니다.
Body를 제외하고는 각각 1~4 바이트로 구성이 돼있으며
Body의 경우에는 Protocal Buffer를 사용합니다.
패킷을 받게 되면 각 Body를 제외한 부분을 바이트로 파싱을 합니다.
Body는
Wire Type 을 사용
각 필드 * 3바이트(8) + Wire Type을 사용해서 필요한 값을 정함
ex) Field3 에 Wire Type 1로 하고 값이 9928일 경우 (double로 → 8바이트)
19(3*8 + 1 16진수) 00 00 00 00 00 64 C3 40
ex) Field2 에 Wire Type이 2이고 값이 4999864(string)일 경우
12(2*8 + 2 16진수) 0B(뒤에 길이 0B == 11) 08 1E 12 07 34 39 39 39 38 36 34
다만 Wire Type이 0일 경우 값을 추론해서 사용해야함.
MSB (Most Significant Bit) 규칙:
각 바이트의 최상위 비트 (MSB):
- MSB = 1: 다음 바이트가 더 있음 (계속 읽기)
- MSB = 0: 마지막 바이트 (여기서 끝)
0x96 0x01 = 10010110 00000001
↑ ↑
MSB=1 MSB=0
(계속) (끝)
// Wire Type 상수
WIRE_TYPE_VARINT = 0;
WIRE_TYPE_64BIT = 1;
WIRE_TYPE_LENGTH_DELIMITED = 2;
WIRE_TYPE_START_GROUP = 3;
WIRE_TYPE_END_GROUP = 4;
WIRE_TYPE_32BIT = 5;
을 규칙으로 해서 파싱을 합니다.
Body내의 데이터가 하나의 프로토콜 버퍼로 이루어져 있다면, 기본으로 제공하는 파싱 메소드로 파싱하면 되지만,
Body내의 데이터가 여러개의 프로토콜 버퍼 및 여러가지의 변수가 있다면, 위의 구조로 파싱을 하게 됩니다.
통신 과정
- 클라이언트에서 요청 패킷을 보냅니다.
- 서버에서는 받았다는 응답 패킷을 보냅니다
- 서버에서 필요할때 Notification을 보내고 클라이언트는 해당 Notification에 맞는 명령을 실행합니다.
- 만약, 에러코드를 받았을 때, 에러코드로 기획데이터로 조회하고 팝업을 띄워줍니다.
- 에러코드를 받고 난 뒤, 각 컨텐츠 및 상황에 따라 정의된 CallBack을 호출하게 됩니다.
- 특정 에러코드(서버가 심각한 상황 or 접속 중 점검 상황) 일시 즉시 연결을 끊고, 메인 타이틀로 진입 하지 않는 이상 접속을 하지 않는 상황이 됩니다.
- 소켓 연결
- 소켓은 5초에 한번씩 핑을 보냅니다
- 5초에 한번씩 연결을 검사 합니다.
- 만약, 연결이 끊겨있을 경우 5초->10초->15초…->60초->60초 에 한번씩 연결을 시도합니다..
- 서버에서 특정한 에러를 받았을 경우 연결을 끊거나, 게임 로비로 돌아갑니다.
- 만약, 연결을 시도중일 때, 다시 연결을 시도한다면 무시를 합니다.
- 매칭에 관련한 시도를 했을 때, 연결이 끊겨있다면, 다시 재연결 시도를 합니다.
- 만약, 정의돼있지 않던 패킷 ID 및 파싱을 할수 없는 데이터를 세번 이상 받았을 경우에는 서버 상태가 비정상이라고 판단 하여, 연결을 끊습니다.