1 Star 0 Fork 11

rtpay / 逐梦通讯客户端代码

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
即时通讯软件.md 9.34 KB
一键复制 编辑 原始数据 按行查看 历史

客户端业务逻辑:

登录窗口

(1)socket掉线,重新连接、注册/登录成功失败等(最好把掉线/重连和注册/登录这两种情况分开来发送信号)---->发送信号signalStatus---->窗口接受信号---->SltTcpStatus槽函数处理各种情况 (2)登录成功---->获取到用户信息---->socket先发送信号sigUserInfo,再发送信号signalStatus---->通知界面登录成功 (3)界面收到sigUserInfo信号,在SltUserInfo中保存用户信息到类变量 (4)界面收到signalStatus信号,登录成功以后,取消socket的信号到登录窗口的槽函数,保存登录信息到文件,先初始化主界面,再设置主界面的socket, 发送信号获取好友信息,关闭登录窗口

主界面

重新登录成功 socket 先发送 sigUserInfo,主界面更新个人信息(setUserInfo)再发送signalStatus

删除好友 客户端:BuddyListWidget ---> 调用ContactsWidget发送信号sigDelFriend ---> MiddleWidget槽函数SltDelFriend发送信号sigSend(msg_type_operatefriend,json) --->socket通知服务端删除好友 (客户端选择删除好友以后,只是向服务器发送请求,等服务器将该好友从数据库中删除以后,再通知界面更新真正删除好友) 服务端:收到消息,删除好友成功,返回信息socket发送信号sigDelFriend给客户端通知界面 ---> MiddleWidget::SltDelFriendUpdateWidget--->

接受消息 socket--->ClientSocket::sigChatMsg---> 对方请求加好友: socket--->sigRequestAddUser--->MainWindow::SltRequestAddUser 好友添加结果: socket--->sigAddUserResult--->MainWindow::SltAddUserResult 更新好友列表: socket--->sigFriendList--->MiddleWidget::SltGotFriendList

文件传输

异步文件传输就是一个多生产者(多聊天窗口可以传输多个文件)单一消费者模型(只有一个filesocket),文件的发送和接收通过一个socket来完成,而socket要么只能在发送文件,要么只能在接收文件,原因在于发送和接收的时候都需要用到socket发送缓冲区和接受缓冲区,而且发送和接收都是耗时的操作,线程会阻塞在SltUploadFile或者SltDownloadFile函数,因此引入一个CFileTask类来管理需要传输的文件,该类单独一个线程负责管理等待传输的文件,分别用一个发送和接受队列管理 发送文件 点击发送文件按钮--->选择文件--->如果选择了要发送文件--->new TransFileWgt (设置好文件信息)--->插入右侧文件传输widget--->展开右侧widget--->开启一个临时线程,获取文件Md5值(提示用户文件校验中)--->文件校验完毕--->更新TransFileWgt对应文件md5信息--->把文件发送任务投递给CFileTask任务线程--->检查当前是否有文件正在发送--->没有开始发送文件--->文件发送完毕--->唤醒任务线程,查看QList<TransFileWgt*>队列中是否有文件等待发送,如果没有结束--->任务线程继续等待条件变量m_conditon.wait(&m_mutex);

聊天窗口设计思路

每一个聊天窗口(Chatwin)都有保存一个好友个人信息指针 QQCellChild* ,这个指针由对应的好友分组管理,即BuddyListGroup中的QMap<int,QQCellChild*> m_mapChilds, 同时QQCellChild这个类中也保存一个Chatwin指针,这么做的原因是当QQCellChild中的好友个人信息发生更改时,如果该好友窗口打开,通过判断Chatwin能直接更新对应窗口的好友个人资料, 从而达到更新界面的目的,这种强耦合的设计不知道是否理想? 改进方法两种: 1.QQCellChild由middleWidget申请资源和释放资源,这带来两个好处: (1)打开聊天窗口时只需要发送目标好友的id给middleWidget,然后打开一个窗口,打开窗口的同时初始化窗口的QQCellChild指针变量 (2)历史聊天好友的QQCellChild从MiddleWidget处获取,这样保证聊天窗口,历史聊天好友,好友,共用一个QQCellChild*,各widget 获取qqcellchild的方法通过好友id获取 (3)好友状态更新,先更新MiddleWidget的QQCellChild数据,然后通过一个Update接口更新相关widget的显示 2.获取好友列表以后,将好友信息更新到一个数据库,上述三个widget的好友信息通过id查询数据库更新信息

更新日志

