服务端开发

更新时间:
2024-02-20
下载文档

服务端开发

本节内容介绍 QVSOA 服务端使用 RPC 的方法。

开发须知

微服务对外提供 RPC 服务时,需要指定该 RPC 的 URL 资源标识并将该 URL 加入监听。QVSOA 提供了 QVsoaRPCServerListener 监听 RPC 请求。

开发示例

例如将“灯光状态”定义为一个 /light 的 URL 资源标识,供调用 RPC 的客户端获取灯光状态。

创建一个 RPC 监听器,当客户端调用 /lightQVsoaRPCServerListener 或其子类将感知到 RPC 调用并执行用户代码。具体代码示例如下:

#include <QCoreApplication>
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QVsoa>
#include <QProcessEnvironment>

constexpr char SERVER_INFO[] = "{\"name\":\"light_server\"}";
constexpr char SERVER_PASSWORD[] = "123456";
constexpr char SERVER_ADDR[] = "0.0.0.0";
constexpr int SERVER_PORT = 3001;

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

class LightListener : public QVsoaRPCServerListener
{
    Q_OBJECT
public:
    enum LightState {
        ON = 1,
        OFF = 0
    };

    LightListener(QObject *parent = nullptr)
        : QVsoaRPCServerListener("/light", parent)
    {}

protected:
    void onRPCCall(QPointer<QVsoaCliHandle> client,
                   const QVsoaHeader &header,
                   const QString &,
                   const QVsoaPayload &payload) override
    {
        if (header.flags() & FlagCode::FLAG_SET) {
            auto doc = QJsonDocument::fromJson(payload.param().toUtf8());
            auto object = doc.object();
            m_lightState = static_cast<LightState>(object["light"].toInt());
        }

        QJsonObject obj;
        obj["light"] = static_cast<int>(m_lightState);
        QJsonDocument doc(obj);
        client->reply(StatusCode::SUCCESS, header.seqno(), QVsoaPayload(QString::fromUtf8(doc.toJson()), {}));
    }

private:
    LightState m_lightState = LightState::OFF;
};

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

    // Add /light listener
    LightListener listener;
    listener.listen(&server);

    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.";

    return a.exec();
}
文档内容是否对您有所帮助?
有帮助
没帮助