mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-16 20:26:17 +02:00
187 lines
6.4 KiB
C++
187 lines
6.4 KiB
C++
//
|
|
// MessagesClient.cpp
|
|
// libraries/networking/src
|
|
//
|
|
// Created by Brad hefta-Gaub on 11/16/2015.
|
|
// Copyright 2015 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#include "MessagesClient.h"
|
|
|
|
#include <cstdint>
|
|
|
|
#include <QtCore/QBuffer>
|
|
#include <QtCore/QThread>
|
|
|
|
#include <ThreadHelpers.h>
|
|
|
|
#include "NetworkLogging.h"
|
|
#include "NodeList.h"
|
|
#include "PacketReceiver.h"
|
|
|
|
MessagesClient::MessagesClient() {
|
|
setCustomDeleter([](Dependency* dependency){
|
|
static_cast<MessagesClient*>(dependency)->deleteLater();
|
|
});
|
|
auto nodeList = DependencyManager::get<NodeList>();
|
|
auto& packetReceiver = nodeList->getPacketReceiver();
|
|
packetReceiver.registerListener(PacketType::MessagesData, this, "handleMessagesPacket");
|
|
connect(nodeList.data(), &LimitedNodeList::nodeActivated, this, &MessagesClient::handleNodeActivated);
|
|
}
|
|
|
|
void MessagesClient::decodeMessagesPacket(QSharedPointer<ReceivedMessage> receivedMessage, QString& channel,
|
|
bool& isText, QString& message, QByteArray& data, QUuid& senderID) {
|
|
quint16 channelLength;
|
|
receivedMessage->readPrimitive(&channelLength);
|
|
auto channelData = receivedMessage->read(channelLength);
|
|
channel = QString::fromUtf8(channelData);
|
|
|
|
receivedMessage->readPrimitive(&isText);
|
|
|
|
quint32 messageLength;
|
|
receivedMessage->readPrimitive(&messageLength);
|
|
auto messageData = receivedMessage->read(messageLength);
|
|
if (isText) {
|
|
message = QString::fromUtf8(messageData);
|
|
} else {
|
|
data = messageData;
|
|
}
|
|
|
|
QByteArray bytesSenderID = receivedMessage->read(NUM_BYTES_RFC4122_UUID);
|
|
if (bytesSenderID.length() == NUM_BYTES_RFC4122_UUID) {
|
|
senderID = QUuid::fromRfc4122(bytesSenderID);
|
|
} else {
|
|
QUuid emptyUUID;
|
|
senderID = emptyUUID; // packet was missing UUID use default instead
|
|
}
|
|
}
|
|
|
|
std::unique_ptr<NLPacketList> MessagesClient::encodeMessagesPacket(QString channel, QString message, QUuid senderID) {
|
|
auto packetList = NLPacketList::create(PacketType::MessagesData, QByteArray(), true, true);
|
|
|
|
auto channelUtf8 = channel.toUtf8();
|
|
quint16 channelLength = channelUtf8.length();
|
|
packetList->writePrimitive(channelLength);
|
|
packetList->write(channelUtf8);
|
|
|
|
bool isTextMessage = true;
|
|
packetList->writePrimitive(isTextMessage);
|
|
|
|
auto messageUtf8 = message.toUtf8();
|
|
quint32 messageLength = messageUtf8.length();
|
|
packetList->writePrimitive(messageLength);
|
|
packetList->write(messageUtf8);
|
|
|
|
packetList->write(senderID.toRfc4122());
|
|
|
|
return packetList;
|
|
}
|
|
|
|
std::unique_ptr<NLPacketList> MessagesClient::encodeMessagesDataPacket(QString channel, QByteArray data, QUuid senderID) {
|
|
auto packetList = NLPacketList::create(PacketType::MessagesData, QByteArray(), true, true);
|
|
|
|
auto channelUtf8 = channel.toUtf8();
|
|
quint16 channelLength = channelUtf8.length();
|
|
packetList->writePrimitive(channelLength);
|
|
packetList->write(channelUtf8);
|
|
|
|
bool isTextMessage = false;
|
|
packetList->writePrimitive(isTextMessage);
|
|
|
|
quint32 dataLength = data.length();
|
|
packetList->writePrimitive(dataLength);
|
|
packetList->write(data);
|
|
|
|
packetList->write(senderID.toRfc4122());
|
|
|
|
return packetList;
|
|
}
|
|
|
|
|
|
void MessagesClient::handleMessagesPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode) {
|
|
QString channel, message;
|
|
QByteArray data;
|
|
bool isText { false };
|
|
QUuid senderID;
|
|
decodeMessagesPacket(receivedMessage, channel, isText, message, data, senderID);
|
|
if (isText) {
|
|
emit messageReceived(channel, message, senderID, false);
|
|
} else {
|
|
emit dataReceived(channel, data, senderID, false);
|
|
}
|
|
}
|
|
|
|
void MessagesClient::sendMessage(QString channel, QString message, bool localOnly) {
|
|
auto nodeList = DependencyManager::get<NodeList>();
|
|
if (localOnly) {
|
|
QUuid senderID = nodeList->getSessionUUID();
|
|
emit messageReceived(channel, message, senderID, true);
|
|
} else {
|
|
SharedNodePointer messagesMixer = nodeList->soloNodeOfType(NodeType::MessagesMixer);
|
|
|
|
if (messagesMixer) {
|
|
QUuid senderID = nodeList->getSessionUUID();
|
|
auto packetList = encodeMessagesPacket(channel, message, senderID);
|
|
nodeList->sendPacketList(std::move(packetList), *messagesMixer);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MessagesClient::sendData(QString channel, QByteArray data, bool localOnly) {
|
|
auto nodeList = DependencyManager::get<NodeList>();
|
|
if (localOnly) {
|
|
QUuid senderID = nodeList->getSessionUUID();
|
|
emit dataReceived(channel, data, senderID, true);
|
|
} else {
|
|
SharedNodePointer messagesMixer = nodeList->soloNodeOfType(NodeType::MessagesMixer);
|
|
|
|
if (messagesMixer) {
|
|
QUuid senderID = nodeList->getSessionUUID();
|
|
auto packetList = encodeMessagesDataPacket(channel, data, senderID);
|
|
nodeList->sendPacketList(std::move(packetList), *messagesMixer);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MessagesClient::sendLocalMessage(QString channel, QString message) {
|
|
sendMessage(channel, message, true);
|
|
}
|
|
|
|
void MessagesClient::subscribe(QString channel) {
|
|
_subscribedChannels << channel;
|
|
auto nodeList = DependencyManager::get<NodeList>();
|
|
SharedNodePointer messagesMixer = nodeList->soloNodeOfType(NodeType::MessagesMixer);
|
|
|
|
if (messagesMixer) {
|
|
auto packetList = NLPacketList::create(PacketType::MessagesSubscribe, QByteArray(), true, true);
|
|
packetList->write(channel.toUtf8());
|
|
nodeList->sendPacketList(std::move(packetList), *messagesMixer);
|
|
}
|
|
}
|
|
|
|
void MessagesClient::unsubscribe(QString channel) {
|
|
_subscribedChannels.remove(channel);
|
|
auto nodeList = DependencyManager::get<NodeList>();
|
|
SharedNodePointer messagesMixer = nodeList->soloNodeOfType(NodeType::MessagesMixer);
|
|
|
|
if (messagesMixer) {
|
|
auto packetList = NLPacketList::create(PacketType::MessagesUnsubscribe, QByteArray(), true, true);
|
|
packetList->write(channel.toUtf8());
|
|
nodeList->sendPacketList(std::move(packetList), *messagesMixer);
|
|
}
|
|
}
|
|
|
|
void MessagesClient::handleNodeActivated(SharedNodePointer node) {
|
|
if (node->getType() == NodeType::MessagesMixer) {
|
|
for (const auto& channel : _subscribedChannels) {
|
|
subscribe(channel);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MessagesClient::startThread() {
|
|
moveToNewNamedThread(this, "Messages Client Thread");
|
|
}
|