2018/11/12日更新如下 (1)聊天窗口显示聊天信息控件由QTextEdit改为QWebView,聊天内容由html显示,界面优化用css完成,往QWebView插入一条消息现在是把所有发送内容执行的js语句都写在 ChatWin.cpp代码中,之后考虑整合到html文件中,由qt直接调用js接口完成消息插入 (2)发送消息增加表情窗口,现在可以发送表情,之后考虑重新实现发送消息框MyTextEdit的复制黏贴功能,因为现在这个widget存在一个问题,从别的地方不用快捷键复制的消息 无法完成黏贴 (3)增加截屏功能,下一步截屏如果是用户直接选取的图片,考虑先放入一个temp文件夹,然后直接插入图片到MyTextEdit中

2018/11/14日更新如下 (1)增加数据库接口,保存好友聊天消息到相应的个人目录下,每次打开加载10条历史纪录;

2018/11/18日更新如下 (1)主界面bug一个:快速在右侧拖动窗口放大时出现界面刷新不及时导致的扩大后的界面完全透明, 原因:TopWidget没有设置this->setAutoFillBackground(true)属性导致 (2)管理好友信息数据结构QQCellChild的资源申请释放类由BuddyListGroup类变更到MainWindow类中,调整部分架构, 调整原因:一个QQCellChild需要同时给主界面使用(消息到来通知,头像闪烁),同时聊天窗口也需要,好友列表窗口需要,历史会话窗口也需要, 所以把这个类的管理调整到一个最上层的类,方便下层的类使用 之后打算在QQCellChild中增加一个属性,当QQCellChild的m_UnReadMsg由大于0变为0时,发送信号,这样上述几个widget只要通过这个信号来改变界面显示的目的 (3)完善聊天窗口,增加右侧历史消息widget,现存在一个问题,历史消息中的表情不会动,后面把表情插入方式改一下完善 (4)增加发送窗口抖动功能,现在窗口抖动的消息没有插入数据库,抖动以后直接丢弃,后面考虑还是插入数据库

2018/12/5更新如下 (1)代码中所有显示用户的文字都用英文,然后用qt语言家翻译成中文显示,避免各种因编码带来的问题 (2)登陆界面使用全新的界面,特色有:窗口移入移出效果,背景动态效果 (3)托盘功能有待完善

2018/12/6日更新如下 (1)新增断线重连机制,断线重连实现思路: 客户端第一次启动,调用ClientSocket::ConnectToHost,重连间隔2倍增大,从500ms最大增大到30s时间间隔,连接成功以后,信号触发调用ClientSocket::SltConnected槽函数 重连定时器取消,一旦客户端连接成功以后再次与服务器终端连接,信号触发调用槽函数ClientSocket::SltDisconnected,槽函数中重新启用定时器开始主动连接服务器

2018/12/12更新如下 (1)修复bug,接受不到历史消息,先前登录成功以后再new出mainwin然后设置socket,由于服务端历史消息登录以后马上发送给客户端,这导致登录以后服务端发送过来的历史消息,没有槽函数接收,直接被系统丢弃,修改以后mainwin在loginwin中同时初始化

2018/12/25更新如下 (1)增加文件传输任务类,一个线程单独运行,接受每个窗口文件任务的投递,每个文件发送前生成唯一个md5值,暂时不考虑MD5碰撞的可能性,文件传输socket采用阻塞connect,recv,send接口编写 (2)现已完成文件发送的编写

2018/12/31更新如下 (1)完成文件接收的编写,修复当文件大小为0,更新进度条时,作为分母为0,导致程序退出的bug (2)mainwin增加离线消息缓存队列,当离线以后再次登录,缓存服务器的离线消息会首先推送到客户端,因此先缓存起来,等好友列表加载完了再显示 (3)注意程序退出的时候,如果有文件还在传输,需要提醒用户,如果终止传输,需要安全退出文件接收子线程,同时还应该提醒对方已经取消接收文件(这个还没写)

2018/1/3更新如下 (1)新增客户端日志模块,之后打印日志统一使用CIULog,方便运行时决定是否打印日志,打印日志到控制台,或者输出到文件 (2)界面阴影改用paintevent绘制,不用阴影动画效果

界面效果部分如下,模仿的是QQ的界面风格,仅做学习用,如有侵权,请联系 登录窗口 设置窗口 好友主界面 会话主界面 聊天窗口 聊天窗口

马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/rtpay/Dreamgo.git
git@gitee.com:rtpay/Dreamgo.git
rtpay
Dreamgo
逐梦通讯客户端代码
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891