集群C++聊天服务器

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个功能:

  1. 创建群。再创建一个Group表。
  2. 加入群。就是在Group表中插入一行。insert into group
  3. 查询用户所在群组信息。将这个表的信息都查询出来select
  4. 发送群聊消息,在这个群的所有成员都可以收到,不在线的成员的消息要存储到离线消息表

客户端首页功能开发

  1. 注册成功,客服端接收到服务器返回的msgid:Reg_MSG_ACK。会打印"register success"
  2. 登陆成功,会打印这个用户的好友列表,群里的好友信息,还有离线消息。

服务器集群

加了nginx ,可以更好处理高并发。有一个服务器宕机,也不影响其他的。

从"单机时代"跨入到了"分布式时代"。不同服务器之间的内存是不共享的。Nginx 把用户 A 分配到了 Server 1,把用户 B 分配到了 Server 2,Server 1 怎么可能拿到 Server 2 内存里的 TCP 连接(userConMap)呢?

引入 基于发布-订阅的redis消息队列

底层就是redis的单Reactor单线程模式,用发发布-订阅 封装。

相关推荐
你不是我我3 小时前
【Java 开发日记】HTTP3 性能更好,为什么内网微服务依然多用 HTTP2?HTTP2 内网优势是什么?
java·开发语言·微服务
tjl521314_214 小时前
04C++ 名称空间(Namespace)
开发语言·c++
ximu_polaris4 小时前
设计模式(C++)-行为型模式-备忘录模式
c++·设计模式·备忘录模式
赏金术士4 小时前
Kotlin 数据流与单双向绑定
android·开发语言·kotlin
逻辑驱动的ken5 小时前
Java高频面试场景题25
java·开发语言·深度学习·面试·职场和发展
杨云龙UP5 小时前
SQL Server2022部署:Windows Server 2016下安装、SSMS配置、备份还原与1433端口放通全流程_20260508
运维·服务器·数据库·sql·sqlserver·2022
AI人工智能+电脑小能手6 小时前
【大白话说Java面试题】【Java基础篇】第32题:Java的异常处理机制是什么
java·开发语言·后端·面试
fish_xk7 小时前
Linux开方工具
linux·运维·服务器
無限進步D8 小时前
Java 面向对象高级 接口
java·开发语言
tankeven8 小时前
C++ 智能指针
c++