服务端开发
本节内容介绍 QVSOA 服务端使用订阅与发布的方法。
开发须知
QVSOA 服务端的数据发布分为“普通发布方式”和“快速发布方式”。
当服务端需要大量高频的发布数据时,可以使用快速发布的方式。快速发布进行大量高频的数据发布无法保证所有数据都能有效的到达,因此客户端在接收时可能会存在数据的丢失,使用快速发布的条件是这些丢失的数据并不影响程序的实际效果。若数据的变化是离散的而非连续的,使用快速发布可能会存在弊端。
在 QVSOA 的底层实现中,普通发布方式基于 TCP,快速发布方式基于 UDP,当有大批量快周期更新数据的传输需求时,应当使用快速发布方式,否则 TCP 的丢包会因恢复时间过长导致实时性下降。
普通发布方式
如下在 axis_server 微服务中封装一个陀螺仪数据发布的接口,对外提供一个 /axis
资源对数据进行发布。
#include <QCoreApplication>
#include <QDebug>
#include <QJsonDocument>
#include <QProcessEnvironment>
#include <QTimer>
#include <QVsoa>
constexpr char SERVER_INFO[] = "{\"name\":\"axis_server\"}";
constexpr char SERVER_PASSWORD[] = "123456";
constexpr char SERVER_ADDR[] = "0.0.0.0";
constexpr int SERVER_PORT = 3002;
using namespace std::placeholders;
void onNewClient(QPointer<QVsoaCliHandle> client)
{
qDebug() << QStringLiteral("New client, address: %1:%2").arg(client->address().ip()).arg(client->address().port());
}
void onDisconnected(QPointer<QVsoaCliHandle> client)
{
qDebug() << QStringLiteral("Client disconnect: %1:%2").arg(client->address().ip()).arg(client->address().port());
}
static int roll = 1;
static int pitch = 1;
static int yaw = 1;
void publishMessage(QVsoaServer *server)
{
if (server->isSubscribed("/axis")) {
QVariantMap param = {
{"poll", roll++ },
{"pitch", pitch++},
{"yaw", yaw++ }
};
// Publish /axis
server->publish("/axis", QVsoaPayload(QString::fromUtf8(QJsonDocument::fromVariant(param).toJson()), {}));
}
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// Initialize server
QVsoaServer server(SERVER_INFO);
if (server.isInvalid()) {
qDebug() << "Can not create VSOA server!";
return -1;
}
// If need password
server.setPassword(SERVER_PASSWORD);
QObject::connect(&server, &QVsoaServer::newClient, onNewClient);
QObject::connect(&server, &QVsoaServer::clientDisconnect, onDisconnected);
int port = SERVER_PORT;
int auto_port = QProcessEnvironment::systemEnvironment().value("VSOA_AUTO_PORT", "-1").toInt();
if (auto_port != -1) {
port = auto_port;
}
// Start server
if (!server.start(QVsoaSocketAddress(AF_INET, SERVER_ADDR, port))) {
qDebug() << "Can not start VSOA server!";
return -1;
}
qDebug() << "Started VSOA server.";
QTimer timer;
QObject::connect(&timer, &QTimer::timeout, std::bind(publishMessage, &server));
timer.start(1000);
return a.exec();
}
快速发布方式
对于 Qt 环境,将 publish 最后一个参数设置为“true” 即可。
server->publish("/axis", QVsoaPayload(QString::fromUtf8(QJsonDocument::fromVariant(param).toJson()), {}), true);