-
스파르타) The Last Rollback (D-32, Node.js 게임 서버 최종 프로젝트)TIL-sparta 2024. 7. 26. 20:04
> 과제 진행 간 완료한 사항 및 문제점과 해결 과정을 정리해보았다.학습 키워드: Protobuf, Node.js, C#, Unity, TCP, serialize, deserialize, enum
1. 완료한 과제 진행 사항
1) ~기능 구현 완료:
35 update 통지 패킷 구조 추가 by donkim1212 · Pull Request #36 · eliotjang/the-last-rollback-server
관련 Issue close #35 작업 내용 #35 에서 명시한 작업 완료 주요 변경 사항 클라이언트의 핸들러가 받는 두 번째 인자를 IMessage 타입으로 원상 복구 변경 전: 변경 후: sendNotification 기능 활성화
github.com
- Notification 패킷 구조 추가 및 패킷 송수신 구조 수정
- 기존 구조에서는 클라이언트가 RequestPacket을, 서버가 ResponsePacket 만을 보내고 있었는데, 초반에는 다른 패킷 타입의 추가를 고려하지 않고 설계해서 핸들러의 인자를 IMessage 타입에서 ResponsePacket 타입으로 바꿔두는 등 이것저것 바꿔둔 부분이 많았으나, 회의를 통해 최종적으로 바깥 패킷 (oneof payload를 가지는) 구조를 추가하는 것으로 결론이 나서 코드 작성에 혼선이 없도록 구조를 다시 원래의 형태로 수정하게 되었다.
- Notification 패킷 구조를 추가하면서 Response 패킷 구조와 동일한 payload를 쓰게되는 상황이 있는지 토의해본 결과 몇몇 payload message 구조는 통지와 응답 패킷에 똑같이 사용될 수 있는 것으로 결론이 나서 이를 같은 핸들러에서 처리할 수 있도록 외부 패킷 (Response | Notification)을 우선적으로 역직렬화 하고, 응답 패킷의 경우 에러 코드와 메세지를 따로 받아서 처리할 수 있는 PacketErrorCodeHandler 클래스를 생성하게 되었다.
- 그 외 상세 내용은 위 PR 및 연결된 Issue 참고
2. 과제 진행 간 문제점
1) Protobuf로 직렬화된 key의 값이 undefined인 문제 (해결):
Figure 1. payloadType이 undefined로 나타나는 문제 발생 // 클라이언트의 패킷 전송 코드 ... public void Send(IMessage payload) { // determine payload type Type t = payload.GetType(); string msgName = t.Name.Replace("_", String.Empty); MsgId msgId = (MsgId)Enum.Parse(typeof(MsgId), msgName); // wrap in reqPkt RequestPacket reqPkt = new RequestPacket { ClientVersion = "1.0.0", // 임시 Sequence = 1, // 임시 Token = "token1", // 임시 PayloadType = (ushort) msgId, }; PropertyInfo propInfo = reqPkt.GetType().GetProperty(msgName); propInfo.SetValue(reqPkt, payload); _session.Send(reqPkt); } ...
Protobuf 패킷 전송 구조를 손보는 도중 특정 패킷 전송 시 payloadType 값이 undefined가 되는 문제가 있었다. PayloadType 값을 컴파일된 protobuf 파일의 enum 값으로 얻어오고 있었기 때문에 잘 못된 값을 넣어줄 수가 없는 구조여서 문제가 무엇인지 검색하면서 StackOverflow의 어느 글을 통해 원인을 바로 알게 되었다. 아래는 해당 글의 답변이 참조한 공식 문서 내용이다.
Figure 2. 공식 문서 발췌 공식 문서에서 정의하기를, enum 의 기본값은 0인데, scalar 값이 encode된 후에는 이 값이 기본 값인지 직접 지정한 0 값인지를 알 수 없고, 기본 값으로 지정된 scalar 메세지는 wire에 직렬화되지 않는다고 한다. 이러한 특징으로 인해 공식 문서의 예시에서는 0 번째 매핑을 UNSPECIFIED로 사용하고 있다.
우선은 서버에서 undefined payloadType을 받게 되면 0으로 치환해주도록 수정했으나, 추후 패킷 매핑 번호를 손보게되면 0번을 제외하도록 해야겠다.
3. 기타 사항
1) Unity에서의 JWT 토큰 저장? (짧):
서버에서 전송해주고 있는 토큰을 클라이언트에서 어디에 저장하고 어떻게 보내줄 지?
찾아보기:
- PlayerPref, Unity Authentication
--
REFERENCES:GitHub - eliotjang/the-last-rollback-server: 액션 MORPG
액션 MORPG. Contribute to eliotjang/the-last-rollback-server development by creating an account on GitHub.
github.com
> 프로젝트 repo
Language Guide (proto 3)
Covers how to use the version 3 of Protocol Buffers in your project.
protobuf.dev
> Protobuf 공식 문서 (Figure 2)
728x90'TIL-sparta' 카테고리의 다른 글
[TIL] TypeScript 배우기 (짧) - 1 (0) 2024.07.28 LeetCode) 1211. Queries Quality and Percentage 풀이 (0) 2024.07.28 스파르타) The Last Rollback (D-33, Node.js 게임 서버 최종 프로젝트) (0) 2024.07.25 스파르타) The Last Rollback (D-34, Node.js 게임 서버 최종 프로젝트) - Protobuf (3) (2) 2024.07.25 스파르타) The Last Rollback (D-35, Node.js 게임 서버 최종 프로젝트) - Protobuf (2) (0) 2024.07.23 - Notification 패킷 구조 추가 및 패킷 송수신 구조 수정