【问题标题】:Why Bi-directional stream is block until CompleteAsync为什么双向流在 CompleteAsync 之前被阻塞
【发布时间】:2020-10-23 19:46:08
【问题描述】:

我不明白为什么只有当我使用 CompleteAsync() 时才会收到响应。

using var call = _apiClient.GetToken(headers: _threadContext.Metadata,  deadline: DateTime.UtcNow.AddSeconds(5));

var keyReq = new GetTokenRequest()
{
    Key = publicKey
};

var readTask = Task.Run(async () =>
{
    await foreach(var message in call.ResponseStream.ReadAllAsync())
    {
        if (message.Challenge != null)
        {
            var challenge = message.Challenge.ToByteArray();
            var signature = await VerifySignature(challenge);
            var signReq = new GetTokenRequest
            {
                Signature = ByteString.CopyFrom(signature)
            };
            await call.RequestStream.WriteAsync(signReq);
            await call.RequestStream.CompleteAsync();
        }
        else if (message.Token != null)
        {
            token = message.Token;
        }
    }
});

await call.RequestStream.WriteAsync(keyReq);

await readTask;

如果我以此更改结尾,我会收到消息,但在响应中下一个 WriteAsync 失败,因为流已关闭。

await call.RequestStream.WriteAsync(keyReq);
await call.RequestStream.CompleteAsync();
await readTask;

如果我没有完成请求,响应消息永远不会出现。

有什么想法吗?

注意:服务器正在运行。

【问题讨论】:

  • Net 库中的流等待阻塞,直到流关闭。当你到达流的末尾时不是。流可能仍在填充,您想等到所有数据都在流中。
  • @jdweng 如果流在发送所有数据之前被阻塞,那么与字节数组相比,它们将毫无用处,并且无法用于发送大量数据。实际上,流的存在是专门用于以块的形式处理数据的。你一定听说过cancel a read on a network stream是不可能的,这是完全不同的事情。
  • @GSerg :我没有说流被阻止了。我只是指等待。查看操作代码。 foreach 循环,但在流关闭之前循环不会终止。

标签: c# grpc grpc-node


【解决方案1】:

此代码仅适用于 Grpc.Net.Client.Web。使用经典的 SocketHttpHandler 就可以了。问题解决了。谢谢。

【讨论】:

    猜你喜欢
    • 2017-01-26
    • 2014-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    • 2020-08-22
    • 1970-01-01
    • 2012-10-31
    相关资源
    最近更新 更多