Examples: use CBOR in the network-chat broadcast message

Instead of sending one @-separated message, send one CBOR message. The
message structure is, using the CBOR Data Definition Language:

  broadcast = [
    username: tstr,
    port: 0..65535
  ]

Change-Id: Ic38ec929fc3f4bb795dafffd150ac2614d18c6bf
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Thiago Macieira 2018-01-17 17:12:27 -08:00
parent bfcb8c6dca
commit 9998654eac
3 changed files with 39 additions and 19 deletions

View File

@ -78,7 +78,7 @@ void Client::sendMessage(const QString &message)
QString Client::nickName() const
{
return QString(peerManager->userName()) + '@' + QHostInfo::localHostName()
return peerManager->userName() + '@' + QHostInfo::localHostName()
+ ':' + QString::number(server.serverPort());
}

View File

@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
@ -62,16 +63,14 @@ PeerManager::PeerManager(Client *client)
{
this->client = client;
QStringList envVariables;
envVariables << "USERNAME" << "USER" << "USERDOMAIN"
<< "HOSTNAME" << "DOMAINNAME";
static const char *envVariables[] = {
"USERNAME", "USER", "USERDOMAIN", "HOSTNAME", "DOMAINNAME"
};
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
foreach (QString string, envVariables) {
if (environment.contains(string)) {
username = environment.value(string).toUtf8();
for (const char *varname : envVariables) {
username = qEnvironmentVariable(varname);
if (!username.isNull())
break;
}
}
if (username.isEmpty())
@ -95,7 +94,7 @@ void PeerManager::setServerPort(int port)
serverPort = port;
}
QByteArray PeerManager::userName() const
QString PeerManager::userName() const
{
return username;
}
@ -116,9 +115,14 @@ bool PeerManager::isLocalHostAddress(const QHostAddress &address)
void PeerManager::sendBroadcastDatagram()
{
QByteArray datagram(username);
datagram.append('@');
datagram.append(QByteArray::number(serverPort));
QByteArray datagram;
{
QCborStreamWriter writer(&datagram);
writer.startArray(2);
writer.append(username);
writer.append(serverPort);
writer.endArray();
}
bool validBroadcastAddresses = true;
foreach (QHostAddress address, broadcastAddresses) {
@ -142,11 +146,27 @@ void PeerManager::readBroadcastDatagram()
&senderIp, &senderPort) == -1)
continue;
QList<QByteArray> list = datagram.split('@');
if (list.size() != 2)
continue;
int senderServerPort;
{
// decode the datagram
QCborStreamReader reader(datagram);
if (reader.lastError() != QCborError::NoError || !reader.isArray())
continue;
if (!reader.isLengthKnown() || reader.length() != 2)
continue;
reader.enterContainer();
if (reader.lastError() != QCborError::NoError || !reader.isString())
continue;
while (reader.readString().status == QCborStreamReader::Ok) {
// we don't actually need the username right now
}
if (reader.lastError() != QCborError::NoError || !reader.isUnsignedInteger())
continue;
senderServerPort = reader.toInteger();
}
int senderServerPort = list.at(1).toInt();
if (isLocalHostAddress(senderIp) && senderServerPort == serverPort)
continue;

View File

@ -68,7 +68,7 @@ public:
PeerManager(Client *client);
void setServerPort(int port);
QByteArray userName() const;
QString userName() const;
void startBroadcasting();
bool isLocalHostAddress(const QHostAddress &address);
@ -87,7 +87,7 @@ private:
QList<QHostAddress> ipAddresses;
QUdpSocket broadcastSocket;
QTimer broadcastTimer;
QByteArray username;
QString username;
int serverPort;
};