Files
RRJServer/ServerLMS/Systems/sendsystem.cpp
2025-09-25 11:47:42 +03:00

342 lines
9.0 KiB
C++

#include "sendsystem.h"
SendSystem::SendSystem(QObject *parent) : QObject(parent)
{
isSendStopped = false;
}
void SendSystem::initialize(DataParser *dataParser,QMutex *globalMutex)
{
this->dataParser = dataParser;
connect(this,&SendSystem::sigSendXMLmessage,dataParser->ClientAnswer(),&ClientAnswerParser::message,Qt::AutoConnection);
connect(this,&SendSystem::sigSendNotify,dataParser->ClientAnswer(),&ClientAnswerParser::notify,Qt::DirectConnection); //потому что возвращает значение
connect(this,&SendSystem::sigSendVersion,dataParser->ClientAnswer(),&ClientAnswerParser::currentVersion,Qt::AutoConnection);
qDebug() << "SendSystem thread: " << QThread::currentThreadId();
mutex = globalMutex;
}
void SendSystem::setClient(Client *client,QTcpSocket *socket)
{
this->socket = socket;
this->type = client->getClientType();
this->client = client;
isSendStopped = false;
}
void SendSystem::sendNotify(QString notify)
{
qDebug() << "SendNotify thread: " << QThread::currentThreadId();
auto answer = emit sigSendNotify(notify);
sendXmlAnswer(answer);
}
void SendSystem::sendFileBlock(QString path)
{
QFile file(path);
QFileInfo fileInfo(file);
if(isSendStopped)
{ //Поведение на случай отключения клиента
file.close();
Logger::instance().log("UNLOCK STOP MUTEX : " + client->getLogin(),LogLevel::ERROR);
return;
}
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
fileSize = file.size();
if (fileSize == 0)
{
Logger::instance().log("Client: " + client->getLogin() + " WARNING! Zero size " + fileInfo.fileName(),LogLevel::ERROR);
Logger::instance().log(path,LogLevel::ERROR);
return;
}
stream << PacketType::TYPE_FILE; //Отправляем тип блока
stream << path << fileSize;
if(file.open(QFile::ReadOnly))
{
while(!file.atEnd())
{
QByteArray data = file.read(sendFileBlockSize);
stream << data;
//socket->waitForBytesWritten(10);
if(socket->state() == QAbstractSocket::UnconnectedState) break;
countSend++;
}
//emit sigSendToLogger(Tools::getTime() + " send file " + fileInfo.fileName());
}
file.close();
countSend = 0;
}
void SendSystem::sendFileBlockByteArray(QByteArray array, PacketType packetType)
{
if(client->getClientType() == TypeClientAutorization::TYPE_QT_CLIENT ||
client->getClientType() == TypeClientAutorization::TYPE_GUI)
{
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
quint64 size = array.size();
qint64 bytesSended = 0;
if (size == 0)
{
Logger::instance().log(" WARNING! Zero size ",LogLevel::ERROR);
return;
}
stream << packetType; //Отправляем тип блока
stream << size;
while (size > 0)
{
QByteArray chunk = array.mid(bytesSended,sendFileBlockSize);
stream << chunk;
bytesSended += chunk.length();
size -= bytesSended;
}
}
else
{
sendPacketType(packetType);
quint64 size = array.size();
qint64 bytesSended = 0;
if (size == 0)
{
Logger::instance().log(" WARNING! Zero size ",LogLevel::ERROR);
return;
}
QByteArray message;
message.append(reinterpret_cast<char*>(&size), sizeof(int));
socket->write(message);
while (size > 0)
{
QByteArray chunk = array.mid(bytesSended,sendFileBlockSize);
quint64 bytesSended = socket->write(chunk);
size -= bytesSended;
}
}
}
void SendSystem::sendVersion()
{
QByteArray data = dataParser->ClientAnswer()->currentVersion();
sendXmlAnswer(data);
}
void SendSystem::sendFileBlockWithRename(QString path, QString newName)
{
qDebug() << "sendFileBlockWithRename thread: " << QThread::currentThreadId();
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
QFile file(Tools::createRootPath(path));
QFileInfo fileInfo(file);
fileSize = fileInfo.size();
if(fileSize == 0){
Logger::instance().log("Client: " + client->getLogin() + " WARNING! Zero size " + fileInfo.fileName(),LogLevel::ERROR);
return;
}
QString pathForSend = Tools::createFolderPath(path) + "/" + staticDataFolderName + newName;
stream << PacketType::TYPE_FILE; //Отправляем тип блока
stream << pathForSend << fileSize;
if(isSendStopped) { //Поведение на случай отключения клиента
file.close();
return;
}
socket->waitForBytesWritten();
if(file.open(QFile::ReadOnly)){
while(!file.atEnd()){
QByteArray data = file.read(sendFileBlockSize);
stream << data;
socket->waitForBytesWritten();
countSend++;
}
Logger::instance().log("Send file " + fileInfo.fileName());
}
file.close();
countSend = 0;
socket->waitForBytesWritten();
socket->waitForReadyRead(100);
sendNotify(commandHashCompleteClient);
}
void SendSystem::sendFolderBlock(QString path)
{
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
stream << PacketType::TYPE_FOLDER;
stream << path;
}
void SendSystem::sendDeleteBlock(QString path)
{
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
stream << PacketType::TYPE_DELETE;
stream << path;
qDebug() << "DELETE: " + path;
socket->waitForReadyRead(10);
}
void SendSystem::sendPacketType(PacketType packetType)
{
Logger::instance().log("C: " + client->getLogin() + " send pack " + enumToString(packetType), LogLevel::DEBUG);
if (client->getClientType() == TypeClientAutorization::TYPE_QT_CLIENT ||
client->getClientType() == TypeClientAutorization::TYPE_GUI)
{
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
stream << packetType;
socket->waitForReadyRead(100);
}
else
{
QByteArray message;
int type = (int)packetType;
message.append(reinterpret_cast<char*>(&type), sizeof(int));
socket->write(message);
}
}
void SendSystem::sendHello()
{
socket->write(SERVER_HELLO);
}
void SendSystem::sendXmlAnswer(QByteArray array, PacketType packetType)
{
qDebug() << "SendSystemThread: " << QThread::currentThreadId();
Logger::instance().log("C: " + client->getLogin() + " send pack " + enumToString(packetType) +
" " + QString::fromUtf8(array),LogLevel::DEBUG);
if (client->getClientType() == TypeClientAutorization::TYPE_QT_CLIENT ||
client->getClientType() == TypeClientAutorization::TYPE_GUI)
{
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
stream << packetType;
stream << array;
socket->waitForBytesWritten();
}
else
{
sendPacketType(packetType);
QByteArray message;
int size = array.length();
message.append(reinterpret_cast<char*>(&size), sizeof(int));
socket->write(message);
socket->write(array);
}
}
void SendSystem::sendNeedUpdate(bool flag,quint64 size,quint64 fileCount,quint64 deleteCount)
{
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
stream << PacketType::TYPE_NEEDUPDATE;
stream << flag;
stream << size;
stream << fileCount;
stream << deleteCount;
}
void SendSystem::updateFiles(QList<FileData> fileSendList, QList<FileData> deleteList){
QMutexLocker locker(mutex);
QListIterator<FileData> clientIterator(deleteList);
while(clientIterator.hasNext())
{
FileData data = clientIterator.next();
sendDeleteBlock(data.path);
if(getIsSendStopped())
{
return;
}
}
QListIterator<FileData> serverIterator(fileSendList);
while(serverIterator.hasNext())
{
FileData data = serverIterator.next();
if (data.hash == "FOLDER")
{
sendFolderBlock(data.path);
socket->waitForBytesWritten();
}
else
{
sendFileBlock(data.path);
socket->waitForBytesWritten();
}
if(isSendStopped)
{
return;
}
}
sendPacketType(PacketType::TYPE_FINISH);
}
void SendSystem::socketClose()
{
socket->close();
}
bool SendSystem::socketFlush() //TODO: проверить использование
{
return socket->flush();
}
void SendSystem::sendStop()
{
isSendStopped = true;
}
bool SendSystem::getIsSendStopped() const
{
return isSendStopped;
}
SendSystem::~SendSystem()
{
}