Serialization #4

CJB_ny·2022년 2월 25일
0

Unity_Server

목록 보기
38/55
post-thumbnail

오늘은 리스트를 주고 받은 부분 할 것이다.

이런식으로 리스트안에 기본 자료형인 int가 들어가 있다고 하면은

string, byte[]를 넘겼던 것과 마찬가지로

List에 몇개짜리가 있는지 먼저 밀어 넣어 주고

그 다음에 데이터를 밀어넣는 작업을 똑같이 해주면 될 것이다.


그런데 List안에 있는게 구조체 (== struct라면?)

우짤래??

이런식으로 int형 List가 아니라 SkillInfo라는

데이터 구조체로 저장이 되어있다고 하면은

이 skills를 밀어 넣을 때는 과연 어떻게 해야되는지가 또 궁금하다.

이렇때는 그래서 어떻게 해야할지가

고민이 된다.


string과 똑같이 일단 해주면 되는데

nameLen이 아니라

이렇게 해주고 이 안에서 뭔가를 해주어야 할 것이다.

그러면 skill하나마다 데이터를 밀어 넣어주는 작업을 해야된다는 것인데

그렇다는 것인 포이치 잠시 놔두고

SkillInfo에 가가지고 뭔가를 만들어 주도록 하자.

그래서 여기에 기존의 Write에서 인자를 sendBuff를 참조한 s와 ref로 count를 그대로 받아와서

기존과 같이 만들어 주면 될 것이다.

그래서 Write는 이런식으로 맞춰 주면 된다.

그리고 밑에 다시 내려가서 작업을 하면되는데

이렇게 작업을 해주면

내가 들고 있는 skill마다

루프를 돌면서 하나씩 하나씩

span으로 찝어준 영역에다가 넣어주게 될 것이다.

그다음

SkillInfo안에 Read도

이렇게 인터페이스를 파주자.

그리고

이게 기존의 Read인데 커닝을 해서 채워주자면은

이렇게 채워주자

(float의 경우 ToSingle이다)

이렇게하면 id, level, duration다 뽑을 수 있다.


그래서 나중에

리스트를 정의를 할때 리스트 안에다가 뭐가 들어 올지를

구조체로 선언을 해줄 것인데

이런식으로 구조체를 만들어서 Write, Read를 편하게 할 수 있게 만들어 준다음에

그거를 나중에

실제 Write안에서

이런 부분안에서 만들어줄때 사용하면 될 것이다.

그러면 찐 Read에 Read하는 부분 만들어 주도록 하자.

이렇게하면 skill이 몇개가 들어가있는지 skillLen으로 추출을 할 수 있을 것이다.

그래서 for를 돌면서 skill을 뽑아와서 skills List에다가 뽑아온 것을 넣어주면 될 것이다.

혹시 모르니까 Clear 앞에 넣어주고

이렇게!

그럼 이때까지 작업한거 다시 클라세션에다가 복붙 해주자.

여기서 콘솔을 찍고있었는데

이렇게 해주면됨

근데 지금 skills에다가 값을 안 넣어주었었다.

packet에다가 스킬 정보를 넣어 줘야한다.

이렇게 넣어주도록 하자.

이렇게 4개정도 만들어 주자.

그래서 실행을 해보면

왜 에러가 나는지 보면은 코드를 잘못침

지금은 잘된다.

지금 간단한 포폴이거나 그런거를 만들때는

public struct SkillInfo
{
public int id;
public short level;
public float duration;

        public bool Write(Span<byte> s, ref ushort count)
        {
            bool success = true;
            success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), id);
            count += sizeof(int);
            success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), level);
            count += sizeof(short);
            success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), duration);
            count += sizeof(float);

            return success;
        }
        public void Read(ReadOnlySpan<byte> s, ref ushort count)
        {
            id = BitConverter.ToInt32(s.Slice(count, s.Length - count));
            count += sizeof(int);
            level = BitConverter.ToInt16(s.Slice(count, s.Length - count));
            count += sizeof(short); ;
            duration = BitConverter.ToSingle(s.Slice(count, s.Length - count));
            count += sizeof(float); ;
        }
    }
    

SkillInfo같은 부분을을 한땀한땀 이렇게 만들어도 괜찮음..

단점 : 반복작업 많아지고 실수 많아질 확률 올라감.

그래서 이런 패킷들을 조금더 자동화해서 만드는 방법을 알아 볼것이다.


그래서 이런 직렬화를 할때

굉장히 자주 사용하는 것중 하나가

구글의 "프로토 버프"나 "플랫 버퍼" 둘중 하나를 골라서 사용하게 되는데

프로토 버퍼는

이런식으로 인스턴스를 만들어서

이렇게 변환을 하는 작업을 거치게 되는 방법이고

플랫 버퍼는

여기에다가 막바로 집어 넣는 방식으로 구현이 되어있다.

그래서

프로토 버퍼 는 인스턴스를 만들어서 변환을 하는데

성능상으로는 조금 떨어지겠지만

코드를 만들때 직관적이라 좋다

-> 이방법을 사용을 하자.

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

0개의 댓글