在用户应用程序中使用 Qt GRPC 客户端 API。
聊天 explains how to authenticate chat users and send and receive short messages between chat clients. The application supports the following message formats:
'Ctrl + V'
shortcut.
The chat client uses a simple RPC protocol described in the protobuf scheme:
package qtgrpc.examples.chat; message ChatMessage { enum ContentType { Unknown = 0; Text = 1; Image = 2; }; uint64 timestamp = 1; bytes content = 2; ContentType type = 3; string from = 4; } message ChatMessages { repeated ChatMessage messages = 1; } message User { string name = 1; string password = 2; } message Users { repeated User users = 1; } message None { } service SimpleChat { rpc messageList(None) returns (stream ChatMessages) { } rpc sendMessage(ChatMessage) returns (None) { } }
On the login screen, enter user credentials:
注意:
The list of users is predefined on the server side and is constant. The password for all users is
qwerty
.
The chat client uses an authentication type called
call credentials
. Each gRPC message includes the user credentials in the message header. Credentials are passed to the
QGrpcHttp2Channel
once and reused implicitily:
std::shared_ptr<QAbstractGrpcChannel> channel( new QGrpcHttp2Channel(url, QGrpcUserPasswordCredentials(name, password.toUtf8()) | QGrpcInsecureChannelCredentials()));
The chat client starts the communication with the server using a subscription to gRPC server streaming:
auto stream = m_client->streamMessageList(qtgrpc::examples::chat::None()); QObject::connect(stream.get(), &QGrpcStream::errorOccurred, this, [this, stream](const QGrpcStatus &status) { qCritical() << "Stream error(" << status.code() << "):" << status.message(); if (status.code() == QGrpcStatus::Unauthenticated) emit authFailed(); }); QObject::connect(stream.get(), &QGrpcStream::finished, this, [this, stream]() { setState(Disconnected); }); QObject::connect(stream.get(), &QGrpcStream::messageReceived, this, [this, name, stream]() { if (m_userName != name) { m_userName = name; emit userNameChanged(); } setState(Connected); m_messages.append(stream->read<qtgrpc::examples::chat::ChatMessages>().messages()); });
The QGrpcStream handler provides the signals that the client application should connect to.
The QGrpcStream::errorOccurred signal indicates the error that occurred either on the server side or in the communication channel. Typically, an error results in the connection to the server being closed and the QGrpcStream::finished signal being emitted.
When the server sends new messages to the stream,
QGrpcStream
发射
QGrpcStream::messageReceived
signal. The slot connected to this signal processes the chat message. Messages that are received from the
SimpleChat/messageList
server stream are collected in the custom
QAbstractListModel
model and displayed to the user.
当 QGrpcStream::finished signal is emitted, there is nothing more you can do with this stream instance, so you need to initiate a new subscription.
After a successful subscription, the chat client switches to the conversation screen and allows you to see and send short messages:
To send the message, use a unary RPC call
SimpleChat/sendMessage
. The client application first sets fields of the
ChatMessage
protobuf message and then calls the client method:
qtgrpc::examples::chat::ChatMessage msg; msg.setContent(content.toUtf8()); msg.setType(qtgrpc::examples::chat::ChatMessage::Text); msg.setTimestamp(QDateTime::currentMSecsSinceEpoch()); msg.setFrom(m_userName); m_client->sendMessage(msg);
Then, the gRPC server processes the client messages and broadcasts them to all the connected clients through the
SimpleChat/messageList
stream.
注意: This example uses the reference gRPC C++ API in the server implementation.