【问题标题】:Why gRPC Python does not see first field?为什么 gRPC Python 看不到第一个字段?
【发布时间】:2020-05-05 15:45:20
【问题描述】:

Python gRPC 消息不序列化第一个字段。我多次更新了原型并清理了所有东西,但它没有修复。您可以看到日志,settings_dictstop 字段,但在将这些字段传递给 AgentSetting 后,在日志和服务器端看不到它。我也尝试手动传递stop 字段,但也没有看到。烦人的事情是 gRPC 不会抛出任何异常,它接受 stop 字段但它没有发送到服务器,打印时在 AgentSetting 中也看不到它,但 stop 字段可以像 agent_setting.stop 一样访问。

这是我的原型文件:

syntax = 'proto3';

import "base.proto";

message ConnectionCheckRequest {
  string host_name = 1;
}

message RecordChunkRequest {
  string host_name = 1;
  string name = 2;
  bytes chunk = 3;
  uint32 chunk_index = 4;
  uint32 chunk_number = 5;
}

message AgentSetting {
    bool stop = 1;

    bool connection = 2;
    bool registered = 3;

    string image_mode = 4;

    uint32 sending_fail_limit = 5;
    uint64 limit_of_old_records = 6;

    string offline_records_exceed_policy = 7;
}

message AgentSettingRequest {
    AgentSetting agent_setting = 1;
    string host_name = 2;
}

message AgentSettingResponse {
    AgentSetting agent_setting = 1;
}

message AgentRegistryRequest {
    AgentSetting agent_setting = 1;
    string host_name = 2;
}

service Chief {
  rpc agent_update_setting(AgentSettingRequest) returns (AgentSettingResponse) {};
  rpc agent_registry(AgentRegistryRequest) returns (Response) {};
  rpc send (stream RecordChunkRequest) returns (Response) {};
  rpc connection_check (ConnectionCheckRequest) returns (Response) {};
}

这是我的代码 sn-p:

def register():
    try:
        with insecure_channel(settings.server_address) as channel:
            setting_dict = settings.dict()

            logger.info(f'\nSetting Dict: {setting_dict}')

            agent_setting = AgentSetting(**setting_dict)

            logger.info(f'\nAgent Setting Instance: \n{agent_setting}')

            response = ChiefStub(channel).agent_registry(
                AgentRegistryRequest(
                    agent_setting=agent_setting,
                    host_name=settings.host_name
                )
            )
            return response
    except Exception as e:
        logger.exception(f'Register Error: {str(e)}')
        return Response(success=False, message="failure")

日志:

|2020-05-05T18:33:56.931140+0300| |5480| |INFO| |reqs:register:28| 
Setting Dict: {'stop': False, 'connection': True, 'registered': False, 'image_mode': 'RGB', 'sending_fail_limit': 3, 'limit_of_old_records': 5368709120, 'offline_records_exceed_policy': 'OVERWRITE'}
|2020-05-05T18:33:56.932137+0300| |5480| |INFO| |reqs:register:32| 
Agent Setting Instance: 
connection: true
image_mode: "RGB"
sending_fail_limit: 3
limit_of_old_records: 5368709120
offline_records_exceed_policy: "OVERWRITE"

【问题讨论】:

    标签: python grpc grpc-python


    【解决方案1】:

    在 proto3 中,未设置的值和默认值被认为是等价的。

    所以stop: false 被认为等同于完全省略stop

    Language Guide (proto3)

    请注意,对于标量消息字段,一旦消息被解析,就无法判断该字段是显式设置为默认值(例如布尔值是否设置为 false)还是根本没有设置:您应该在定义消息类型时请记住这一点。例如,如果您不希望默认情况下也发生该行为,则不要在设置为 false 时打开某些行为的布尔值。另请注意,如果标量消息字段设置为其默认值,则该值将不会在线上序列化。

    请注意,这与 proto2 不同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多