1.json
一种数据序列化的方式。先将数据==》json对象=》文本
格式

原先的js对象,出不了门。只能在自己的电脑是看地址读数据。现在给它拍扁成文本形式,这样在另一台电脑上才有人可以认出它嘛。

{},【】," "这些符号都有特定的寓意。
用{ }括起来的,
js["id"] = { 1 , 2 , 3 , 4 , 5 };{ }是初始化列表的代表。
{"id":[1,2,3,4,5],"name":"zhangsan"}则是它原本的功能,里面必须包含字符串(" ")。
还有json打印出来,就是key : value。有这个:就是json的特点。
2.muduo网络库
框架搭起来后,我们只需要关注2个点。
在当前chatServer服务器类的构造函数当中,注册处理连接 的回调函数和处理读写 事件的回调函数。


构造一个chatServer,网络模块。

3.cmake
cMakeList.txt

cmake . 根据CMakeList.txt生成Makefile文件
make执行Makefile文件,(Makefile文件就是集成了很多编译命令)生成可执行程序


4.Mysql相关
1.sql语句先在mysql服务端建库建表

2.用c++将Mysql封装起来,作为数据客户端层
这样调用Mysql的对象会遵循RAII。
在服务器端也能连接db,敲sql命令了。

3.用user,userModel类将业务层和数据层解耦
业务层往只会看到操作UserModel往User类中再增加一行。
UserModel才会看到对数据层的操作。


5.业务模块与网络模块解耦
回调函数 +Map 将网络模块,业务模块解耦。
解耦很容易理解,就是在网络模块中,不会出现业务模块的函数(虽然底层调用的还是void login()),用msgHandler当做盲盒。
chatserver不知道盲盒中是什么,只知道要执行盲盒。
chatservice注册盲盒中是什么。


业务



1. 注册业务
业务层ChatSevice::reg()通过User UserModel::insert(int user)来注册
2. 登录业务
业务层ChatSevice::login( )通过User UserModel::query(int id),userModel.updateState(user)来登录。
(比如id 1在表中吗,如果在就将其state设置为online)。
另外,在业务层中放一个
cpp
//存储在线用户的通信连接
unordered_map<int,TcpConnectionPtr> _userConnMap;
3.客户端异常退出业务
业务层ChatService::clientCloseExecption通过userModel.updateState(user)来实现退出。
更新用户状态信息 user表中状态改为offline
同时,从userConnMap中删除用户的连接信息
4.1对1聊天业务+离线消息存储业务
A向B发消息。A通过tcpConnectionA发给服务器,服务器再通过tcpConnectionB发给B(userConnMap的作用来了)
业务层ChatService::oneChat通过userConnMap找到另一个tcpConnection
5.离线消息存储业务
A向B发消息,但是B离线。
业务层通过offlineMsgModel操作层,往B的offlineMsg表中添加数据。
B上线后通过OfflineMsgModel::query(int userid)可以查到
6.服务器异常退出
服务器异常是ctrl+c触发的,所以没有msgid。没有在msgHandleMap查找
,而是直接通过signal(SIGINT,resetHandler)捕获。

7.添加好友业务

添加好友后,每次用户登录会返回离线消息和好友列表。
在业务层通过addFriend()中的 FriendModel::insert+vector<User> FriendModel::query(int userid)实现。
- friendModel操作层
FriendModel::insert添加好友关系 vector<User> FriendModel::query(int userid)通过userid,查询朋友的信息.
userId是1的人的朋友的用户信息,
sql语句如下:
sql
select a.id,a.name,a.state
from user a
inner join friend b
on b.friendid=a.id
where b.userid = %d
8. 群组功能业务
麻烦死了,我直接将原本的AllGroup表和GroupUser表合并一个Group表。
合并出来的表还可以直接继承 user表。爽。
用GroupModel操作Group表。
实现4个功能:
- 创建群。再创建一个Group表。
- 加入群。就是在Group表中插入一行。insert into group
- 查询用户所在群组信息。将这个表的信息都查询出来select
- 发送群聊消息,在这个群的所有成员都可以收到,不在线的成员的消息要存储到离线消息表
客户端首页功能开发
- 注册成功,客服端接收到服务器返回的msgid:Reg_MSG_ACK。会打印"register success"
- 登陆成功,会打印这个用户的好友列表,群里的好友信息,还有离线消息。
服务器集群
加了nginx ,可以更好处理高并发。有一个服务器宕机,也不影响其他的。

从"单机时代"跨入到了"分布式时代"。不同服务器之间的内存是不共享的。Nginx 把用户 A 分配到了 Server 1,把用户 B 分配到了 Server 2,Server 1 怎么可能拿到 Server 2 内存里的 TCP 连接(userConMap)呢?
引入 基于发布-订阅的redis消息队列 。
底层就是redis的单Reactor单线程模式,用发发布-订阅 封装。
