- Json序列化和反序列化
- muduo网络库开发
- nginx源码编译安装和环境部署
- nginx的tcp负载均衡器配置
- redis缓存服务器编程实践
- 基于发布-订阅的服务器中间件redis消息队列编程实践
- MySQL数据库编程CMake构建编译环境
- 客户端新用户注册
- 客户端用户登录
- 添加好友和添加群组
- 好友聊天
- 群组聊天
- 离线消息
- nginx配置tcp负载均衡
- 集群聊天系统支持客户端跨服务器通信
就是把我们想要打包的数据,或者对象,直接处理成Json字符串。
json js;
// 添加数组
js["id"] = {1,2,3,4,5};
// 添加key-value
js["name"] = "zhang san";
// 添加对象
js["msg"]["zhang san"] = "hello world";
js["msg"]["liu shuo"] = "hello china";
// 上面等同于下面这句一次性添加数组对象
js["msg"] = {{"zhang san", "hello world"}, {"liu shuo", "hello china"}};
cout << js << endl;
序列化结果是:
{"id":[1,2,3,4,5],msg":{"liu shuo":"hello china","zhang san":"hello world"},"name":"zhang san"}
json js;
// 直接序列化一个vector容器
vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(5);
js["list"] = vec;
// 直接序列化一个map容器
map<int, string> m;
m.insert({1, "黄山"});
m.insert({2, "华山"});
m.insert({3, "泰山"});
js["path"] = m;
cout<<js<<endl;
把C++ STL中的容器内容可以直接序列化成Json字符串,上面代码打印如下:
{"list":[1,2,5],"path":[[1,"黄山"],[2,"华山"],[3,"泰山"]]}
当从网络接收到字符串为Json格式,可以用JSON for Modern C++ 直接反序列化取得数据或者直接反序列化出对象,甚至容器。
string jsonstr = js.dump();
cout<<"jsonstr:"<<jsonstr<<endl;
// 模拟从网络接收到json字符串,通过json::parse函数把json字符串专程json对象
json js2 = json::parse(jsonstr);
// 直接取key-value
string name = js2["name"];
cout << "name:" << name << endl;
// 直接反序列化vector容器
vector<int> v = js2["list"];
for(int val : v)
{
cout << val << " ";
}
cout << endl;
// 直接反序列化map容器
map<int, string> m2 = js2["path"];
for(auto p : m2)
{
cout << p.first << " " << p.second << endl;
}
cout << endl;
单台服务器受限于硬件资源,其性能是有上限的,当单台服务器不能满足应用场景的并发需求量时,就需要考虑部署多个服务器共同处理客户端的并发请求,但是客户端怎么知道去连接具体哪台服务器呢?
此时就需要一台负载均衡器,通过预设的负载算法,指导客户端连接服务器。负载均衡器有基于客户端的负载均衡和服务器的负载均衡。普通的基于哈希的负载算法,并不能满足负载均衡所要求的单调性和平衡性,但一致性哈希算法非常好的保持了这两种特性,所以经常用在需要设计负载算法的应用场景当中。
集群部署的服务器之间进行通信,最好的方式就是引入中间件消息队列,解耦各个服务器,使整个系统松耦合,提高服务器的响应能力,节省服务器的带宽资源。
在集群分布式环境中,经常使用的中间件消息队列有ActiveMQ、RabbitMQ、Kafka等,都是应用场景广泛并且性能很好的消息队列,供集群服务器之间,分布式服务之间进行消息通信。限于我们的项目业务类型并不是非常复杂,对并发请求量也没有太高的要求,因此中间件消息队列选型的是-基于发布-订阅模式的redis。
User表
字段名称 | 字段类型 | 字段说明 | 约束 |
---|---|---|---|
id | INT | 用户id | PRIMARY KEY、AUTO_INCREMENT |
name | VARCHAR(50) | 用户名 | NOT NULL, UNIQUE |
password | VARCHAR(50) | 用户密码 | NOT NULL |
state | ENUM('online','offerline') | 登录状态 | DEFAULT 'offline' |
Friend表
字段名称 | 字段类型 | 字段说明 | 约束 |
---|---|---|---|
user id | INT | 用户 id | NOT NULL、联合主键 |
friend id | INT | 好友 id | NOT NULL、联合主键 |
AllGroup表
字段名称 | 字段类型 | 字段说明 | 约束 |
---|---|---|---|
id | INT | 组id | PRIMARY KEY、AUTO_INCREMENT |
groupname | VARCHAR(50) | 组名称 | NOT NULL,UNIQUE |
groupdesc | VARCHAR(200) | 组功能描述 | DEFAULT '' |
GroupUser表
字段名称 | 字段类型 | 字段说明 | 约束 |
---|---|---|---|
group id | INT | 组id | NOT NULL、联合主键 |
user id | INT | 组员id | NOT NULL、联合主键 |
grouprole | ENUM('creator', 'normal') | 组内角色 | DEFAULT ‘normal’ |
OfflineMessage表
字段名称 | 字段类型 | 字段说明 | 约束 |
---|---|---|---|
user id | INT | 用户id | NOT NULL |
message | VARCHAR(500) | 离线消息(存储Json字符串) | NOT NULL |