不懂的一些东西
(const TcpConnectionPtr&)作为形参啥意思:接收一个常量引用,函数内部不允许修改该指针所指向的对象。
优势
1.网络层与业务层分离:通过网络层传来的id,设计一个map存储id以及对印的业务处理器,处理器bind绑定处理函数,直接分离根据id调用业务即可
2.这里传入的是user对象而不是sql语句,很方便
概述
网络层---业务层---数据层
mudou库和libevent二选一
JSON介绍
muduo网络库
回声服务器
客户端实现
muduo中的线程池做计算任务
moduo网络库的多线程模型
网络服务器模型
moduo中的reactor模型
cmake
项目数据库以及表的设计
集群项目聊天工程目录创建
网络模块代码
业务模块代码
网络模块和业务模块解耦度降级
网络模块分发业务事件回调操作功能测试
talent连接客户端发送json数据进行测试
Mysql数据库代码封装
Model数据层代码框架设计
用户注册业务代码
客户端发送json数据,其中msgid是2,代表注册消息。
流程分析:输入ip端口连接上服务器,启动chatserver,调用其中的注册链接回调,并通过loop.loop()进入事件循环这样TcpServer对象接收到消息时就会调用onMessage回调函数,客户端发送msgid,name,password,调用onMessage回调函数,根据msgid获取对应的事件处理器并运行,进而启动相应注册业务函数,取出发过来的name和password放到User对象中,调用Usermodel对象(专门用来操作数据库的)的插入数据库方法,设置一个json格式消息返回给客户端。
用户登录业务代码
测试输入
记录用户的连接信息以及线程安全问题
这里记录连接信息只是在本台服务器,不可跨服务器
客户端异常退出业务代码
即客户端调用quit操作断开连接时被调用
点对点聊天业务代码
测试代码:注册两个,开两个客户端登录,发消息
离线消息业务代码实现
小总结:
这里服务器充当中间角色,A客户端给B客户端发消息,离线消息存储在服务器mysql中,B客户端登录后查询是否有离线消息,如果有就取出来发给他(这个操作是服务器到客户端的send方法)这里存储消息的userid代表要发给的人的id,别人登录也用这个id,正好依次查询数据库信息
服务器异常退出处理代码
ctrl+c退出,数据库不会把online变为offline
添加好友业务
小总结
这里的逻辑是添加好友要输入自己的id和所添加的好友的id,下次登录后查询好友状态的操作逻辑是根据我输入我自己的id,在friend表(userid+friendid存储方式)中查询我的id有哪些friendid,根据friendid在全局User表中查询对应用户信息返回给登录的用户。
群组业务代码
Group类包括了群组id,群名,群描述,和所有群组用户信息
创建群组:传入group,给allgroup插入组名和组描述,第17行什么意思?
加入群组:传入创建者(加入者)的id,要加入的组id,职位,这个职位可以设置变量,这里为了方便,直接给创建者设置为creator,后加的默认role。然后放到GroupUser表。
业务实操
查询用户所在组信息:在groupuser表利用自己的id查自己组的id,然后换到allgroup表查这个组的信息放入groupVec(里面是一个个group)
查询群组的用户信息:上面得到了组信息,根据组id在groupuser表中筛选出加入了这个组的人id,利用人id与所有用户都在的user表匹配查出用户的详细信息。因为上面groupVec里面每个group先只放了群信息,还剩一个放群员信息变量没放东西,下面会把群员信息(groupuser)放入其中,group还是原来的group,所以最后还是return groupVec
业务实操:(groupVec嵌套了group的vector,group嵌套了groupuser的vector)函数最终返回的是群组信息和群组的用户信息,服务器的作用是当客户端登录后,服务器开始查询,先整合群id群名字等一个json,再利用函数返回值整个一个json(这里的getUsers函数借用了User方法因为他们是继承关系)
整合json逻辑:先放群组信息,再for循环整合群员信息这是一个大json,即大json是grpjson,放到一个vector中最后传入response
给群里其他人发消息:输入自己的id在输入想发消息的群组id,根据groupid在groupuser表中查询是同一群成员id且id不等于自己的人id,因为只需要id不需要详细信息,所以无需像上面从user表中查信息,这里返回的是群友的id
实战操作:
客户端开发1
集群服务器引入负载均衡器
集群聊天服务器跨服务器通信
client1登录,想发消息给client2,如果能找到client2的connection,证明他们用的是一台服务器,否则,去查数据库看client2是否是online,如果在线,想办法吧消息转给client2所在的服务器,然后找到connection发给client2。
nginx负载均衡
让客户端去指定连接nginx然后会自动跳转到服务器
redis发布订阅代码
服务器支持redis跨服务器通信
1.
2.
3.
4.不在发消息用户所在的这台服务器就去队列里发布
5.
6.回调函数由redis调用,收消息用户在哪登陆了,这台服务器就会收到订阅消息
总结:哪个用户登录这台服务器,服务器就会用你的id在redis注册一个管道channel
测试