grpc 字段 Message.Field 的非法线路类型。PeopleRequest.ages:2(预期为 0))
grpc Illegal wire type for field Message.Field .PeopleRequest.ages: 2 (0 expected))
这是我的原型文件:
syntax = "proto3";
package grpcClient;
service GrpcClient {
rpc GetPeople(PeopleRequest) returns (PeopleResponse) {}
}
message PeopleRequest {
repeated string names = 1; // ex: ['jack', 'marie']
repeated int32 ages = 2; // ex: [18, 24]
}
message PeopleResponse {
repeated Person people = 1;
}
message Person {
string name = 1;
int32 age = 2;
}
这里是 python 存根构造:
from . import grpcClient_pb2
class GrpcClient:
def __init__(self):
server_url = "http://my_url:5001"
secure_channel = make_secure_channel(server_url)
self.__stub = grpcClient_pb2.GrpcClientStub(secure_channel)
def get_people(self, **kwargs):
people_request = grpcClient_pb2.PeopleRequest(**kwargs)
# your test example
try:
serialized_people_request = grpcClient_pb2.PeopleRequest.SerializeToString(people_request)
except Exception as e:
print(e)
else:
print('Serialized to binary of type {} and length {}'.format(type(serialized_people_request), len(serialized_people_request)))
return self.__stub.GetPeople(people_request) # this throw an error
这是我的 grpc 调用:
grpcClient = GrpcClient()
grpcClient.get_people({ 'names': ['daniel', 'jack'] }) # this is OK
grpcClient.get_people({ 'names': ['daniel', 'jack'], 'ages': [18, 22] }) # this throws
我使用 Python 3.6 并且我的 pip 包版本是:
grpcio 1.0.4
grpcio-tools 1.0.4
pip 9.0.1
protobuf 3.1.0.post1
我使用此命令生成 grpcClient_pb2.py
和 grpcClient_pb2_grpc.py
:
python -m grpc.tools.protoc -I./ --python_out=./ --grpc_python_out=./ ./grpcClient.proto
注意:这里是自动生成的 python 代码:
_descriptor.FieldDescriptor(
name='names', full_name='PeopleRequest.names', index=0,
number=1, type=9, cpp_type=9, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='ages', full_name='PeopleRequest.ages', index=1,
number=2, type=5, cpp_type=1, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
非常感谢您的帮助!
我认为没有足够的信息来诊断问题。你能提供整个原型文件吗?我假设它包含一个 GetPeoples
服务。
能不能也提供一下你的整个客户端程序?使用 gRPC 时,导入可能会造成混淆,因为您需要从 grpc
包和生成的 <your_proto>_pb2_grpc
包中导入内容。不清楚 grpc.PeopleRequest
指的是哪一个。
我尝试使用以下我命名为 test.proto
:
的原型文件来填补缺失的部分
syntax = "proto3";
service MyService {
rpc GetPeoples(PeopleRequest) returns (PeopleReply) {}
}
message PeopleRequest {
repeated string names = 1; // ex: ['jack', 'marie']
repeated int32 ages = 2; // ex: [1, 2]
}
message PeopleReply {
}
以及以下适合我的客户端:
from __future__ import print_function
import grpc
import test_pb2
import test_pb2_grpc
def run():
channel = grpc.insecure_channel('localhost:50051')
stub = test_pb2_grpc.MyServiceStub(channel)
obj = test_pb2.PeopleRequest(
names=['daniel'],
ages=[32])
print(obj) # Ok, no error when building the object
stub.GetPeoples(obj) # ERROR Illegal wire type for field ages: 2 (0 expected))
if __name__ == '__main__':
run()
这是我构建的,per the Python quickstart:
$ virtualenv venv
$ source venv/bin/activate
(venv) $ python --version
Python 2.7.6
(venv) $ pip install grpcio
(venv) $ pip install cython
(venv) $ pip install grpcio-tools
(venv) $ pip freeze
Cython==0.25.2
argparse==1.2.1
coverage==4.3.4
enum34==1.1.6
futures==3.0.5
grpcio==1.0.4
grpcio-tools==1.0.4
protobuf==3.1.0.post1
six==1.10.0
wheel==0.29.0
wsgiref==0.1.2
(venv) $ python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. test.proto
祝你好运!
小故事: 我的服务器是用 node.js 编写的,并且:
rm -rf node_modules
npm i
解决了我的问题。
长话短说: 看起来无论我的客户端连接到什么服务器(我有一个本地和一个远程 node.js 服务器 运行测试)在这两种情况下我的客户都会抛出。这就是为什么我在客户端代码中查找错误,而不是在服务器端查找错误。此外,服务器从未记录任何内容,只有客户端抛出错误。
最后我在 python 中重新实现了服务器端,令人惊讶的是我的客户端在连接到 python 服务器时不会抛出异常。于是我开始怀疑我的node.js服务器有问题,最后我完全重装了我的node.js服务器的node_modules,重启,果然问题消失了。所以我得出结论,这个问题与 node_modules.
中的某个包有关
这是我的原型文件:
syntax = "proto3";
package grpcClient;
service GrpcClient {
rpc GetPeople(PeopleRequest) returns (PeopleResponse) {}
}
message PeopleRequest {
repeated string names = 1; // ex: ['jack', 'marie']
repeated int32 ages = 2; // ex: [18, 24]
}
message PeopleResponse {
repeated Person people = 1;
}
message Person {
string name = 1;
int32 age = 2;
}
这里是 python 存根构造:
from . import grpcClient_pb2
class GrpcClient:
def __init__(self):
server_url = "http://my_url:5001"
secure_channel = make_secure_channel(server_url)
self.__stub = grpcClient_pb2.GrpcClientStub(secure_channel)
def get_people(self, **kwargs):
people_request = grpcClient_pb2.PeopleRequest(**kwargs)
# your test example
try:
serialized_people_request = grpcClient_pb2.PeopleRequest.SerializeToString(people_request)
except Exception as e:
print(e)
else:
print('Serialized to binary of type {} and length {}'.format(type(serialized_people_request), len(serialized_people_request)))
return self.__stub.GetPeople(people_request) # this throw an error
这是我的 grpc 调用:
grpcClient = GrpcClient()
grpcClient.get_people({ 'names': ['daniel', 'jack'] }) # this is OK
grpcClient.get_people({ 'names': ['daniel', 'jack'], 'ages': [18, 22] }) # this throws
我使用 Python 3.6 并且我的 pip 包版本是:
grpcio 1.0.4
grpcio-tools 1.0.4
pip 9.0.1
protobuf 3.1.0.post1
我使用此命令生成 grpcClient_pb2.py
和 grpcClient_pb2_grpc.py
:
python -m grpc.tools.protoc -I./ --python_out=./ --grpc_python_out=./ ./grpcClient.proto
注意:这里是自动生成的 python 代码:
_descriptor.FieldDescriptor(
name='names', full_name='PeopleRequest.names', index=0,
number=1, type=9, cpp_type=9, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='ages', full_name='PeopleRequest.ages', index=1,
number=2, type=5, cpp_type=1, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
非常感谢您的帮助!
我认为没有足够的信息来诊断问题。你能提供整个原型文件吗?我假设它包含一个 GetPeoples
服务。
能不能也提供一下你的整个客户端程序?使用 gRPC 时,导入可能会造成混淆,因为您需要从 grpc
包和生成的 <your_proto>_pb2_grpc
包中导入内容。不清楚 grpc.PeopleRequest
指的是哪一个。
我尝试使用以下我命名为 test.proto
:
syntax = "proto3";
service MyService {
rpc GetPeoples(PeopleRequest) returns (PeopleReply) {}
}
message PeopleRequest {
repeated string names = 1; // ex: ['jack', 'marie']
repeated int32 ages = 2; // ex: [1, 2]
}
message PeopleReply {
}
以及以下适合我的客户端:
from __future__ import print_function
import grpc
import test_pb2
import test_pb2_grpc
def run():
channel = grpc.insecure_channel('localhost:50051')
stub = test_pb2_grpc.MyServiceStub(channel)
obj = test_pb2.PeopleRequest(
names=['daniel'],
ages=[32])
print(obj) # Ok, no error when building the object
stub.GetPeoples(obj) # ERROR Illegal wire type for field ages: 2 (0 expected))
if __name__ == '__main__':
run()
这是我构建的,per the Python quickstart:
$ virtualenv venv
$ source venv/bin/activate
(venv) $ python --version
Python 2.7.6
(venv) $ pip install grpcio
(venv) $ pip install cython
(venv) $ pip install grpcio-tools
(venv) $ pip freeze
Cython==0.25.2
argparse==1.2.1
coverage==4.3.4
enum34==1.1.6
futures==3.0.5
grpcio==1.0.4
grpcio-tools==1.0.4
protobuf==3.1.0.post1
six==1.10.0
wheel==0.29.0
wsgiref==0.1.2
(venv) $ python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. test.proto
祝你好运!
小故事: 我的服务器是用 node.js 编写的,并且:
rm -rf node_modules
npm i
解决了我的问题。
长话短说: 看起来无论我的客户端连接到什么服务器(我有一个本地和一个远程 node.js 服务器 运行测试)在这两种情况下我的客户都会抛出。这就是为什么我在客户端代码中查找错误,而不是在服务器端查找错误。此外,服务器从未记录任何内容,只有客户端抛出错误。
最后我在 python 中重新实现了服务器端,令人惊讶的是我的客户端在连接到 python 服务器时不会抛出异常。于是我开始怀疑我的node.js服务器有问题,最后我完全重装了我的node.js服务器的node_modules,重启,果然问题消失了。所以我得出结论,这个问题与 node_modules.
中的某个包有关