Magic 8 Ball

Creating a HTTP2 connection between a Qt gRPC client and a C++ gRPC server.

Magic 8 ball sends a question to a server and displays the received answer:

"Magic 8 ball example screenshot"

The example code includes the following components:

  • magic8ball Qt gRPC client application that uses the qt_add_protobuf() and qt_add_grpc() CMake functions for message and service Qt code generation.
  • server application that calls C++ gRPC plugin for generating server code and implementing simple server logic.

Note: you need the C++ gRPC plugin installed. Find details here: Module prerequisites

Both components use generated messages from the protobuf schema described in the exampleservice.proto file:

syntax = "proto3";

package qtgrpc.examples;

message AnswerRequest {
    string question = 1;
}

message AnswerResponse {
    string message = 1;
}

service ExampleService {
    rpc answerMethod(AnswerRequest) returns (AnswerResponse) {}
}

The gRPC client is defined as a QML object which is available after the code is compiled.

    ExampleServiceClient {
        id: grpcClient
        channel: grpcChannel.channel
    }

The client service connects to the localhost with port 50051, which is specified in the gRPC channel options:

    GrpcHttp2Channel {
        id: grpcChannel
        hostUri: "http://localhost:50051"
        // Optionally, you can specify custom channel options here
        // options: GrpcChannelOptions {}
    }

And sends a request to the server part:

    function requestAnswer(question: string): void {
        ...
        root.answerReq.question = question;
        grpcClient.answerMethod(root.answerReq, finishCallback, errorCallback, grpcCallOptions);
    }

answerMethod is a gRPC method that the client calls. It has four parameters: the request object, a finish callback function, an error callback function and a GrpcCallOptions object.

Click the Ask button to send the request to the magic8ball server.

Note: You have to run the server in parallel with the client application.

The server application chooses a random answer from the list of answers and sends the data to the client's port. It also checks that the request contains a non empty field question. If the field is empty, it returns a StatusCode::INVALID_ARGUMENT

    grpc::Status answerMethod(grpc::ServerContext *, const AnswerRequest *request,
                              AnswerResponse *response) override
    {
        if (request->question().empty()) {
            std::cerr << "Question is empty" << std::endl;
            return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Question is empty");
        }
        std::cout << "Received question: " << request->question() << std::endl;

        response->set_message(getRandomAnswer());

        return grpc::Status();
    };

After receiving a response, the client application shows the answer.

Example project @ code.qt.io

© 2024 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.