登录功能和公聊功能的实现
发布日期:2021-07-01 04:27:34
浏览次数:2
分类:技术文章
本文共 4316 字,大约阅读时间需要 14 分钟。
文章目录
1 登录功能和公聊功能的实现
1.1 分析
问题:
- 如何设计客户端和服务端之间的消息交互流程?
消息类型主要分为如下两种:
-
控制消息:
- 与聊天内容无关,设计用户状态。
- 连接、断开、踢人、禁言等。
-
文本消息:
- 与聊天内容相关,用户可见消息。
- 公聊消息,私聊消息。
用户登录、注册流程:
服务端认证流程:
简化设计: 文本消息传输模型(公聊模式): 文本消息传输模型(私聊模式):1.2 代码实现
为了能够正确解析多条一次性接收的数据,需要对onDataReady()函数进行修改:
客户端中修改:
MainWin.h: MainWinSlot.cpp修改后如下:#include "MainWin.h"#include#include void MainWin::initMember(){ m_client.setHandler(this); m_handlerMap.insert("CONN", CONN_Handler); m_handlerMap.insert("DSCN", DSCN_Handler); m_handlerMap.insert("LIOK", LIOK_Handler); m_handlerMap.insert("LIER", LIER_Handler); m_handlerMap.insert("MSGA", MSGA_Handler);}void MainWin::sendBtnClicked(){ QString text = inputGrpBx.title() + ":\n" + " " + inputEdit.text() + "\n"; TextMessage tm("MSGA", text); if( m_client.send(tm) ) { inputEdit.clear(); }}void MainWin::logInOutBtnClicked(){ if( !m_client.isValid() ) { if( loginDlg.exec() == QDialog::Accepted ) { QString usr = loginDlg.getUser().trimmed(); QString pwd = loginDlg.getPwd(); if( m_client.connectTo("127.0.0.1", 8890) ) { TextMessage tm("LGIN", usr + '\r' + pwd); m_client.send(tm); } else { QMessageBox::critical(this, "失败", "连接不到远程服务端!"); } } } else { m_client.close(); }}void MainWin::handle(QTcpSocket& obj, TextMessage& message){ if( m_handlerMap.contains(message.type()) ) { MSGHandler handler = m_handlerMap.value(message.type()); (this->*handler)(obj, message); }}void MainWin::CONN_Handler(QTcpSocket&, TextMessage&){ }void MainWin::MSGA_Handler(QTcpSocket&, TextMessage& message){ msgEditor.appendPlainText(message.data());}void MainWin::DSCN_Handler(QTcpSocket&, TextMessage&){ setCtrlEnabled(false); inputGrpBx.setTitle("用户名");}void MainWin::LIOK_Handler(QTcpSocket&, TextMessage& message){ setCtrlEnabled(true); inputGrpBx.setTitle(message.data());}void MainWin::LIER_Handler(QTcpSocket&, TextMessage&){ QMessageBox::critical(this, "错误", "身份验证失败!"); m_client.close();}MainWin::~MainWin(){ m_client.close();}
服务端代码进行如下修改:
ServerHandler.h修改如下: ServerHandler.cpp修改后的内容如下:#include "ServerHandler.h"#includeServerHandler::ServerHandler(){ m_handlerMap.insert("CONN", CONN_Handler); m_handlerMap.insert("DSCN", DSCN_Handler); m_handlerMap.insert("LGIN", LGIN_Handler); m_handlerMap.insert("MSGA", MSGA_Handler);}void ServerHandler::handle(QTcpSocket& obj, TextMessage& message){ if( m_handlerMap.contains(message.type()) ) { MSGHandler handler = m_handlerMap.value(message.type()); (this->*handler)(obj, message); }}void ServerHandler::CONN_Handler(QTcpSocket&, TextMessage&){ }void ServerHandler::DSCN_Handler(QTcpSocket& obj, TextMessage&){ for(int i=0; i socket == &obj ) { n->socket = NULL; break; } }}void ServerHandler::MSGA_Handler(QTcpSocket&, TextMessage& message){ const QByteArray& ba = message.serialize(); for(int i=0; i socket != NULL ) { n->socket->write(ba); } }}void ServerHandler::LGIN_Handler(QTcpSocket& obj, TextMessage& message){ QString data = message.data(); int index = data.indexOf('\r'); QString id = data.mid(0, index); QString pwd = data.mid(index + 1); QString result = ""; index = -1; for(int i=0; i id ) { index = i; break; } } if( index == -1 ) { Node* newNode = new Node(); if( newNode != NULL ) { newNode->id = id; newNode->pwd = pwd; newNode->socket = &obj; m_nodeList.append(newNode); result = "LIOK"; } else { result = "LIER"; } } else { Node* n = m_nodeList.at(index); if( pwd == n->pwd ) { n->socket = &obj; result = "LIOK"; } else { result = "LIER"; } } obj.write(TextMessage(result, id).serialize());}
参考资料:
转载地址:https://muzimin.blog.csdn.net/article/details/105795058 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
做的很好,不错不错
[***.243.131.199]2024年04月17日 22时19分32秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
ACM 2017 北京区域赛 J-Pangu and Stones(区间dp)
2019-04-30
java常用类 String面试题
2019-04-30
四线触摸屏原理
2019-04-30
C/C++如何返回一个数组/指针
2019-04-30
腾讯AI语音识别API踩坑记录
2019-04-30
java.net.BindException: 无法指定被请求的地址
2019-05-01
svn服务器安装
2019-05-01
spark 笔记1
2019-05-01
shell dirname basename
2019-05-01
未来已至,5G加持下的云游戏将走向何方?
2019-05-01
计算机网络 —— 网络层 1.
2019-05-01
Android 之 ContentProvider 与 ContentResolver
2019-05-01
【接口自动化】
2019-05-01
推荐一位川大零基础转行 Python 的人生勇士
2019-05-01
Python解惑之:True与False
2019-05-01
你要的微信小程序终于来了
2019-05-01
有了这些 Chrome 插件,效率提升10倍(建议收藏)
2019-05-01
只有1%的程序员搞懂过浮点数陷阱
2019-05-01
一名 Google 工程师的大数据处理经验
2019-05-01
命名难,难于上青天
2019-05-01