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* });
  }
}

在此之后,您可以使用客户端示例。