Bevezetés

Első körben szeretnénk ismertetni, hogy házifeladatunk megoldásához milyen technológiákat használtunk, amik nagy mértékben megkönnyítették a programjaink megírását. Ezek a következők voltak: Websocket, JSON, és JavaScript használta a szimulátorhoz.

Websocket

Kommunikációra magasabb nyelven írt applikációkban érdemes lehet a websocket használta. Használata nagyon egyszerű, valós idejű alkalmazásoknál nagyon gyakran használják.

Mi is a Websocket

Egy kétirányú kommunikációs csatorna ami duplex kommunikációt valósít meg, TCP-re épül. A kiépítéséhez egy HTTP kommunikációra van szükség, ahol a két fél megegyezik arról, hogy „felfejlesztik” a kommunikációt innentől WebSocketre. Innentől már csak TCP fölött kommunikának, amit nagyon kis overheaddel tud a szerver és a kliens megvalósítani. Nagy előnye a HTTP-vel szemben, hogy a két félnek nem kell folyton pollingolnia egymást, hanem ha van adat azt egyből tudják küldeni a másik fél részére. Mivel HTTP-n indul a kommunikáció, így egy HTTP-s webszerveren könnyedén megvalósítható ez a módszer. A kis overhead, és a pusholt adatok miatt valós idejű komminkációk megvalósításához nagyon elterjedt technológia.

#JSON (JavaScript Object Notation):

Adatok átviteléhez érdemes az üzeneteket valamilyen struktúrába becsomagolni. Erre az egyik legegyszerűbb lehetőség a JSON használta.

Ember által is olvasható, kisméretű szabvány, ami összesen 6 féle adattípust használ: szám, szöveg, boolean, null, objektum és tömb. Ezekkel általában mindent le lehet írni, akár több szintű struktúrákat is. Napjainkban nagyon elterjedt, szinte mindenhol ezt használnak adatcserére, ahol nem szükséges bináris adatátvitel, vagy nem probléma a szerializálás számításigényessége.

Az XML-hez képest sokkal kisebb a mérete, sokkal kevesebb memóriát igényel és egyszerűbb a szerializálása, egyetlen hátránya, hogy nem lehet benne kommentet használni.

JavaScript

Alapból a QML is használ JavaScriptet ezért a megismerése ebből a szempontból is előnyös a félév során. Ugyan interpreteres és gyengén típusos nyelv, de ezzel körülbelül minden negatívumát elmondtuk. Természetesen a sebessége sem egyezik meg egy hasonló C++-os kódéval, de nem is olyan helyeken kell használni, ahol arra kell kiélezni az alkalmazást. A megismerését megkönnyíti, hogy szintakszisa nagyon hasonló a C++-hoz.

Könnyen lehet vele egyszerű programokat összerakni. Ilyen volt a mi esetünkben is a szimulátor, ami csak tárol pár állapotot, és a kapott üzenetekre megváltoztatja azokat, és visszakommunikál.

Sok programkönyvtár található hozzá, például a korábban ismertetett Websocket, és a gyakran használatos műveletek JSON-ökkel már implementálva vannak benne. Ezen felül HTTP szervert, TCP klienst és szervert is könnyen lehet vele megvalósítani.

Websocket használata QT-ben, QML-ben és JavaScriptben JSON adatcsomagokra:

QML-ben is van implementációja (import QtWebSockets 1.0) mind a Websocket szervernek, mind a kliensnek.

QML:

    WebSocket {
            id: socket
            url: "ws://localhost:8080"
            onTextMessageReceived: {
                console.log("Recieved message: " + message)
                var jsonmsg = JSON.parse(message) 
            }
            onStatusChanged: if (socket.status == WebSocket.Error) {
                                 console.log("Error: " + socket.errorString)
                             } else if (socket.status == WebSocket.Open) {
                                 console.log("opened")
                             } else if (socket.status == WebSocket.Closed) {
                                 messageBox.text += "\nSocket closed"
                             }
            active: true
        }

Az 1. Sorban létrehozzuk a Websocket klienst, a 3. sorban megadjuk, hogy hova csatlakozzon fel. A 4. sorban feliratkozunk arra az eseményre ha üzenet érkezik. Az üzenetet a ’message’ változóban találjuk szöveg formátumban, amit egyből ki is írathatunk a konzolra. Ha JSON üzeneteket használunk, akkor a var jsonmsg = JSON.parse(message) -el már szét is parseolhatjuk, és ki lehet olvasni belőle a változók értékeit.

Az onStatusChanged arra szolgál, hogy lekezeljük hogy a kommunikációs csatornánkkal mi történik.

QT-ban ugyanez a kód:

Ahhoz hogy használni tudjuk be kell importálni a QtWebSockets/QWebSocket -et. Létre kell hozni egy példányt belőle:

 QWebSocket m_webSocket; 

majd:

    connect(&m_webSocket, &QWebSocket::connected, this, &WebSocketClient::onConnected);
    connect(&m_webSocket, &QWebSocket::textMessageReceived,
    this, &WebSocketClient::onTextMessageReceived);

Az első sorral lehet beállítani, hogy a Websocket csatlakozásakor melyik függvény fusson le, a másodikkal, hogy amikor üzenet jön, akkor melyik.

    m_webSocket.open(QUrl(url));

Így lehet felcsatalkozni egy url-re.

    void WebSocketClient::onTextMessageReceived(QString message)
    {
        if (m_debug)
            qDebug() << "Message received:" << message;
    
        QJsonObject obj;
        QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8());
    }

Ez pedig az onTextMessageReceived függvény fogadása, ami szintén kiíratja a kapott üzenetet és parseolja a JSON-t. Innen már az üzenetnek megfelelően lehet az alkalmazásunkat elágaztatni.

Üzenet kültésére használható függvény:

    m_webSocket.sendTextMessage(Hello);

JavaScriptben egy Websocket szerver készítése:

    var WebSocketServer = require('websocket').server;
    var http = require('http');
    
    var server = http.createServer(function(request, response) {
        console.log((new Date()) + ' Received request for ' + request.url);
        response.writeHead(404);
        response.end();
    });
    server.listen(8080, function() {
        console.log((new Date()) + ' Server is listening on port 8080');
    });
    
    wsServer = new WebSocketServer({
        httpServer: server,
        autoAcceptConnections: true
    });
    
        console.log((new Date()) + ' Connection accepted.');
    
    connection.on('message', function(message) {
        if (message.type === 'utf8') {
            console.log('Received Message: ' + message.utf8Data);
            try {
                var jsonMessage = JSON.parse(message.utf8Data);
                connection.send(JSON.stringify({message: jsonMessage["message"]}));
            }
            catch (e) {
                console.error(e);
            }
        }
    }

Ez a kód létrehoz egy http szervert, ami a Websocket szerver alapja. Utána erre létrehozza a Websocket szervert, ami annyit csinál, hogy egy JSON objektumban kapott „message” kulccsal tárolt szöveget belerak egy JSON objektumnak szintén a „message” tagjába, és visszaküldi.

További információk