.net gRPC:如何在流gRPC中查找特定客户端

mxg2im7a  于 2022-12-01  发布在  .NET
关注(0)|答案(1)|浏览(212)

我想通过gRPC服务器流创建客户端和服务器。我想在此时区分每个客户端。我研究了一下,我认为我们可以选择使用UID来区分客户端或使用对等体来区分客户端。
我比较好奇的是,当我想只向一个特定的客户端发送一个响应时,不知道是不是只有一种方式,就是在发送给所有人之后,通过uid或者peer来区分,服务器难道不能从一开始就只向一个客户端发送吗?
例如,假设您创建了一个名为send()的服务器流grpc服务,从多个客户端请求send()并通过stream等待响应,服务器需要响应send()到特定客户端,但我不知道如何为该特定客户端生成唯一的send()服务。

deyfvvtc

deyfvvtc1#

一种解决方案(但可能有更好的解决方案)是在元数据中从客户端向服务器传递一个唯一的ID,并在服务器端为所有连接的客户端提供一个集中式存储,如singleton client manager 类。
例如,在客户端,当订阅服务器流时,机器名作为具有关键字client-id的标识符在元数据中传递(尽管类似GUID的东西可能更唯一):

// client-side method that subscribes to the gRPC client
public async void Subscribe()
{
    // subscribe to the server stream with a unique client id
    _call = _serviceClient.SubscribeToServerStream(new Empty(), headers: new Metadata
    {
        new Metadata.Entry("client-id", Environment.MachineName)
    });

    // handle incoming messages from the server for this client
    await HandleIncomingServerMessages(_call.ResponseStream);
}

服务器端的代码被简化了一些,但是我认为它解释了这个想法。(singleton)_clientManager 类,它保存所有连接的客户端,并管理应该向谁进行流传输。(仅作为示例)将此客户端的streaming属性设置为active,您可以检查传出流中此客户端是否处于活动状态(使用从调用上下文中提取的id),从而检查消息流是否处于活动状态。

// server-side method in the gRPC service that implements the stream
public override async Task SubscribeToServerStream(Empty request,
    IServerStreamWriter<Message> responseStream,
    ServerCallContext context)
{
    // extract the unique client id
    _clientId = context.RequestHeaders.FirstOrDefault(m => String.Equals(m.Key, "client-id", StringComparison.Ordinal));

    // register it to the server-side client manager
    _clientManager.AddNewConnectedClient(_clientId);

    while(_isStreaming)
    {
        if(_clientManager.IsActiveClient(this._clientId))
        {
            // this client is set to active in the manager, therefore stream
        }
        else
        {
            // do nothing, since you currently do not want to stream to this connected client
        }
    }
}

我非常肯定这将工作,因为我实现了一些非常相似的不久前,虽然它有点hacky(多个客户端可以连接,但同时只有一个可以接收流,还有一些其他条件)。但可能有比我的答案更好的解决方案来解决你的问题,和调试所有的代码,以便为您提供开箱即用的功能。

相关问题