首页 > 解决方案 > 如何将包含自定义格式定义的消息与 Protocol Buffers for Python 一起使用

问题描述

我正在尝试使用协议缓冲区开发客户端,以通过 MQTT 通信与服务器进行通信。

我用协议的一个子集做了一个小测试,但它不起作用。我不知道为什么。

协议定义:

syntax = "proto2";

message EventHeader {
    // Gw id that generated the event
    required string gw_id = 1;
    // Sink id if relevant for event
    optional string sink_id = 2;
    // Random event id to help duplicate event filtering
    required uint64 event_id = 3;
}

enum OnOffState {
    ON = 1;
    OFF = 2;
}

message StatusEvent {
    required EventHeader header = 1;
    required uint32 version = 2;
    required OnOffState state = 3;
}

protoc 生成的 python 代码

from protobuf3.message import Message
from protobuf3.fields import EnumField, StringField, UInt64Field, MessageField, UInt32Field
from enum import Enum


class EventHeader(Message):
    pass


class StatusEvent(Message):
    pass


class OnOffState(Enum):
    ON = 1
    OFF = 2

EventHeader.add_field('gw_id', StringField(field_number=1, required=True))
EventHeader.add_field('sink_id', StringField(field_number=2, optional=True))
EventHeader.add_field('event_id', UInt64Field(field_number=3, required=True))
StatusEvent.add_field('header', MessageField(field_number=1, required=True, message_cls=EventHeader))
StatusEvent.add_field('version', UInt32Field(field_number=2, required=True))
StatusEvent.add_field('state', EnumField(field_number=3, required=True, enum_cls=OnOffState))

使用定义的消息的 Python 代码

msg = message.StatusEvent()
header = msg.header

header.gw_id = 'gateway_test'
header.event_id=random.randint(0,2**64-1)

header.sink_id='sink_test'
msg.version = 0
msg.version = message.OnOffState.ON

我得到的错误

  File "/home/dc/svn/Code/APS/Application/BigBrother/trunk/Client.py", line 23, in run
    header.gw_id = 'gateway_test'
  File "/usr/local/lib/python3.5/dist-packages/protobuf3/fields/base.py", line 87, in __set__
    self._convert_to_wire_type(value))
  File "/usr/local/lib/python3.5/dist-packages/protobuf3/message.py", line 185, in _set_wire_values
    msg._set_wire_values(number, FIELD_VARIABLE_LENGTH, self.encode_to_bytes(), idx)
  File "/usr/local/lib/python3.5/dist-packages/protobuf3/message.py", line 204, in encode_to_bytes
    self._check_required_fields()
  File "/usr/local/lib/python3.5/dist-packages/protobuf3/message.py", line 159, in _check_required_fields
    raise KeyError("Some required fields are missing: " + ", ".join(missing_fields))
KeyError: 'Some required fields are missing: event_id'

我不明白我应该如何用数据初始化我的消息。当我尝试填写一个字段时,python 系统地崩溃告诉我我首先必须初始化另一个字段。

我使用 Python 3.5.2 进行此测试。

我基于此页面上的工作

标签: pythonprotocol-bufferspython-3.5

解决方案


您使用的 protobuf3 是一个存档项目https://github.com/Pr0Ger/protobuf3。请使用 pypi.org/project/protobuf。


推荐阅读