服务端开发
本节介绍服务端使用 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 客户端互联。