您的位置:首页 > 编程语言 > Qt开发

一个基于qt的桌面聊天系统的学习笔记(1)-邮件模块(2)收发信处理流程

2016-11-21 12:04 585 查看
写信:

一.在邮件编辑界面(在IMMailWriteWidget文件中定义)中编辑好信件,点击发送按钮,发出clicked信号

二.IMMailWriteWidget捕获到这个信号,调用槽函数onClickBtnSend

connect(m_btnSend, SIGNAL(clicked()),
this, SLOT(onClickBtnSend()));


三.在槽函数onClickBtnSend中调用getMailInformation函数取得消息输入框的信息,再让邮件控制器类IMMailCtrl调用requestSendMail函数

void IMMailWriteWidget::onClickBtnSend()
{
if (m_leReceiverAddress->text().isEmpty())
{
QMessageBox::about(NULL, tr("提示"), tr("收件人不能为空!"));
return;
}
if (m_leReceiverAddress->text().compare(m_myID) == 0)
{
QMessageBox::about(NULL, tr("提示"), tr("不能给自己发送邮件!"));
return;
}
if (m_leTheme->text().isEmpty())
{
QMessageBox::about(NULL, tr("提示"), tr("信件主题不能为空"));

return;
}
if (m_textInput->toPlainText().isEmpty())
{
QMessageBox::about(NULL, tr("提示"), tr("信件内容不能为空!"));
return;
}

// 获取信息输入框的信息
getMailInformation();

m_mailCtrl->requestSendMail(m_mail);
}


四.requestSendMail函数通过socket与服务器通信(并把消息类型标记为SEND_MAIL)

void IMMailCtrl::requestSendMail(const MailInformation &mail)
{
qDebug() << "send mail: " << mail.m_theme;

if (NULL == m_tcpSocket)
return;
m_blockSize = 0;
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_8);
out << quint16(0) << int(SEND_MAIL) << mail;
out.device()->seek(0);
out << quint16(block.size() - sizeof(quint16));
m_tcpSocket->write(block);

}


服务器:

一.在客户端通信类(在IMClientSocket类中定义)的receiveMessage函数中识别到SEND_MAIL, 发出sendSignal信号

connect(this, &IMClientSocketCtrl::readyRead,
this, &IMClientSocketCtrl::receiveMessage);
connect(this, &IMClientSocketCtrl::disconnected,
this, &IMClientSocketCtrl::deleteScoket);


void IMClientSocketCtrl::receiveMessage()
{
switch (m_save.m_requestKind)
{
case SEND_MAIL:
{
in >> m_save.m_mail;
break;
}
}
emit sendSignal(m_save);
}


二.服务器类(在IMTcpServer类中定义)捕获到这个信号,调用sendMessage槽函数进行处理

connect(clientScoket, &IMClientSocketCtrl::sendSignal,
this, &IMTcpServer::sendMessage);
connect(clientScoket, &IMClientSocketCtrl::deleteSignal,
this, &IMTcpServer::clientDisconnected);


三.sendMessage识别到SEND_MAIL,通过操作数据库类(在IMDatabase中定义)往数据库中插入一条邮件记录,如果成功就返回SEND_MAIL_SUCCESS到relyKind,然后通过socket给发信方发送消息,告诉发信方信已成功发出。然后在服务器的邮箱用户表中找到收信人的socket, 把信件发送给收信人

int IMDatabaseCtrl::insertMail(MailInformation & mail)
{
if (!createConnection())
{
return SEND_MAIL_FAIL;
}
//sql 事务
QSqlDatabase::database().transaction();

QSqlQuery query(*m_db);
query.prepare(INSERT_MAIL_IN_MAIL);
query.addBindValue(mail.m_senderAddress);
query.addBindValue(MAIL_ADDRESS_FORMAT);
query.addBindValue(mail.m_receiverAddress);
query.addBindValue(MAIL_ADDRESS_FORMAT);
query.addBindValue(mail.m_theme);
query.addBindValue(mail.m_content);
query.addBindValue(mail.m_dateTime);
query.exec();

errorSQLOrder(query, "insert-mail");
if (!query.isActive())
{
qDebug() << "QUERY_FAIL::" << query.lastError().text();
m_db->close();
return SEND_MAIL_FAIL;
}

if (0 >= query.numRowsAffected())
{
return SEND_MAIL_FAIL;
}
QSqlDatabase::database().commit();

query.exec("select LAST_INSERT_ID() from Mail");
if (query.next())
{
mail.m_mailID = query.value(0).toInt();
}

//    m_db->close();
return SEND_MAIL_SUCCESS;
}


void IMTcpServer::sendMessage(const SaveTmpInformation &save)
{
m_save.m_requestKind = save.m_requestKind;
switch(m_save.m_requestKind)
{
case SEND_MAIL:
{
m_save.m_mail = save.m_mail;
m_save.m_replyKind = m_database.insertMail(m_save.m_mail);

save.m_clientSocket->sendMessage(m_save);

if(SEND_MAIL_SUCCESS == m_save.m_replyKind)
{
QString mailAddress = m_save.m_mail.m_receiverAddress;
mailAddress.append(MAIL_ADDRESS_FORMAT);

QMap<QString, IMClientSocketCtrl *>::iterator iter;
iter = m_userMailMap.find(mailAddress);
if(iter != m_userMailMap.end())
{
m_save.m_replyKind = RECEIVE_MAIL;
iter.value()->sendMessage(m_save);
}
}
break;
}
}
}


收信:

一.邮件通信控制类(在IMMailCtrl中定义)的socket与服务器连接成功并准备好读信息时,会调用readMessage槽函数

connect(m_tcpSocket, SIGNAL(connected()), this, SLOT(requestGetInMails()));
connect(m_tcpSocket, SIGNAL(readyRead()), this, SLOT(readMessage()));


二.readMessage槽函数识别到RECEIVE_MAIL,发出getInMail信号

void IMMailCtrl::readMessage()
{
in >> type;

switch (type)
{
case RECEIVE_MAIL:
{
in >> m_mail;
if (m_mail.m_receiverAddress == m_myID)
emit getInMail(m_mail);
break;
}
}
}


三.邮件主界面(在IMMailWidget中定义)捕获信号, 调用addNewInMailButton

connect(m_mailCtrl, &IMMailCtrl::getInMail,
this, &IMMailWidget::addNewInMailButton);


bool IMMailWidget::addNewInMailBu
9eee
tton(const MailInformation &mail)
{
if(m_inMailMap.contains(mail.m_mailID))
{
return false;
}
IMMailButton *button = new IMMailButton(mail, this, this);

m_inMailMap.insert(mail.m_mailID, button);
m_inWidget.insertItem(0, button);
return true;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