Skip to content
Snippets Groups Projects
websocketserver.cpp 3.26 KiB
Newer Older
akiraohgaki's avatar
akiraohgaki committed
#include "websocketserver.h"

#include <QHostAddress>
#include <QWebSocketServer>
akiraohgaki's avatar
akiraohgaki committed
#include <QWebSocket>
#include "qtlib_json.h"

akiraohgaki's avatar
akiraohgaki committed
WebSocketServer::WebSocketServer(const QString &serverName, quint16 serverPort, QObject *parent)
    : QObject(parent), serverName_(serverName), serverPort_(serverPort)
{
akiraohgaki's avatar
akiraohgaki committed
    wsServer_ = new QWebSocketServer(serverName_, QWebSocketServer::NonSecureMode, this);
    connect(wsServer_, &QWebSocketServer::newConnection, this, &WebSocketServer::wsNewConnection);
    connect(wsServer_, &QWebSocketServer::closed, this, &WebSocketServer::stopped);
akiraohgaki's avatar
akiraohgaki committed
}

WebSocketServer::~WebSocketServer()
{
akiraohgaki's avatar
akiraohgaki committed
    stop();
akiraohgaki's avatar
akiraohgaki committed
    wsServer_->deleteLater();
akiraohgaki's avatar
akiraohgaki committed
}

bool WebSocketServer::start()
{
akiraohgaki's avatar
akiraohgaki committed
    if (wsServer_->listen(QHostAddress::Any, serverPort_)) {
akiraohgaki's avatar
akiraohgaki committed
        emit started();
        return true;
    }
    return false;
akiraohgaki's avatar
akiraohgaki committed
}

void WebSocketServer::stop()
{
akiraohgaki's avatar
akiraohgaki committed
    wsServer_->close();
akiraohgaki's avatar
akiraohgaki committed

bool WebSocketServer::isError()
{
akiraohgaki's avatar
akiraohgaki committed
    if (wsServer_->error() != QWebSocketProtocol::CloseCodeNormal) {
akiraohgaki's avatar
akiraohgaki committed
        return true;
    }
    return false;
}

QString WebSocketServer::errorString()
{
akiraohgaki's avatar
akiraohgaki committed
    return wsServer_->errorString();
akiraohgaki's avatar
akiraohgaki committed
}

QUrl WebSocketServer::serverUrl()
{
akiraohgaki's avatar
akiraohgaki committed
    return wsServer_->serverUrl();
}

void WebSocketServer::wsNewConnection()
{
    QWebSocket *wsClient = wsServer_->nextPendingConnection();
    connect(wsClient, &QWebSocket::disconnected, this, &WebSocketServer::wsDisconnected);
akiraohgaki's avatar
akiraohgaki committed
    connect(wsClient, &QWebSocket::textMessageReceived, this, &WebSocketServer::wsTextMessageReceived);
    connect(wsClient, &QWebSocket::binaryMessageReceived, this, &WebSocketServer::wsBinaryMessageReceived);
akiraohgaki's avatar
akiraohgaki committed
    wsClients_ << wsClient;
}

akiraohgaki's avatar
akiraohgaki committed
void WebSocketServer::wsDisconnected()
akiraohgaki's avatar
akiraohgaki committed
{
    QWebSocket *wsClient = qobject_cast<QWebSocket *>(sender());
    if (wsClient) {
akiraohgaki's avatar
akiraohgaki committed
        wsClients_.removeAll(wsClient);
        wsClient->deleteLater();
akiraohgaki's avatar
akiraohgaki committed
    }
}

void WebSocketServer::wsTextMessageReceived(const QString &message)
{
    QWebSocket *wsClient = qobject_cast<QWebSocket *>(sender());
    if (wsClient) {
        qtlib::Json json(message.toUtf8());
        if (json.isValid()) {
akiraohgaki's avatar
akiraohgaki committed
            callFunction(json.toObject(), wsClient);
akiraohgaki's avatar
akiraohgaki committed
void WebSocketServer::wsBinaryMessageReceived(const QByteArray &message)
akiraohgaki's avatar
akiraohgaki committed
{
    QWebSocket *wsClient = qobject_cast<QWebSocket *>(sender());
    if (wsClient) {
akiraohgaki's avatar
akiraohgaki committed
        qtlib::Json json(message);
        if (json.isValid()) {
            callFunction(json.toObject(), wsClient);
        }
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed
}
akiraohgaki's avatar
akiraohgaki committed

void WebSocketServer::callFunction(const QJsonObject &request, QWebSocket *wsClient)
{
    /* request object format
    {
        "id": "example",
        "call": "functionName",
        "args": {
            "arg1": "value",
            "arg2": 2,
            "arg3": true
        }
    }
    */

    /* response object format
    {
        "id": "example",
        "result": {}
    }
    */

    QString id = request["id"].toString();
    QString call = request["call"].toString();
    QJsonObject args = request["args"].toObject();

    QJsonObject response;
    response["id"] = id;

    if (call == "WebSocketServer::stop") {
        stop();
    }
    else if (call == "WebSocketServer::serverUrl") {
        response["result"] = serverUrl().toString();
    }

    wsClient->sendTextMessage(QString(qtlib::Json(response).toJson()));
    //wsClient->sendBinaryMessage(qtlib::Json(response).toJson());
}