WIP-How to create a simple chat application: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(Created page with "=== Introduction === This article will illustrate a simple chat client and server communicating over TCP. The aim is to clarify aspects of QTcpSocket/QTcpServer that are not d...")
 
No edit summary
Line 34: Line 34:
{
{
     connect(this,&ServerSocket::readyRead,this,&ServerSocket::receiveJson);
     connect(this,&ServerSocket::readyRead,this,&ServerSocket::receiveJson);
}
void ServerSocket::sendJson(const QByteArray &jsonData)
{
    QDataStream socketStream(this);
    socketStream.setVersion(QDataStream::Qt_5_9);
    socketStream << jsonData;
}
}


Line 40: Line 47:
     QByteArray jsonData;
     QByteArray jsonData;
     QDataStream socketStream(this);
     QDataStream socketStream(this);
    socketStream.setVersion(QDataStream::Qt_5_9);
     socketStream.startTransaction();
     socketStream.startTransaction();
     socketStream >> jsonData;
     socketStream >> jsonData;
Line 48: Line 56:
             emit jsonReceived(jsonDoc);
             emit jsonReceived(jsonDoc);
     }
     }
}
void ServerSocket::sendJson(const QByteArray &jsonData)
{
    QDataStream socketStream(this);
    socketStream << jsonData;
}
}
</code>
</code>
The implementation is also relatively straightforward.
The constructor calls the base class and the connects the <tt>readyRead</tt> signal to <tt>receiveJson</tt> slot that will take care of decoding the data.
<tt>sendJson</tt>

Revision as of 14:57, 15 May 2018

Introduction

This article will illustrate a simple chat client and server communicating over TCP. The aim is to clarify aspects of QTcpSocket/QTcpServer that are not developed in the official Qt Fortune example. This has no intention to be a fully featured chat application

The Logic

This application will use a central server that will manage the communication among clients via JSON messages. On the server side, we'll distribute the clients over multiple threads to speed up the processing.

The Server Socket

The fist class we'll look at is the socket on the server that will communicate with a single client

#include <QTcpSocket>
class ServerSocket : public QTcpSocket
{
    Q_OBJECT
    Q_DISABLE_COPY(ServerSocket)
public:
    explicit ServerSocket(QObject* parent = nullptr);
private slots:
    void receiveJson();
    void sendJson(const QByteArray& jsonData);
signals:
    void jsonReceived(const QJsonDocument& jsonDoc);
};

The declaration is very simple, we are just adding 2 slots: sendJson to send messages to the client and receiveJson to receive and decode a message coming from the client. The jsonReceived signal will notify the server of incoming data.

#include "serversocket.h"
#include <QDataStream>
#include <QJsonDocument>
#include <QJsonParseError>
ServerSocket::ServerSocket(QObject* parent)
    :QTcpSocket(parent)
{
    connect(this,&ServerSocket::readyRead,this,&ServerSocket::receiveJson);
}

void ServerSocket::sendJson(const QByteArray &jsonData)
{
    QDataStream socketStream(this);
    socketStream.setVersion(QDataStream::Qt_5_9);
    socketStream << jsonData;
}

void ServerSocket::receiveJson()
{
    QByteArray jsonData;
    QDataStream socketStream(this);
    socketStream.setVersion(QDataStream::Qt_5_9);
    socketStream.startTransaction();
    socketStream >> jsonData;
    if(socketStream.commitTransaction()){
        QJsonParseError parseError;
        const QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData,&parseError);
        if(parseError.error == QJsonParseError::NoError)
            emit jsonReceived(jsonDoc);
    }
}

The implementation is also relatively straightforward. The constructor calls the base class and the connects the readyRead signal to receiveJson slot that will take care of decoding the data. sendJson