Are you forced to use Sockets or can you use Websockets too? If so, Qt has a wonderful way to deal with Websockets and Signals / Slots.
For example, here's what I use for my Remote Control App on my smartphone to control my Music Player (the code has been truncated). But the server can also send commands to synchronize the UI on the smartphone.
The client:
RemoteClient::RemoteClient(CoverProvider *coverProvider, QObject *parent)
: QObject(parent)
, _socket(new QWebSocket("remote", QWebSocketProtocol::VersionLatest, this))
{
connect(_socket, &QWebSocket::textMessageReceived, this, &RemoteClient::processTextMessage);
}
/// Direction: Remote App is receiving orders from Server
void RemoteClient::processTextMessage(const QString &message)
{
if (message.isEmpty()) {
return;
}
QStringList list = message.split(QChar::Null);
if (list.size() <= 1) {
return;
}
int command = list.first().toInt();
switch (command) {
case CMD_Playback:
// Nothing
break;
case CMD_State: {
QMediaPlayer::State state = (QMediaPlayer::State) list.at(1).toInt();
if (state == QMediaPlayer::PlayingState) {
emit playing();
} else if (state == QMediaPlayer::PausedState) {
emit paused();
} else {
emit stopped();
}
break;
}
case CMD_Track:
/// etc.
break;
}
/// etc.
default:
break;
}
}
/// Direction: Remote App is sending orders to Server
void RemoteClient::setVolume(qreal v)
{
QStringList args = { QString::number(CMD_Volume), QString::number(v) };
_socket->sendTextMessage(args.join(QChar::Null));
}
The server:
void RemoteControl::startServer()
{
auto b = _webSocketServer->listen(QHostAddress::Any, _port);
qDebug() << Q_FUNC_INFO << b;
}
void RemoteControl::initializeConnection()
{
/// ...
connect(mediaPlayer(), &MediaPlayer::volumeChanged, this, &RemoteControl::sendVolume);
}
/// Direction: Server to updating Remote App
void RemoteControl::sendVolume(qreal volume)
{
QStringList args = { QString::number(CMD_Volume), QString::number(volume) };
_webSocket->sendTextMessage(args.join(QChar::Null));
}
/// Direction: Remote App is sending command to Server
void RemoteControl::decodeResponseFromClient(const QString &message)
{
if (message.isEmpty()) {
return;
}
QStringList args = message.split(QChar::Null);
if (args.count() < 2) {
return;
}
int command = args.first().toInt();
switch (command) {
case CMD_Volume: {
qreal volume = args.at(1).toFloat();
_currentView->mediaPlayerControl()->mediaPlayer()->setVolume(volume);
break;
}
/// etc.
}
}