WIP-How to create a simple chat application: Difference between revisions
No edit summary |
No edit summary |
||
Line 50: | Line 50: | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Private Members | ! colspan="2" | Private Members | ||
|- | |||
| <tt>m_clientSocket</tt> || The socket that will interact with the server | | <tt>m_clientSocket</tt> || The socket that will interact with the server | ||
|- | |- | ||
| <tt>m_loggedIn</tt> || Used to record whether the client already agreed a username with the server or not | | <tt>m_loggedIn</tt> || Used to record whether the client already agreed a username with the server or not | ||
|- | |||
! colspan="2" | Private Methods and Slots | |||
|- | |||
| <tt>onReadyRead()</tt> || Slot that reacts to data being available on the socket. It will download the data and pass it to <tt>jsonReceived()</tt> | |||
|- | |- | ||
| <tt>jsonReceived()</tt> || Method to process the messages received from the server | | <tt>jsonReceived()</tt> || Method to process the messages received from the server | ||
|- | |- | ||
| <tt> | ! colspan="2" | Signals | ||
|- | |||
| <tt>connected()</tt> || The client connected to the server successfully | |||
|- | |||
| <tt>disconnected()</tt> || The client is not connected any more | |||
|- | |- | ||
| | | <tt>loggedIn()</tt> || The client successfully agreed a username with the server | ||
|- | |- | ||
| | | <tt>loginError()</tt> || The server rejected the username provided | ||
|- | |- | ||
| | | <tt>messageReceived()</tt> || The client received a chat message | ||
|- | |- | ||
| | | <tt>userJoined()</tt> || A new user joined the chat | ||
|- | |- | ||
| | | <tt>userLeft()</tt> || A user left the chat | ||
|- | |- | ||
| | | <tt>error()</tt> || Just a forward of the [http://doc.qt.io/qt-5/qabstractsocket.html#error QTcpSocket::error signal] | ||
|- | |- | ||
| | ! colspan="2" | Public Slots | ||
|- | |- | ||
| | | <tt>connectToServer()</tt> || Attempts the connection to a server | ||
|- | |- | ||
| | | <tt>login()</tt> || Attempts to agree the given username with the server | ||
|- | |- | ||
| | | <tt>disconnectFromHost()</tt> || Closes the connection with the server | ||
|- | |- | ||
| | | <tt>sendMessage()</tt> || Sends a chat message to the server | ||
|- | |- | ||
|} | |} | ||
Revision as of 10:49, 1 June 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.
You can find the source code relating to this example on GitHub
Pre-Requisites
An intermediate level of knowledge of Qt Familiarity with C++11 concepts, especially lambdas and std::bind
The Logic
This application will use a central server that will manage the communication among clients via JSON messages. We'll implement 2 versions of the server, one that runs in a single server and one that distributes the sockets among multiple threads.
The Client
The client in this example is a simple QtWidgets application, the ui is minimal, just a button to connect to the server, a list view to display the messages received, a line edit to type your messages and a button to send them.
The core of the functionality is in the ChatClient class.
class ChatClient : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(ChatClient)
public:
explicit ChatClient(QObject *parent = nullptr);
public slots:
void connectToServer(const QHostAddress &address, quint16 port);
void login(const QString &userName);
void sendMessage(const QString &text);
void disconnectFromHost();
private slots:
void onReadyRead();
signals:
void connected();
void loggedIn();
void loginError(const QString &reason);
void disconnected();
void messageReceived(const QString &sender, const QString &text);
void error(QAbstractSocket::SocketError socketError);
void userJoined(const QString &username);
void userLeft(const QString &username);
private:
QTcpSocket *m_clientSocket;
bool m_loggedIn;
void jsonReceived(const QJsonObject &doc);
};
Let's break down what each of these methods and member does:
Private Members | |
---|---|
m_clientSocket | The socket that will interact with the server |
m_loggedIn | Used to record whether the client already agreed a username with the server or not |
Private Methods and Slots | |
onReadyRead() | Slot that reacts to data being available on the socket. It will download the data and pass it to jsonReceived() |
jsonReceived() | Method to process the messages received from the server |
Signals | |
connected() | The client connected to the server successfully |
disconnected() | The client is not connected any more |
loggedIn() | The client successfully agreed a username with the server |
loginError() | The server rejected the username provided |
messageReceived() | The client received a chat message |
userJoined() | A new user joined the chat |
userLeft() | A user left the chat |
error() | Just a forward of the QTcpSocket::error signal |
Public Slots | |
connectToServer() | Attempts the connection to a server |
login() | Attempts to agree the given username with the server |
disconnectFromHost() | Closes the connection with the server |
sendMessage() | Sends a chat message to the server |