WIP-How to create a simple chat application

From Qt Wiki
Revision as of 14:48, 15 May 2018 by VRonin (talk | contribs) (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...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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::receiveJson()
{
    QByteArray jsonData;
    QDataStream socketStream(this);
    socketStream.startTransaction();
    socketStream >> jsonData;
    if(socketStream.commitTransaction()){
        QJsonParseError parseError;
        const QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData,&parseError);
        if(parseError.error == QJsonParseError::NoError)
            emit jsonReceived(jsonDoc);
    }
}

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