简体   繁体   中英

grpc Server in background thread c++

I am trying to run an grpc server in a thread in an MFC app.

I have (grpc parts straight from the GRPC example):

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();
}

Without the thread, it runs fine (client can connect and call SayHello ), but blocks the constructor at RunServer() because of the grpcServer->Wait() call. Trying it with the thread, I get a compiler error: call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type

Not calling grpcServer->Wait() causes the server to close immediately after RunServer() exits, although the variable grpcServer is still in the scope as long as the class instance is running.

How do I properly start a grpcServer and put it in the background?

I think the problem is this line within MyAppDlg::RunServer() :

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

You're defining a local variable called grpcServer instead of assigning to the class data member of the same name, so it's going out of scope as soon as RunServer() returns. I think that should just be:

grpcServer.reset(builder.BuildAndStart());

If you want to run the server in a separate thread, that is the

grpcThread(Runserver);

You need to associate the RunServer method with an object instance, in this case "this":

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

This should fix the compilation error.

And as Mark pointed out, you have a class member grpcServer, but you declare a local variable grpcServer in RunServer which goes out of scope after RunServer exits.

What's more, even if you do the Wait() inside RunServer and run it on a separate thread (which should work just fine), the MyAppDlg::~MyAppDlg() will not shutdown the server since it will shutdown the MyAppDlg::grpcServer , which is different from the local variable grpcServer inside RunServer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM