python - 如何将包含自定义格式定义的消息与 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 进行此测试。
我基于此页面上的工作
解决方案
您使用的 protobuf3 是一个存档项目https://github.com/Pr0Ger/protobuf3。请使用 pypi.org/project/protobuf。
推荐阅读
- google-apps-script - 谷歌表单触发选项选择警报
- php - 从 SQL 表中获取文件列表,在 PHP 中显示并检查文件是否处于活动状态
- python - PySpark Dataframe 的最佳实践 - 删除多列?
- r - 如何将R中的月份日期(mm.yy)转换为月份日期(mon yyyy)
- c++ - 将 Eigen::Map 与结构数组一起使用
- google-analytics - 核心报告 API
- r - 仅在 ggplot2 中为 eigenvector>10 添加标签
- javascript - 将下载文件从浏览器应用程序拖放到 Windows 应用程序,如 Outlook、打印机队列
- sql - MS Access 查询:在 Switch 函数或 IIF 函数中使用 Select 语句
- python - 有没有一种简单的方法可以将目录的特定部分复制到 Dockerfile 中?