文章目录

  • 1 登录功能和公聊功能的实现
    • 1.1 分析
    • 1.2 代码实现

1 登录功能和公聊功能的实现

1.1 分析

问题:

  • 如何设计客户端和服务端之间的消息交互流程?

消息类型主要分为如下两种:

  • 控制消息:

    • 与聊天内容无关,设计用户状态。
    • 连接、断开、踢人、禁言等。
  • 文本消息:

    • 与聊天内容相关,用户可见消息。
    • 公聊消息,私聊消息。

用户登录、注册流程:

服务端认证流程:

简化设计:

文本消息传输模型(公聊模式):

文本消息传输模型(私聊模式):

1.2 代码实现

为了能够正确解析多条一次性接收的数据,需要对onDataReady()函数进行修改:

客户端中修改:
MainWin.h:

MainWinSlot.cpp修改后如下:

#include "MainWin.h"
#include <QMessageBox>
#include <QDebug>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"
#include <QDebug>ServerHandler::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<m_nodeList.length(); i++){Node* n = m_nodeList.at(i);if( n->socket == &obj ){n->socket = NULL;break;}}
}void ServerHandler::MSGA_Handler(QTcpSocket&, TextMessage& message)
{const QByteArray& ba = message.serialize();for(int i=0; i<m_nodeList.length(); i++){Node* n = m_nodeList.at(i);if( n->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<m_nodeList.length(); i++){if( id == m_nodeList.at(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());
}

参考资料:

  1. QT实验分析教程

登录功能和公聊功能的实现相关推荐

  1. 从0实现基于Linux socket聊天室-实现聊天室的公聊、私聊功能-4

    前面文章链接如下: <从0实现基于Linux socket聊天室-多线程服务器模型-1> <从0实现基于Linux socket聊天室-多线程服务器一个很隐晦的错误-2> &l ...

  2. 实现了私聊和群聊功能的聊天工具

    在前面的博客(简单的C/S聊天室)中,我们已经提到了,采用的是多线程的方法.服务器端主线程负责不断的侦听端口,子线程负责接收和发送消息.客户端主线程需要接收键盘消息,将其发送到服务器端,子线程需要接收 ...

  3. 互联网早报 | 3月16日 星期二 | 微信AI直播助理开放内测;汽车之家港交所挂牌上市;美团App内测“群聊”功能...

    今日看点 ✦ 汽车之家港交所成功挂牌,成年内首家回港二次上市中概股 ✦ 恒大汽车与腾讯旗下梧桐车联成立合资公司 ,共同开发车载智能操作系统 ✦ 微信AI直播助理开放内测,助力电商带货 ✦ 美团App内 ...

  4. ASP.NET SignalR 与LayIM配合,轻松实现网站客服聊天室(四) 添加表情、群聊功能...

    休息了两天,还是决定把这个尾巴给收了.本篇是最后一篇,也算是草草收尾吧.今天要加上表情功能和群聊.基本上就差不多了,其他功能,读者可以自行扩展或者优化.至于我写的代码方面,自己也没去重构.好的,我们开 ...

  5. C++搭建集群聊天室(十四):群聊功能

    文章目录 群聊功能思路 放码过来 groupuser.hpp group.hpp groupmodel.hpp groupmodel.cpp 群聊功能思路 1.创建群聊,提交群信息,返回群号 2.拉取 ...

  6. 小程序集成网易云通信群聊功能Demo发布

    前端代码是可以直接使用的,获取后端代码加微信13439975582 功能实现说明: 1.小程序生命周期完美整合 2.消息小红点,群聊小红点代码实现都实现了 3.历史信息回放 4.小程序帐号集成 代码都 ...

  7. 华为快应用IDE:微信小程序转换成快应用功能火热公测啦!

    华为快应用IDE:微信小程序转换成快应用功能火热公测啦! 华为快应用和微信小程序一样都为用户提供了无需安装,即点即用点的方便性.快应用可以在操作系统层面实现用户需求与应用服务间的无缝连接,提升用户的使 ...

  8. Netty聊天系统(4)群聊功能实现

    7 群聊功能的实现 7.1 群聊的创建 创建一个创建群聊请求的实体类,依然是继承Packet,因为要通过我们的协议进行编解码 服务器端创建一个处理创建群聊请求的Handler,并实现其中的逻辑 创建一 ...

  9. 用C++/MFC实现P2P和群聊功能的聊天小软件

    final edit 2015-01-03 · 实现平台: Window 8.1,Visual Studio 2013 Window 7, Visual Studio 2010 · 所用框架: 是基于 ...

最新文章

  1. 逻辑回归,朴素贝叶斯,KMeans,决策树的不足和优势
  2. 内容推荐 | 生信技术与前沿内容知识库
  3. Mock.js mysql_平台支持mock功能—未完成版
  4. 关于Linux服务器配置java环境遇到的问题
  5. Linux下GCC与G++的区别和联系
  6. vue使用query传参页面刷新数据丢失问题
  7. js三元判断html,JS 三元条件运算符
  8. typra修改快捷键
  9. CF 2A-Winner
  10. firefox 火狐浏览器安装java插件
  11. 就算不偷盗,也让你看看计算机里常用的有那些软件--常用软件序列号
  12. vue 动态引入组件
  13. RHEL Linux 8.3 通过 BIND 实现 DNS 基本功能
  14. 电信物联网平台插件开发相关总结
  15. VB.net写的音乐播放器,带百度翻译歌词
  16. 多模态情感分析的研究现状
  17. 在WindowsMobil系统中实现透明树组件
  18. Delphi图像处理 -- 彩色浮雕
  19. 50例源码Python scipy.stats.norm 模块,pdf()
  20. java模板velocity,java模板引擎:velocity

热门文章

  1. 谷歌身份验证器验证码不对怎么回事_地面最强下载器:IDM+【安卓】详细介绍...
  2. 【Leetcode | easy】回文数
  3. 【控制】《鲁棒控制-线性矩阵不等式处理方法》-俞立老师-第9章-时滞系统的分析和综合
  4. Nordic系列芯片讲解九 (BLE事件回调机制解析)
  5. cadence原理图软件(orcad)层级原理图与位号
  6. 我思故我在之编程规范及编程思想篇
  7. 如何为SFP光模块搭配对应的光纤跳线?
  8. 大数据方面核心技术有哪些?新人必读
  9. 4MLinux 24.0 发布
  10. Linux jdk配置/下载/安装简单说明