源码下载网站有哪些,小程序游戏开发平台,成品门户网站源码免费,企业服务有哪些网络聊天服务器项目#xff0c;该项目分为4个模块#xff1a; 首先是网络模块#xff1a;我使用了muduo高性能网络库#xff0c;解耦合网络与业务之间这两部分代码#xff0c;可以更加专注与业务的功能开发其次是服务层模块#xff1a;我使用了基于C11的技术比如绑定器和… 网络聊天服务器项目该项目分为4个模块 首先是网络模块我使用了muduo高性能网络库解耦合网络与业务之间这两部分代码可以更加专注与业务的功能开发其次是服务层模块我使用了基于C11的技术比如绑定器和map绑定器实现了用户发送的消息id类型回调业务功能函数的机制当网络i/o发送消息请求后通过解析json消息获取消息id 回调业务功能函数然后是数据存储模块我使用了MySQL数据库存储关键的信息用户账户、离线消息列表、群组信息、好友列表等由客户端的功能请求进行增删改查 以上是单机服务器的模块设计但是单机服务器的并发数量是有限的所以我采用了集群服务器经行并发能力扩展 4.最后在多台服务器部署基于Tcp 协议搭建的C/S 通信所以我使用了Nginx Tcp负载均衡保持长连接状态并且引入Redis 的发布订阅功能实现跨服务器间通信 1. 客户端
1.1. 两个模块
1.1.1. 负责用户登录、注册、退出功能
作为客户端连接服务器成功后的首界面展示提供以上三种服务
客户端设计模式主线线程专注于信息的发送、子线程负责接受信息
将具体功能的所需参数进行jsonkey-value键值对存储文本形式序列化发送给服务器
个别服务需要服务器返回方法返回值状态信息登录成功、信息注册成功多线程协调实现
由主线程发送后阻塞获取信号量子线程此时接受服务器返回的json对象由json中的服务方法枚举id分类细化具体的功能实现业务逻辑将服务方法调用的状态写入最后将信号量释放主函数则可以通过子线程写入的状态进行下一步工作 登陆成功后进入功能菜单
1.1.2. 负责聊天服务器业务功能添加好友信息、创建群组、加入群组、单人聊天、群组聊天
将功能函数处理为map表形式存储函数方法名称方法绑定器循环处理客户端的输入的方法请求在循环中未使用switch_case而是mapbind回调适应于程序开发中的开闭原则对修改关闭对开发扩展开放
该部分函数主要处理用户的功能以及输入的参数封装为json 对象服务器协商的通信规则方法枚举id的标识与方法请求一致的参数列表发送给服务器
auto it commandHandlerMap.find(command);
if (it commandHandlerMap.end())
//error// 调用相应命令的事件处理回调mainMenu对修改封闭添加新功能不需要修改该函数
it-second(clientfd, commandbuf.substr(idx 1, commandbuf.size() - idx));
// 调用命令处理方法 2. 服务器
2.1. 服务器需要处理信息转发、功能性数据的存储、查询、更新服务
解决基于数据库的功能服务问题MySQL
解决高并发场景下数据收发问题muduo 静态网络库
解决跨服务器通信问题 Redis发布订阅问题
解决负载均衡问题Nginx_基于Tcp长连接的负载均衡问题
2.2. 主要基于以上内容将服务器划分出
server、service、db、model、redis、public 六个模块
2.2.1. server——muduo网络
基于epoll多线程的机制实现高并发需求
在该模块中设置四个工作线程其中一个处理连接回调在连接异常的场景下关闭连接余下三个线程为工作线程完成将接收的字符基于json-parse反序列化发送给service基于服务方法id回调具体的处理函数
2.2.2. db
数据库的接口API 创建初始化、数据库连接、
数据更新、数据查询query
// 初始化数据库连接_conn mysql_init(nullptr);// 释放数据库连接资源
if (_conn ! nullptr)mysql_close(_conn);// 连接数据库MYSQL *p mysql_real_connect(_conn, server.c_str(), user.c_str(),password.c_str(), dbname.c_str(), 3306, nullptr, 0);// 更新操作
mysql_query(_conn, sql.c_str())// 查询操作
mysql_query(_conn, sql.c_str())return mysql_use_result(_conn);2.2.3. model 该模块用来实现用户需求与服务器数据库交互增、删、改、查问题
以举例
// 添加好友关系在好友数据表中添加一条记录
sprintf(sql, insert into friend values(%d, %d), userid, friendid);// 返回用户好友列表联合查询用户表和好友表将结果插入vector并用返回
sprintf(sql, select a.id,a.name,a.state from user a /
inner join friend b on b.friendid a.id where b.userid%d, userid);// 删除用户的离线消息删除离线列表的一条信息
sprintf(sql, delete from offlinemessage where userid%d, userid);// 更新用户的状态信息
sprintf(sql, update user set state %s where id %d,/user.getState().c_str(), user.getId());
2.2.4. redis
基于Redis发布订阅问题解决跨服务器通信问题
初始化发布上下文、订阅上下文进行连接、向指定chennel 发布、订阅结束订阅、断开连接 2.2.5. service
设置方法map集合方法id方法handler绑定器
设置用户连接map集合用户id连接TcpConnectionPtr接口将所有方法的枚举值函数方法绑定器插入map表连接Redis服务器、MySQL 数据库
基于具体的方法选择结合底层存储的用户数据查询、插入、删除完成登录、注册、注销用户
结合model模块下的函数具体结合用户需求完善功能函数
聊天服务查询用户的连接信息在本服务器时转发聊天信息不在本台服务器检查数据库的用户登陆状态未登录存储离线信息表登录则发布到Redis的发布队列
登录问题最复杂
从json对象解析得到登录id、密码
在用户信息表中查询该id的所属对象并比对密码不一致将封装json返回原因
一致时检查登陆状态避免重复登陆继而更新用户的登陆状态
在用户登录map中插入其连接信息
订阅Redis对该id 为chennel的消息
打印该用户的离线消息
将该对象的好友信息封装为vector存储的json序列化文本信息作为返回的json-response对象key-value 存储的对象之一群组信息如上
最后返回最后的json-response序列化内容。
2.2.6. public
保存服务方法的枚举信息将每一服务名称与id一一对应