为什么gRPC Python看不到第一个字段?

2024-10-03 06:20:57 发布

您现在位置:Python中文网/ 问答频道 /正文

Python gRPC消息不会序列化第一个字段。我更新了protos并清理了很多次,但都没有修复。您可以看到日志,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) {};
}

这是我的代码片段:

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"

Tags: namehostmessagestringsettingsrpcconnectionsetting
1条回答
网友
1楼 · 发布于 2024-10-03 06:20:57

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

因此stop: false被认为等同于完全省略stop

Language Guide (proto3)

Note that for scalar message fields, once a message is parsed there's no way of telling whether a field was explicitly set to the default value (for example whether a boolean was set to false) or just not set at all: you should bear this in mind when defining your message types. For example, don't have a boolean that switches on some behaviour when set to false if you don't want that behaviour to also happen by default. Also note that if a scalar message field is set to its default, the value will not be serialized on the wire.

请注意,这与proto2不同

相关问题 更多 >