服务端开发

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

服务端开发

本节介绍服务端使用 VSOA Stream 的方法。

开发须知

QVSOA 服务端与客户端均使用 QVsoaStream::createStream 方法创建 Stream。 在服务端接收到客户端的 RPC 请求时,服务端先行创建 Stream 并返回 tunnel ID 给客户端,以供客户端连接。

开发示例

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

constexpr char SERVER_INFO[] = "{\"name\":\"vsoa_stream_server\"}";
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 ReadListener : public QVsoaRPCServerListener
{
    Q_OBJECT
public:
    ReadListener(QVsoaServer *server)
        : QVsoaRPCServerListener("/read"),
          m_server(server)
    {
        listen(server);
    }

    void onStreamConStatusChange(bool ok)
    {
        auto stream = qobject_cast<QVsoaStream *>(sender());
        if (!ok) {
            qDebug() << "Stream has no client connected.";
            stream->deleteLater();
            return;
        }
        char data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        if (stream->write(data, sizeof(data)) != sizeof(data)) {
            qDebug() << "Cannot write stream.";
        }
    }

protected:
    // /read Callback
    void onRPCCall(QPointer<QVsoaCliHandle> client,
                   const QVsoaHeader &header,
                   const QString &,
                   const QVsoaPayload &) override
    {
        auto stream = QVsoaStream::createStream(m_server, 1000, 5000);
        connect(stream, &QVsoaStream::connectionStatusChange, this, &ReadListener::onStreamConStatusChange);

        // make a client reply
        client->reply(StatusCode::SUCCESS, header.seqno(), QVsoaPayload{}, stream->tunid());
        qDebug() << "Replied client stream tunnel ID:" << stream->tunid();
    }

private:
    QVsoaServer *m_server;
};

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

    QObject::connect(&server, &QVsoaServer::newClient, onNewClient);
    QObject::connect(&server, &QVsoaServer::clientDisconnect, onDisconnected);

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

注意:
QVSOA 服务端可以与 C、JavaScript、Java 的 VSOA 客户端互联。

文档内容是否对您有所帮助?
有帮助
没帮助