gRPC 响应类型问题
gRPC response type issue
我有一个 gRPC 服务 DeviceCommWeb
,它在 .proto 文件中有以下 rpc:
// NOTE: This is part of the .proto file
service DeviceCommWeb {
rpc GetConnectedDevices(GetConnectedDevicesRequest) returns (stream GetConnectedDevicesResponse);
}
GetConnectedDevicesRequest
消息:
// NOTE: This is part of the .proto file
message GetConnectedMessageRequest {
enum DeviceType {
USB = 0;
HDMI = 1;
DisplayPort = 2;
}
DeviceType deviceType = 1;
string pdiUid = 2;
}
GetConnectedDevicesResponse
消息:
// NOTE: This is part of the .proto file
message GetConnectedDevicesResponse {
repeated DeviceComm devices = 1;
}
在服务中我实现了 GetConnectedDevices
:
public override async Task GetConnectedDevices(GetConnectedDevicesRequest, IServerStreamWriter<GetConnectedDevicesResponse> repsonseStream, ServerCallContext context)
{
await responseStream.WriteAsync(ListConnectedDevices((DeviceType)request.DeviceType, Guid.Parse(request.uid)));
}
ListConnectedDevices
方法:
private GetConnectedDevicesResponse ListConnectedDevices(DeviceType deviceType, Guid uid)
{
var connectedDevices = DeviceCommMoq.ConnectedDevices() // This is just a Moq. Returns a List<DeviceComm> of DeviceComm objects.
var result = new GetCOnnectedDevicesResponse();
foreach (DeviceComm device in connectedDevices)
{
// This is where I'm confused. How do I build the GetConnectedDevicesResponse?
}
}
目标是获取 DeviceCommMoq.ConnectedDevices()
中已连接设备的列表,并将它们 return 作为 GetConnectedDevicesResponse
的(或流)。我不确定该怎么做,我尝试的一切都给我错误:
Cannot implicitly convert type 'DeviceComm' to 'GetConnectedDevicesResponse'
我做错了什么?我觉得这里有更好的方法来实现最终目标。
使用WriteAsync()
意味着你必须阅读特定的数据。
首先,调用using var response = yourGrpcClient.GetConnectedDevices()
得到ResponseStream
。然后读取数据:
await foreach (var data in response.ResponseStream.ReadAllAsync())
{
//Do Stuff
}
此外,如果您使用流,WriteAsync()
foreach 循环中的每个元素。
已编辑
您的解决方案中有很多错误。让我们从 .proto
文件开始。响应包含多个 DeviceComm
元素。错了,因为你用的是stream as response,就是流GetConnectedDevicesResponse
类型的元素,所以你应该重新定义它。将 repeated DeviceComm devices = 1;
替换为 DeviceComm 属性。
在此更改后 GetConnectedDevices
方法如下:
public override async Task GetConnectedDevices(GetConnectedDevicesRequest,
IServerStreamWriter<GetConnectedDevicesResponse> repsonseStream,
ServerCallContext context)
{
var connectedDevices = deDeviceCommMoq.ConnectedDevices();
foreach(var device in connectedDevices)
{
await responseStream.WriteAsync(new GetConnectedDevicesResponse() { *Initialize properties from device object* });
}
}
在此之后,您可以使用客户端示例。
我有一个 gRPC 服务 DeviceCommWeb
,它在 .proto 文件中有以下 rpc:
// NOTE: This is part of the .proto file
service DeviceCommWeb {
rpc GetConnectedDevices(GetConnectedDevicesRequest) returns (stream GetConnectedDevicesResponse);
}
GetConnectedDevicesRequest
消息:
// NOTE: This is part of the .proto file
message GetConnectedMessageRequest {
enum DeviceType {
USB = 0;
HDMI = 1;
DisplayPort = 2;
}
DeviceType deviceType = 1;
string pdiUid = 2;
}
GetConnectedDevicesResponse
消息:
// NOTE: This is part of the .proto file
message GetConnectedDevicesResponse {
repeated DeviceComm devices = 1;
}
在服务中我实现了 GetConnectedDevices
:
public override async Task GetConnectedDevices(GetConnectedDevicesRequest, IServerStreamWriter<GetConnectedDevicesResponse> repsonseStream, ServerCallContext context)
{
await responseStream.WriteAsync(ListConnectedDevices((DeviceType)request.DeviceType, Guid.Parse(request.uid)));
}
ListConnectedDevices
方法:
private GetConnectedDevicesResponse ListConnectedDevices(DeviceType deviceType, Guid uid)
{
var connectedDevices = DeviceCommMoq.ConnectedDevices() // This is just a Moq. Returns a List<DeviceComm> of DeviceComm objects.
var result = new GetCOnnectedDevicesResponse();
foreach (DeviceComm device in connectedDevices)
{
// This is where I'm confused. How do I build the GetConnectedDevicesResponse?
}
}
目标是获取 DeviceCommMoq.ConnectedDevices()
中已连接设备的列表,并将它们 return 作为 GetConnectedDevicesResponse
的(或流)。我不确定该怎么做,我尝试的一切都给我错误:
Cannot implicitly convert type 'DeviceComm' to 'GetConnectedDevicesResponse'
我做错了什么?我觉得这里有更好的方法来实现最终目标。
使用WriteAsync()
意味着你必须阅读特定的数据。
首先,调用using var response = yourGrpcClient.GetConnectedDevices()
得到ResponseStream
。然后读取数据:
await foreach (var data in response.ResponseStream.ReadAllAsync())
{
//Do Stuff
}
此外,如果您使用流,WriteAsync()
foreach 循环中的每个元素。
已编辑
您的解决方案中有很多错误。让我们从 .proto
文件开始。响应包含多个 DeviceComm
元素。错了,因为你用的是stream as response,就是流GetConnectedDevicesResponse
类型的元素,所以你应该重新定义它。将 repeated DeviceComm devices = 1;
替换为 DeviceComm 属性。
在此更改后 GetConnectedDevices
方法如下:
public override async Task GetConnectedDevices(GetConnectedDevicesRequest,
IServerStreamWriter<GetConnectedDevicesResponse> repsonseStream,
ServerCallContext context)
{
var connectedDevices = deDeviceCommMoq.ConnectedDevices();
foreach(var device in connectedDevices)
{
await responseStream.WriteAsync(new GetConnectedDevicesResponse() { *Initialize properties from device object* });
}
}
在此之后,您可以使用客户端示例。