Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3
Wiki Markup
QtNetwork modulin laajennos.


h3. QxtRPCPeer-luokka

QxtRPCPeer-luokka tarjoaa mahdollisuuden signaalien lähettämiseen verkkoyhteyden välityksellä.

Seuraavana esimerkki, jossa esitellään käyttäjän (Client) ja serverin (Server) toiminta, sekä pieni pääohjelma jossa käyttäjä yhdistetään serveriin. Ideana on, että serveriin (joka esimerkiksi ylläpitää jonkin laitteen toimintaa) voidaan ottaa yhteys verkosta.

*tcp_client.h*

{code}
#ifndef TCP_CLIENT_H
#define TCP_CLIENT_H

#include <QxtNetwork/qxtrpcpeer.h>

class TCPClient : public QObject
{
    Q_OBJECT
public:
    TCPClient();
    ~TCPClient();

private:
    /// QxtRPCPeer-olio joka huolehtii fyysisesti serverille yhdistämisestä
    /// ja signaalin lähettämisestä/vastaanottamisesta
    QxtRPCPeer *client;

    /// Serverin IP
    QString hostIp;

    /// Serverin portti
    int hostPort;

    /// Ollaanko yhteydessä vai ei
    bool connected;

signals:
    /// Signaalin (viestin) lähettäminen serverille
    void sendSignal(QVector<QString>);

    /// Signaali, kun serveriin yhdistäminen onnistuu
    void connectedToServer();

    /// Signaali, kun serveriin yhdistäminen epäonnistuu
    void serverError();

private slots:
    /// Slotti, joka yhdistää käyttäjän serveriin
    void connectToServer();

    /// Slotti, joka yhdistää käyttäjän serveriin (annettuun ip-osoitteeseen (QString)
    /// ja annettuun porttiin (int))
    void connectToServer(QString, int);

    /// Yhteyden katkaiseminen serveriin
    void disconnectFromServer();

    /// Viestin lähetys, aktivoi sendSignal()-signaalin
    void sendData(QVector<QString>);

    /// Viestin vastaanotto serveriltä (esim. käyttöliittymän päivittäminen uusilla tiedoilla)
    void receiveData(QVector<QString>);

    /// Ilmoitus mikäli yhteyden luominen onnistui (ei pakollinen)
    void connectionEstablished();

    /// Ilmoitus mikäli yhteyden muodostamisessa ilmenee ongelmia (ei pakollinen)
    void connectionError();
};

#endif // TCP_CLIENT_H
{code}
*tcp_client.cpp*

{code}
 #include "tcp_client.h"

TCPClient::TCPClient()
{
    /// Olion luominen
    client = new QxtRPCPeer();

    /// Oletus IP, johon yhdistetään mikäli käyttäjä ei syötä IP:tä
    hostIp = "127.0.0.1";

    /// Oletusportti johon yhdistetään
    hostPort = 45123;

    /// Ollaanko yhteydessä? Oletuksena false
    connected = false;

    /// Jotta signaaleihin voidaan yhdistää QVector-tyyppisiä parametreja, on ne määrittettävä seuraavasti
    qRegisterMetaTypeStreamOperators< QVector<QString> >("QVector<QString>");

    /// Liitetään signaalit slotteihin
    connect(this->client, SIGNAL(connectedToServer()), this, SLOT(connectionEstablished()));
    connect(this->client, SIGNAL(serverError(QAbstractSocket::SocketError)), this, SLOT(connectionError()));

    /// attachSignal-funktio kapseloi signaalin muotoon, jossa se voidaan lähettää verkkoyhteyden yli
    /// Funktion QString-parametri on tunniste, jolla signaali tunnistetaan serverin puolella ja
    /// pystytään yhdistämään tiettyyn slottiin.
    client->attachSignal(this, SIGNAL(sendSignal(QVector<QString>)), QString("signalToServer"));

    /// attachSlot-funktio vastaanottaa serveriltä tullevan kapseloidun signaalin,
    /// joka välitetään receiveData-slotille
    client->attachSlot(QString("signalFromServer"), this, SLOT(receiveData(QVector<QString>)));
}
TCPClient::~TCPClient()
{
    /// Poistetaan muodostettu olio muistin säästämiseksi
    delete client;
}

/// Yhdistetään serveriin oletusarvoilla tai käyttäjän antamilla arvoilla
void TCPClient::connectToServer()
{
    /// Connect metodi muodostaa connectedToServer- tai serverError-signaalin
    client->connect(this->hostIp, this->hostPort);
}
void TCPClient::connectToServer(QString ip, int port)
{
    client->connect(ip, port);
}
void TCPClient::disconnectFromServer()
{
    client->disconnectServer();
    connected = false;
}

