基于C++实现的Linux环境下的实时通讯聊天项目,目前支持的功能包括:
- 注册
- 登录
- 私聊
- 群聊
- 记录用户状态实现免登录功能
本项目采用C/S架构,使用I/O多路服用技术epoll模型结合线程池实现的模拟Proactor模式来实现并发服务。MySQL用于存储用户的账号信息、Redis缓存记录用户的登录状态,并通过加入布隆过滤器减少了对于MySQL的查询数量,提供了并称性能。
- Ubuntu 20.04
- g++
- Mysql 5.7.16
- redis 6.2.5
- hiredis库
- C++技术、STL库容器和函数
- 多线程结合线程池实现并发性
- I/O多路服用(使用epoll的ET边缘触发)
- TCP socket网络编程
- MySQL数据库以及SQL语句
- Redis数据库(Hash数据类型,设置键的过期时间)
- 线程同步技术(互斥锁、自旋锁、信号量)
- Makefile编译
- git版本管理
- 使用bitmap实现布隆过滤器
- 用 Mysql 记录客户的账号和密码,注册和登录都要经过 Mysql
- 使用 C/S 模型完成私聊和群聊功能,所有的请求和聊天记录都会经过服务器并转发,减轻客户端压力,客户端只维护和服务器的 TCP 连接
- IO 多路复用 + 线程池:采用 epoll 的边缘触发 ET 模式,对所有的读事件感兴趣,主线程使用 epoll_wait 监听事件,若监测到某个 socket 上有读事件时将会接收数据,并封装成任务加入到任务队列中,通过信号量来唤醒线程池中的工作线程进行处理,线程池中的工作线程负责业务处理,同时 epoll 采用 EPOLLSHOT 模式,防止多个线程在同一 socket 上处理。
- Redis 记录登录状态:用户登录时,如果验证成功,服务器会生成一个唯一的 session_id,将其插入到 Redis 缓存中(key 为 session_id,value 为 用户信息),并设置过期时间,同时 session_id 会被封装到登录状态回复信息中,客户端将作为 cookie 文件进行存储。如果用户在此期间再次登录,则会发送该 cookie,查询合法后会直接进入登录状态,实现记录登录状态免登录功能。
- 布隆过滤器:服务器收到登录请求时,会先根据布隆过滤器来判断该用户名是否一定不存在,如果能够判断不存在就不会查询 MySQL 数据库,减小开销。
test_pressure/test_client.cpp 会根据接收到的参数,向服务器发起指定数量的并发连接,并在这些连接上对服务器发出登录请求,每次使用的用户名和密码都是从本地的 account.txt 文件中进行读取。
其中 test_pressure/add_user.cpp 实现向服务器数据库插入10000个用户,用于进行压力测试。
- 需要部署 MySQL、Redis,以及安装对应的库,启动 Mysql、Redis 服务
- 在数据库创建一个数据库叫 test_connect,再创一个表叫 user,表有两项 VARCHAR 类型属性:NAME 和 PASSWORD,将 NAME 设为主键
- 修改 client.cpp 代码中的 ip 地址,更改为自己的服务器 ip 地址
- 修改 mysql_connection.hpp 中数据库的账户信息
- 执行 make
- 用一个终端先运行 server
- 再开另外一个或多个终端运行 client