微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

gRPCcpp-如何检查RPC通道是否成功连接?

如何解决gRPCcpp-如何检查RPC通道是否成功连接?

创建通道和存根时,如何检查RPC客户端是否成功建立了到RPC服务器的连接?

如果连接失败,我希望能够引发异常或信号。我不确定哪种方法符合“操作”的要求。我不想进行我们定义的任何RPC调用,因为它们都会产生影响....除非唯一的选择是去实现一些“嗨,我在这里” RPC方法,但这似乎很愚蠢。 ,不?

void ChatSyncclient::connect(QUrl const& endpoint)
{
    disconnect();

    // Todo - How do we tell if this fails?
    //        The comments say a lame channel will be returned,where all operations fail
    //        How are we suppose to check right here rather than later?
    auto channel = ::grpc::CreateChannel(endpoint.toString().toStdString(),::grpc::InsecureChannelCredentials());
    m_stub = std::make_unique<chat_sync::Chat::Stub>(channel);

    emit signalOnConnected();
}

解决方法

在我直接回答您的问题之前,让我提供一些背景知识。

gRPC通道实际上与连接不同。实际上,一个通道可能具有多个并行活动的底层连接,具体取决于该通道使用的负载平衡策略。通道API的目的是从应用程序中抽象出各个连接的详细信息。想法是,应用程序应将通道视为发送RPC的通用接口,并且该通道将在内部自动处理连接管理的详细信息,因此应用程序不必担心它们。

因此,在较高级别上,我认为您的应用程序不需要知道或关心通道是否已连接。如果您认为确实需要知道这一点,那么我实际上会认为这表明您需要退后一步,重新考虑如何构建应用程序。

尤其是,我不确定“我不想进行我们定义的任何RPC调用,因为它们都会产生影响”的意思是什么,但这听起来有点奇怪我。我假设您的意思是可能会对服务器的状态产生影响,这意味着RPC不是幂等的。您可能需要考虑以某种方式将其更改为幂等,因为这样做更安全(我将在稍后再讨论原因)。但是,即使您正在处理非幂等的RPC,我也看不出了解基础连接的状态如何帮助您避免该问题。即使在客户端启动RPC的那一刻就已经连接了通道,也永远无法保证服务器会看到它,因为在应用程序告诉gRPC发送它之后,但在网络断开之前,连接可能会失败。否则,在gRPC联机之后,网络本身可能无法将其交付给服务器。或者,更糟的是,服务器可以看到它,但是在服务器的响应返回到客户端之前,网络可能会失败。确实不能保证RPC是原子的,也不能保证客户机和服务器对RPC是否成功具有相同的看法。在所有这些情况下,客户端都知道RPC失败,但是不能由此推断服务器是否实际看到RPC。

这就是为什么通常将RPC设计为幂等的原因。您不必关注通道是否已连接,而可以关注单个RPC是否成功。每当客户端看到RPC失败时,它都可以重试。而且,如果服务器碰巧两次看到相同的RPC,则不会造成任何问题(例如,如果重播删除操作,它将注意到数据已被删除,因此将成为无操作)。 / p>

因此,我的高层答复是,您的客户端代码应该对单个RPC故障而不是对连接故障做出反应。

所有这些,如果您确实想监视通道的连接状态,则可以使用connectivity state API进行监视。请注意,gRPC通道在创建时实际上并不会立即立即启动连接。最初,它处于IDLE状态。当(a)在通道上发送第一个RPC或(b)调用channel->GetState(true)明确要求它进行连接时,它将尝试连接(并转换为CONNECTING状态)。如果连接尝试失败,则通道将转换为状态TRANSIENT_FAILURE,并将定期重试。建立连接后,它将转换为状态READY。

在状态为TRANSIENT_FAILURE的通道上发送的任何RPC都将立即失败,除非它是wait_for_ready。当通道转换到状态TRANSIENT_FAILURE时仍悬而未决的RPC也是如此(例如,如果通道最初处于IDLE状态,并且由于发送RPC而开始连接,但是初始连接尝试失败)

关于la脚通道,请注意,仅在极少数情况下,您尝试使用gRPC不知道如何解析的格式错误的目标URI创建通道。如果gRPC知道它将永远无法解析您指定的名称,它将返回一个me脚的频道,该频道基本上是永久处于TRANSIENT_FAILURE状态的频道。

我希望这些信息对您有所帮助。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。