grp c Сервер в фоновом потоке c ++ - PullRequest
0 голосов
/ 06 мая 2020

Я пытаюсь запустить сервер grp c в потоке приложения MF C.

У меня (grp c частей прямо из примера GRP C):

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), но блокирует конструктор в RunServer() из-за вызова grpcServer->Wait(). Пробуя это с потоком, я получаю ошибку компилятора: call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type

Отсутствие вызова grpcServer->Wait() приводит к закрытию сервера сразу после выхода RunServer(), хотя переменная grpcServer все еще находится в области видимости как пока выполняется экземпляр класса.

Как правильно запустить grpcServer и поместить его в фоновый режим?

Ответы [ 2 ]

0 голосов
/ 08 мая 2020

Если вы хотите запустить сервер в отдельном потоке, это

grpcThread(Runserver);

Вам необходимо связать метод RunServer с экземпляром объекта, в данном случае «this»:

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

Это должно исправить ошибку компиляции.

И, как указал Марк, у вас есть член класса grpcServer, но вы объявляете локальную переменную grpcServer в RunServer, которая выходит за пределы области видимости после выхода из RunServer.

Более того, даже если вы выполните Wait() внутри RunServer и запустите его в отдельном потоке (который должен работать нормально), MyAppDlg::~MyAppDlg() не отключит сервер, поскольку он отключит MyAppDlg::grpcServer , которая отличается от локальной переменной grpcServer внутри RunServer.

0 голосов
/ 06 мая 2020

Я думаю, проблема в этой строке внутри MyAppDlg::RunServer():

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

Вы определяете локальную переменную с именем grpcServer вместо того, чтобы присваивать члену данных класса с тем же именем, поэтому выходит за рамки, как только возвращается RunServer(). Я думаю, это должно быть просто:

grpcServer.reset(builder.BuildAndStart());
...