服务端开发

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

服务端开发

本节介绍 QVSOA 服务端使用 Middleware 的方法。

开发须知

QVSOA 服务端使用 QVsoaServer::addMiddleware 方法添加 Middleware,用户需要自行实现 IQVsoaMiddlewareListener 接口,注册到 Middleware 中使用。

开发示例

本例中,将在临时目录下创建一个“log_file”文件用于存储日志,同时将一个键为“log”的数据传递到下一个回调函数中。

#include <QCoreApplication>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QProcessEnvironment>
#include <QVsoa>

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;

class LogHook : public IQVsoaMiddlewareListener
{
public:
    LogHook()
        : m_file(QString("%1/log_file").arg(QDir::tempPath()))
    {
        if (!m_file.open(QIODevice::Append | QIODevice::Text)) {
            exit(-1);
        }
    }

    static void freeLogData(void *data, const QString &) { free(data); }

    bool hook(const QVsoaServer *,
              QPointer<QVsoaCliHandle>,
              const QVsoaHeader &,
              const QString &url,
              const QVsoaPayload &,
              QVsoaMiddlewareResolve &resolve) override
    {
        if (url.length() > 0) {
            auto data = QString("URL: %1\n").arg(url);
            m_file.write(data.toUtf8());
            m_file.flush();

            // Add a new message data to next handler
            resolve.addData("log", strdup("new resolved data"), LogHook::freeLogData);
        }

        // return true to continue processing next hook
        return true;
    }

private:
    QFile m_file;
};

class MsgHook : public IQVsoaMiddlewareListener
{
public:
    bool hook(const QVsoaServer *,
              QPointer<QVsoaCliHandle> client,
              const QVsoaHeader &header,
              const QString &,
              const QVsoaPayload &,
              QVsoaMiddlewareResolve &resolve) override
    {
        QVsoaPayload sendData("{\"light\": 1}", {});

        // get message data from previous callback
        char *msg = static_cast<char *>(resolve.getData("log"));
        if (msg) {
            qDebug() << QString::asprintf("Log resolved data (key: \"log\") : %s\n", msg);
        }

        // reply vsoa client
        client->reply(StatusCode::SUCCESS, header.seqno(), sendData, 0);

        // return false to stop processing next hook
        return false;
    }
};

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

    LogHook logHook;
    MsgHook msgHook;
    // add mware rpc hook
    // 'logHook' will be called first, if 'logHook' returns 'true'
    // then 'msgHook' will be called
    QVsoaMiddleware mware;
    mware.addListener(&logHook);
    mware.addListener(&msgHook);
    server.addMiddleware("/light", &mware);

    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();
}
文档内容是否对您有所帮助?
有帮助
没帮助