C++ GRPC 异步双向流 - 如何判断客户端何时发送消息?

时间:2021-05-11 05:22:32

标签: c++ grpc

关于如何使用 grpc 执行异步双向流的文档为零。我通过将常规异步示例与我在人们的 github 中找到的内容拼凑在一起进行了猜测。

使用我拥有的 Frankestein 代码,我无法弄清楚如何判断客户何时向我发送了消息。这是我在自己的线程上运行的过程。

void GrpcStreamingServerImpl::listeningThreadProc()
{
    try
    {
        // I think we make a call to the RPC method and wait for others to stream to it?
        ::grpc::ServerContext context;
        void * ourOneAndOnlyTag = reinterpret_cast<void *>(1); ///< Identifies the call we are going to make. I assume we can only handle one client

        ::grpc::ServerAsyncReaderWriter<mycompanynamespace::OutputMessage,
                                        mycompanynamespace::InputMessage>
            stream(&context);

        m_service.RequestMessageStream(&context, &stream, m_completionQueue.get(), m_completionQueue.get(), ourOneAndOnlyTag);

        // Now I'm going to loop and get events from the completion queue
        bool keepGoing = false;
        do
        {
            void*                                                    tag = nullptr;
            bool                                                     ok  = false;
            const std::chrono::time_point<std::chrono::system_clock> deadline(std::chrono::system_clock::now() +
                                                                              std::chrono::seconds(1));

            grpc::CompletionQueue::NextStatus nextStatus = m_completionQueue->AsyncNext(&tag, &ok, deadline);
            switch(nextStatus)
            {
            case grpc::CompletionQueue::NextStatus::TIMEOUT:
            {
                keepGoing = true;
                break;
            }
            case grpc::CompletionQueue::NextStatus::GOT_EVENT:
            {
                keepGoing = true;

                if(ok)
                {
                    // This seems to get called if a client connects
                    // It does not get called if we didn't call 'RequestMessageStream' before the loop started
                    // TODO - How do we tell when the client send us a messages?
                    // TODO - How do we know if they are just connecting?
                    // TODO - How do we get the message client sent?

                    // The tag corresponds to the request we made
                    if(tag == reinterpret_cast<void *>(1))
                    {
                        // SNIP successful writing of a message
                        stream.Write(*(outputMessage.get()), reinterpret_cast<void*>(2));
                    }
                    else if(tag == reinterpret_cast<void *>(2))
                    {
                        // This is telling us the message we sent was completed
                    }
                    else
                    {
                        // TODO - I dunno what else it can be
                    }
                }
                break;
            }
            case grpc::CompletionQueue::NextStatus::SHUTDOWN:
            {
                keepGoing = false;
                break;
            }
            }
        } while(keepGoing);

        // Completion queue was shutdown
    }
    catch(std::exception& e)
    {
        QString errorMessage(
            QString("An std::exception was caught in the listening thread. Exception message: %1").arg(e.what()));
        m_backPointer->onImplError(errorMessage);
    }
    catch(...)
    {
        QString errorMessage("An exception of unknown type, was caught in the listening thread.");
        m_backPointer->onImplError(errorMessage);
    }
}

设置看起来像这样

// Start up the grpc service
grpc::ServerBuilder builder;
builder.RegisterService(&m_service);
builder.AddListeningPort(endpoint.toStdString(), grpc::InsecureServerCredentials());
m_completionQueue = builder.AddCompletionQueue();
m_server          = builder.BuildAndStart();

// Start the listening thread
m_listeningThread = QThread::create(&GrpcStreamingServerImpl::listeningThreadProc, this);

0 个答案:

没有答案