为了账号安全,请及时绑定邮箱和手机立即绑定

从 Python 客户端发送的 GRPC 请求未被高浪服务器正确接收

从 Python 客户端发送的 GRPC 请求未被高浪服务器正确接收

Go
函数式编程 2022-10-04 19:42:41
我已经编写了一个Python GRPC客户端,可以连接到许多GRPC高浪服务。我已经能够像这样完成这项工作:from alphausblue.connection.conn import grpc_client_connectionfrom alphausblue.iam.v1.iam_pb2 import WhoAmIRequestfrom alphausblue.iam.v1.iam_pb2_grpc import IamStubasync def main():    conn = grpc_client_connection(svc = "blue")    stub = IamStub(conn)    resp = await stub.WhoAmI(WhoAmIRequest())    print(resp)其中服务名称为 。但是,如果我尝试连接到其他服务来请求如下数据:bluefrom alphausblue.connection.conn import grpc_client_connectionfrom alphausblue.cost.v1.cost_pb2 import ListAccountsRequestfrom alphausblue.cost.v1.cost_pb2_grpc import CostStubasync def main():    conn = grpc_client_connection(svc = "cost")    stub = CostStub(conn)    account = await stub.GetAccount(GetAccountRequest(vendor = 'aws', id = '731058950257'))    print(account)我得到一个未实现的响应。如果该服务不存在,这将是有道理的,但它确实存在,并且我的Golang客户端可以很好地连接到它。此外,当我检查服务器的日志时,我可以清楚地看到请求已到达服务器。做了更多的研究,我在我的服务器上发现了这段代码:type service struct {    UserInfo *blueinterceptors.UserData    cost.UnimplementedCostServer}func (s *service) GetAccount(ctx context.Context, in *cost.GetAccountRequest) (*api.Account, error) {    switch in.Vendor {    case "aws":        // Do stuff    default:        return status.Errorf(codes.Unimplemented, "not implemented")    }}这告诉我的是,正在调用函数,但正在反序列化的有效负载缺少该字段。但是,在调试时,我可以看到这行:vendorsrc/核心/库/安全/传输/secure_endpoint.cc:296] 写 0000018E2C62FB80: 00 00 00 13 0a 03 61 77 73 12 0c 37 33 31 30 35 38 39 35 30 32 35 37 '......哇.731058950257'因此,数据通过 GRPC 发送到服务器,但被反序列化为缺少字段的对象。那么,这是什么原因呢?更新我查看了Python和Golang客户端的定义,正如@blackgreen所建议的那样。GetAccountRequest高浪客户端代码:// Request message for the Cost.GetAccount rpc.type GetAccountRequest struct {    state         protoimpl.MessageState    sizeCache     protoimpl.SizeCache    unknownFields protoimpl.UnknownFields    Vendor string `protobuf:"bytes,1,opt,name=vendor,proto3" json:"vendor,omitempty"`    Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`}很明显,这里的字段顺序相同,因此我认为除非GRPC使用而不是.,否则这不是问题所在。indexnumber
查看完整描述

1 回答

?
千巷猫影

TA贡献1829条经验 获得超7个赞

在确保您在 Python 字段中设置的字符串不包含不可见字符后,在 Python 客户端中导入的生成代码与 Go 服务器导入的代码中可能存在版本不匹配。version


特别是,如果两个版本实际上都有一个字段,但Go代码以某种方式无法“识别”它,则可能是由字段标记编号不匹配引起的。version


您显示的字节有效负载(hexa,base64)确实在proto字段中发送带有标签号的字符串(我怎么知道0a 03 61 77 73 12 0c 37 33 31 30 35 38 39 35 30 32 35 37CgNhd3MSDDczMTA1ODk1MDI1Nw==aws1)


因此,让我们考虑一个人为的示例,Python客户端中使用的原始架构可能是GetAccountRequest


message GetAccountRequest {

    string version = 1; // field tag number 1

}

Go服务器中使用的那个可能是:


message GetAccountRequest {

    string version = 3; // field tag number 3

}

在这种情况下,您将在网络上看到具有版本字段的消息,但是在根据具有不同标记号的 Go 结构反序列化它时,它最终将为空。客户端使用 标记发送它,服务器期望它带有 标记 。13


您可以通过检查 Go 结构来验证此假设。它应如下所示:GetAccountRequest


type GetAccountRequest struct {

    // unexported fields


    // other fields, in order

    Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"`

}

反引号之间的部分是结构标记,其中 是标记号。`3


我不知道Python中的gRPC代码是什么样的,但你应该能够以某种方式比较标签号。如果它们确实不同,请确保使用生成的具有相同标记号的结构更新客户端或服务器代码。


查看完整回答
反对 回复 2022-10-04
  • 1 回答
  • 0 关注
  • 75 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信