2012-10-04 2 views
1

예상 메시지 클래스를 사용하지 않을 때마다 parseFrom(bytes) 시도 할 때 InvalidProtocolBufferException 얻을 것이라고 생각했습니다.직렬화 된 프로토콜 버퍼에 어떤 종류의 메시지가 있는지 어떻게 알 수 있습니까?

try { 

    LoginMessage msg = LoginMessage.parseFrom(bytes); 
    // ... use msg ... 

} catch(InvalidProtocolBufferException exception) { 

    ErrorMessage error = ErrorMessage.parseFrom(bytes); 
    // ... do something ... 
} 

을 그리고 내 메시지는 다음과 같습니다 :

내 코드는 다음과 같습니다

message LoginMessage 
{ 
required Status status = 1; 
optional UserMessage user= 2; 
}  

message ErrorMessage 
{ 
required Error error = 1; 
} 

TeamStatusError열거 형 있습니다. I는 ErrorMessage 초래한다 코드를 실행할 때

, 그것은 LoginMessage을 파싱 모두 열거 혼란 : error 필드 status 필드.

그럼이 두 가지 유형의 메시지를 어떻게 다르게 할 수 있습니까?

최적화를 위해 구조적 유형 지정을 사용하므로 필드 이름이나 메시지 유형을 전송하지 않지만이 문제를 해결하기위한 실용적인 방법은 무엇입니까? 을 LoginMessage에 삽입하고 항상 LoginMessage을 반환하고 싶지 않습니다.

나는 다른 메시지가 ErrorMessage error = 15000;처럼 사용하지 않습니다 숫자로 error 필드 인덱스를 설정하는 방법에 대한 생각했지만,이 맞다면 나도 몰라, 나 항상 작동하는지 LoginMessage의 모든 필드가 있다면 (상상 옵션, 작동합니까?).

답변

2

아니요, 오류가 없습니다. 열거 형은 직렬화 될 때 정수가되며 예기치 않은 값이 확장 데이터에 저장되므로 필드 1은 메시지간에 완전히 바꿔 쓸 수 있습니다. "사용자"는 선택 사항이므로 존재하지 않는다면 상관 없습니다. 일 경우에는 예상되지만 확장 데이터에 저장됩니다.

최적화를위한 구조 입력을 사용하는 것, 그래서 필드 이름 또는

올바른

메시지 유형을 전송하지 않는다; 필드 번호와 데이터 만 전송됩니다. 이름이 없습니다.

메시지를 구분하는 가장 좋은 방법은 몇 가지 종류의 접두사를 사용하는 것입니다. t이 작업을 수행하는 가장 쉬운 방법은 래퍼 메시지입니다 : 직렬화 복원 할 때

message SomeWrapper { 
    optional LoginMessage login = 1; 
    optional ErrorMessage error = 2; 
} 

그런 다음, 단지 값이있는 필드를 확인. 분명히 직렬화 할 때 SomeWrapper에서도 값을 래핑해야합니다. 포함되지 않은 선택적 값은 비용이 0이됨을 유의하십시오.

관련 문제