簡體   English   中英

后台線程中的 grpc 服務器 c++

[英]grpc Server in background thread c++

我正在嘗試在 MFC 應用程序的線程中運行 grpc 服務器。

我有(直接來自 GRPC 示例的 grpc 部分):

MyAppDlg.h:

#include <thread>
#include <grpcpp\grpcpp.h>

class MyAppDlg : public CDialog
{
public:
    MyAppDlg( CString aFileName, CWnd *pParent = NULL );
    virtual ~MyAppDlg();

    std::unique_ptr<grpc::Server> grpcServer;

    std::thread grpcThread;

    void RunServer();

MyAppDlg.cpp:

class GreeterServiceImpl final : public Greeter::Service {
    Status SayHello(ServerContext* context, const HelloRequest* request,
        HelloReply* reply) override {
        std::string prefix("Hello ");
        reply->set_message(prefix + request->name());
        return Status::OK;
    }
};

void MyAppDlg::RunServer() {
    std::string server_address("0.0.0.0:50051");
    GreeterServiceImpl service;
    grpc::EnableDefaultHealthCheckService(true);
    grpc::reflection::InitProtoReflectionServerBuilderPlugin();
    ServerBuilder builder;
    builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
    builder.RegisterService(&service);
    std::unique_ptr<Server> grpcServer(builder.BuildAndStart());
    std::cout << "Server listening on " << server_address << std::endl;

    // Wait for the server to shutdown. Note that some other thread must be
    // responsible for shutting down the server for this call to ever return.
    grpcServer->Wait(); <-- Leaving this out causes the server to close immediately again.
}

MyAppDlg::MyAppDlg( CString aFileName, CWnd* pParent /* =NULL */ )
{
    ... stuff ...
    // RunServer(); <-- using this works but blocks the thread
    grpcThread(RunServer); <-- does not work

}

MyAppDlg::~MyAppDlg()
{
    grpcServer->Shutdown();
    grpcThread.join();
}

沒有線程,它運行良好(客戶端可以連接並調用SayHello ),但由於grpcServer->Wait()調用而阻塞了RunServer()處的構造函數。 用線程嘗試它,我得到一個編譯器錯誤: call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type

不調用grpcServer->Wait()會導致服務器在RunServer()退出后立即關閉,盡管只要 class 實例正在運行,變量grpcServer仍然在 scope 中。

如何正確啟動grpcServer並將其置於后台?

我認為問題在於MyAppDlg::RunServer()中的這一行:

std::unique_ptr<Server> grpcServer(builder.BuildAndStart());

您正在定義一個名為grpcServer的局部變量,而不是分配給同名的 class 數據成員,因此一旦RunServer()返回,它就會離開 scope 。 我認為應該只是:

grpcServer.reset(builder.BuildAndStart());

如果要在單獨的線程中運行服務器,那就是

grpcThread(Runserver);

您需要將 RunServer 方法與 object 實例相關聯,在本例中為“this”:

grpcTread(std::bind(&MyAppDlg::RunServer, this));

這應該可以修復編譯錯誤。

正如馬克指出的那樣,你有一個 class 成員 grpcServer,但是你在 RunServer 中聲明了一個局部變量 grpcServer,它在 RunServer 退出后退出 scope。

更重要的是,即使您在 RunServer 中執行Wait()並在單獨的線程上運行它(應該可以正常工作), MyAppDlg::~MyAppDlg()也不會關閉服務器,因為它會關閉MyAppDlg::grpcServer ,這與 RunServer 內部的局部變量grpcServer RunServer

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM