服务端开发
本节介绍 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();
}