void TCPClient::sendData(QVector<QString> data)
{
    emit sendSignal(data);
}
void TCPClient::receiveData(QVector<QString>)
{
    qDebug() << "message from server";
}

void TCPClient::connectionEstablished()
{
    connected = true;
    qDebug() << "connected";
}
void TCPClient::connectionError()
{
    qDebug() << "connection error";
}
{code}

*tcp_server.h*
{code}
#ifndef TCP_SERVER_H
#define TCP_SERVER_H

#include <QxtNetwork/qxtrpcpeer.h>

class TCPServer : public QObject
{
    Q_OBJECT
public:
    TCPServer();
    ~TCPServer();

    /// Serverin käynnistäminen oletusarvoilla
    void startServer();

    /// Serverin käynnistäminen käyttäjän antamilla parametreilla
    void startServer(QHostAddress, int);

    /// Serverin pysäyttäminen
    void stopServer();

private:
    /// QxtRPCPeer-olio joka huolehtii fyysisesti serverin toiminnasta (uusien yhteyksien
    /// kuuntelusta, signaalien vastaanottamisesta/lähettämisestä jne.)
    QxtRPCPeer *server;

    /// Serverin ip-osoite
    QHostAddress serverIp;

    /// Serverin käyttämä portti
    int serverPort;

    /// Lista pitämään kirjaa aktiivisista yhteyksistä (käyttäjistä/clienteista)
    QList<quint64> clients;

signals:
    /// Signaali, joka muodostetaan käyttäjän yhdistyessä serverille
    void clientConnected(quint64);

    /// Signaali käyttäjän katkaistaessa yhteyden
    void clientDisconnected(quint64);

    /// Signaali, joka lähetetään takaisin käyttäjälle (esim. käyttöliittymän päivittäminen)
    void sendSignal(QVector<QString>);

private slots:
    /// Slotti jossa lisätään käyttäjä yhteyslistaan (clients) jne.
    void newClient(quint64);

    /// Slotti, jossa poistetaan käyttäjä yhteyslistasta tämän katkaistaessa yhteyden
    void deleteClient(quint64);

    /// Slotti joka huolehtii käyttäjältä tulevan signaalin käsittelystä
    void receiveSignal(quint64, QVector<QString>);
};

#endif // TCP_SERVER_H
{code}
*tcp_server.cpp*
{code}
#include "tcp_server.h"

TCPServer::TCPServer()
{
    server = new QxtRPCPeer();
    serverIp = QHostAddress::Any;
    serverPort = 45123;

    /// Signaalien ja slottien yhdistäminen Client-puolen tapaan
    qRegisterMetaTypeStreamOperators< QVector<QString> >("QVector<QString>");
    /// Käyttäjältä tulevassa signaalissa on lisänä quint64-tyyppinen muuttuja, joka on yhteyden ID
    server->attachSlot(QString("signalToServer"), this, SLOT(receiveSignal(quint64, QVector<QString>)));
    server->attachSignal(this, SIGNAL(sendSignal(QVector<QString>)), QString("signalFromServer"));

    connect(this->server, SIGNAL(clientConnected(quint64)), this, SLOT(newClient(quint64)));
    connect(this->server, SIGNAL(clientDisconnected(quint64)), this, SLOT(deleteClient(quint64)));
}
TCPServer::~TCPServer()
{
    delete server;
}
void TCPServer::startServer()
{
    /// Käynnistetään serveri listen-funktiolla, jolloin se kuuntelee jatkuvasti uusia yhteyksiä
    /// Huom. Client-puolella ei käytetä listen-funktiota, vaan pelkästään connect-funktiota
    server->listen(this->serverIp, this->serverPort);

    qDebug() << "server up";
}
void TCPServer::startServer(QHostAddress address, int port)
{
    server->listen(address, port);

    qDebug() << "server up";
}
void TCPServer::stopServer()
{
    server->stopListening();
    clients.empty();

    qDebug() << "server down";
}

void TCPServer::newClient(quint64 clientId)
{
    clients.append(clientId);

    qDebug() << clientId << " connected";
}
void TCPServer::deleteClient(quint64 clientId)
{
    int delClient = clients.indexOf(clientId);
    clients.removeAt(delClient);

    qDebug() << clientId << " disconnected";
}

void TCPServer::receiveSignal(quint64 connectionId, QVector<QString> data)
{
    // Tee jotain data:lle

    // Lähetetään tietoa serverin tilasta takaisin käyttäjälle
    // emit sendSignal(vector);
}
{code}

*main.cpp*
{code}
///Pääohjelma
{code}