C++实现校园集群聊天服务器
文章平均质量分 66
基于muduo和nginx和json的集群聊天服务器项目,在linux上用C++开发。
林林林ZEYU
坚持
展开
-
906-gdb调试解决聊天服务器项目消息中间件编程遇到的两个Bug
bug 1. 向消息中间件PUBLISH发布消息不成功,导致无法跨服务器通信bug 2. 多次向中间件SUBSCRIBE订阅消息,出现无响应,客户端也无响应问题背景以redis的发布-订阅机制作为集群服务器的消息中间件,解耦服务器之间的通信。用hiredis做客户端编程。Bug1两个客户端C1和C2分别登录在两台服务器S1和S2上,服务器通过redis作为消息中间件进行消息通信。当客户端C1和C2通信时,C1先发送消息到S1上,S1向redis上名字为C2的channel通道发布消息,S2服务器从原创 2021-12-07 19:34:37 · 504 阅读 · 1 评论 -
794-对负载均衡的学习
对负载均衡的学习首先 撇开对线上的影响,如果线上突发来了流量,后端服务扛不住,我们会怎么做呢?无非两种方式:1、提升机器配置(CPU、内存、硬盘、带宽等)2、扩充机器的数量上面两种方式,我们称之为纵向扩展和横向扩展。纵向扩展,是从单机的角度通过增加硬件处理能力,比如CPU处理能力,内存容量,磁盘等方面,实现服务器处理能力的提升,不能满足大型分布式系统(网站),大流量,高并发,海量数据的问题。横向扩展,通过添加机器来满足大型网站服务的处理能力。比如:一台机器不能满足,则增加两台或者多台机器,共同原创 2021-11-10 22:00:21 · 869 阅读 · 0 评论 -
666-集群聊天服务器项目总结
集群聊天服务器项目总结这个项目分为4个模块,首先,第一个模块是网络模块,我通过深入剖析muduo网络库的核心组件,采用C++11重写muduo库的核心组件,将依赖于boost库的技术点转化为C++11的知识点,使其脱离boost库,实现出一套网络库来使用,使用这个网络库的好处是:解耦了网络模块的代码和业务层的代码,能够让开发者专注于业务层的开发。然后第二个模块是业务模块,也就是是服务层,我使用了C++11的一些技术,比如说,map,绑定器,函数对象,做了一个消息id和这个消息发生以后的回调操作的绑定,相当原创 2021-10-09 09:28:26 · 2167 阅读 · 2 评论 -
665-集群聊天服务器的客户端注销问题
客户端注销问题客户端注销后再次登录,失败了。这种假死的场景在Ubuntu比较小概率,但是在centos大概率会发生。我们gdb去调试看看是什么原因:gdb attach 4207我们的客户端有2个线程:一个专门读(主线程,接收客户端用户的输入,然后发送),一个专门写(子线程,recv接收,打印信息)但是,我们现在看到,这2个线程都在recv主线程阻塞在这里:很明显,我们的子线程也在recv上,我们看到,子线程也阻塞在recv也就是说,现在的现象是:客户端刚才登录成功,然后注销退原创 2021-10-04 20:58:22 · 340 阅读 · 0 评论 -
514-一致性哈希算法-负载均衡
场景1(业务服务器)–普通哈希算法存在的问题轮询算法:第一个请求给server1,第二个请求给server2,第3个请求给server3,一直轮询下去。权重比算法:比如说,给第1台分配1的权重,给第2台分配2的权重,给第3台分配1的权重,有4个请求到来,其中2个请求分配给第2台,其他两台各分配1个请求。最少连接算法:负载均衡器要记录跟每一台服务器建立的连接,每次发请求的时候,跟哪台请求创建的连接最少就分发给哪台机器,哪台服务器连接少,说明其压力小,新来的请求就给到压力最小的服务器。哈希算法:除留.原创 2021-09-02 20:44:15 · 1102 阅读 · 1 评论 -
405-Redis发布订阅消息队列在项目上的代码和项目测试
redis发布-订阅的客户端编程redis支持多种不同的客户端编程语言,例如Java对应jedis、php对应phpredis、C++对应的则是hiredis。下面是安装hiredis的步骤:1. git clone https://github.com/redis/hiredis 从github上下载hiredis客户端,进行源码编译安装2、cd hiredis3、make4、sudo make install拷贝生成的动态库到/usr/local/lib目录下!5、sudo ldconf原创 2021-08-08 21:53:04 · 505 阅读 · 0 评论 -
404-redis发布-订阅相关命令
Ubuntu命令sudo apt-get install redis-serverubuntu通过上面命令安装完redis,会自动启动redis服务,通过ps命令确认:可以看到redis默认工作在本地主机的6379端口上。启动Redis客户端详细的Redis安装见我的Redis专栏redis发布-订阅相关命令redis首先是一个强大的缓存服务器,比memcache强大很多,不仅仅支持多种数据结构(不像memcache只能存储字符串)如字符串、list列表、set集合、map映射表等结构,原创 2021-08-08 20:45:22 · 381 阅读 · 0 评论 -
403-nginx的tcp负载均衡配置
负载均衡器 - 一致性哈希算法单台服务器受限于硬件资源,其性能是有上限的,当单台服务器不能满足应用场景的并发需求量时,就需要考虑部署多个服务器共同处理客户端的并发请求,但是客户端怎么知道去连接具体哪台服务器呢?此时就需要一台负载均衡器,通过预设的负载算法,指导客户端连接服务器。负载均衡器有基于客户端的负载均衡和服务器的负载均衡。普通的基于哈希的负载算法,并不能满足负载均衡所要求的单调性和平衡性,但一致性哈希算法非常好的保持了这两种特性,所以经常用在需要设计负载算法的应用场景当中。nginx配置tcp原创 2021-08-08 20:33:23 · 637 阅读 · 1 评论 -
402-如何解决集群聊天服务器跨服务器通信
我们在集群聊天服务器中涉及的通信是:一对一的聊天,群聊。我们看上图,client1登录在chatserver1上,client2登录在chatserver2上,client3登录在chatserver3上,按我们现有的单台服务器业务来说,当client1给client2发送聊天消息的话,我们在每一台服务器上都有_userConMap,在chatserver1上的_userConMap肯定是找不到client2的connection,所以,在集群环境中,我们服务器的代码在业务逻辑上应该做修改,客户端完全不.原创 2021-08-08 12:21:58 · 684 阅读 · 0 评论 -
401-集群聊天服务器为什么要引入负载均衡器
一台服务器在我们的32位的linux下并发量:2万左右的并发量,单台的chatserver支持2万左右的用户在线聊天,如果要支持3万,4万用户同时在线聊天就不可以了。如果我们想提供我们聊天服务器的并发能力,让更多的用户可以同时在线聊天,我们要进行集群部署。在水平方向上扩展多台主机,每一台主机运行着独立的chatserver,我们在下图中,引入了3台主机,每一台主机运行着独立的chatserver服务器,可以给用户提供聊天服务,但是,我们在用QQ客户端登录的时候,人家有没有问你想连哪个服务器?不能把选择服务器原创 2021-08-08 11:46:03 · 485 阅读 · 2 评论 -
400-集群聊天服务器的客户端开发
我们之前把聊天服务器的代码基本上功能开发完了,在后面转成集群版本的时候要引入中间件-基于发布订阅的Redis。现在我们先开始客户端的开发我们聊天服务器项目工程的客户端和服务器会共用很多代码,所以把他们放在集成编译环境中有很大的优势。当客户端和服务器共享头文件,可以同步修改,修改一份都是可见的。集群聊天服务器的客户端开发我们在src下创建一个文件夹:client我们完善src下的CMakeLists.txt我们在src下的client下创建文件:CMakeLists.txt# 定义了一个SR原创 2021-08-08 11:05:17 · 408 阅读 · 0 评论 -
399-群组业务代码
群组业务包含:管理员创建群,组员加入群,群聊群组里面包含组员,一个组员可以在多个群组,一个群组可以有多个组员分为管理员,普通成员群组业务代码我们在include下的server下的model下创建文件:group.hpp#ifndef GROUP_H#define GROUP_H#include "groupuser.hpp"#include <string>#include <vector>using namespace std;//User表的ORM类原创 2021-08-07 21:38:35 · 403 阅读 · 0 评论 -
398-添加好友业务代码和测试
我们在mysql数据库有Friend表表中两个字段,一个是用户id,一个是用户的friend的id,这种关系不用写多次,所以用联合主键。我跟你是好友写一般就可以了。我把你添加好友,服务器会给我返回好友列表信息,然后我根据列表上的用户的id号进行聊天。添加好友业务代码我们完善public.hpp#ifndef PUBLIC_H#define PUBLIC_H/*server和client的公共文件*/enum EnMsgType{ LOGIN_MSG = 1,//登录消息原创 2021-08-07 20:14:00 · 636 阅读 · 0 评论 -
397-服务器异常退出处理代码和测试
在之前,我完成看客户端异常退出的处理代码,客户端异常退出是因为它没有发出json字符串,是通过连接异常断开进行用户的connection的删除和用户表状态的更改。但是服务器异常退出了,user表的用户的状态还是online,这个问题还没有解决。因为我们Ctrl C强制退出服务器的时候,服务器根本没有机会去数据库里更改用户的状态信息。服务器异常退出处理代码我们完善src下的server下的main.cpp#include "chatserver.hpp"#include "chatservice.hp原创 2021-08-07 13:40:40 · 474 阅读 · 0 评论 -
396-离线消息业务代码和测试
在数据库中,我们有专门一个表来存储离线消息我们在include的server下的model文件夹里创建文件:offlinemessagemodel.hpp#ifndef OFFLINEMESSAGEMODEL_H#define OFFLINEMESSAGEMODEL_H#include <string>#include <vector>using namespace std;//提供离线消息表的操作接口方法class OfflineMsgModel{pub原创 2021-08-07 11:37:30 · 355 阅读 · 0 评论 -
395-点对点聊天业务代码和测试
在一对一的聊天业务中,发送过来的json数据都包含了哪些字段?首先我们完善一下public.hpp增加字段 :ONE_CHAT_MSG,//聊天消息#ifndef PUBLIC_H#define PUBLIC_H/*server和client的公共文件*/enum EnMsgType{ LOGIN_MSG = 1,//登录消息 LOGIN_MSG_ACK,//登录响应消息 REG_MSG,//注册消息 REG_MSG_ACK,// 注册响应消息 O原创 2021-08-07 09:40:00 · 268 阅读 · 0 评论 -
394-客户端异常退出业务代码和测试
我们要处理一下客户端的异常退出,客户端在没有任何响应的情况下,直接给异常退出了,它在目前的代码下,退出没有合法的json字符串,json请求,而只是网络连接断开了,我们还要修改用户的状态为offline。客户端异常退出业务代码和测试如果客户端异常退出,它根本就没有发出合法的json消息,而是直接断开连接了。chatserver.cpp所以,在这里,我们专门写一个方法。//上报链接相关信息的回调函数void ChatServer::onConnection(const TcpConnection原创 2021-08-06 23:02:19 · 542 阅读 · 0 评论 -
393-记录用户的连接信息和线程安全问题
假设有2个用户,用户1把它的id号和要说的内容发过去,服务器要主动地去给用户2推送这个消息,但是用户2又不知道什么时候谁会给他说话,他不可能去服务器上拉取消息,所以这个聊天 肯定得是服务器推送给用户2,所以聊天服务器也必须是长连接,不仅仅是客户端请求,服务端被动接收,而且服务端还要主动推送消息到客户端,所以我们拿到用户2的id号,怎么知道这个用户的连接connection在哪里,所以,我们在业务层要想办法,一个用户一个connection,登录成功,连接就建立成功了,这个连接就可以存储下来。记录用户的连接原创 2021-08-06 19:19:16 · 275 阅读 · 0 评论 -
392-用户登录业务代码和测试
用户登录业务代码我们先完善一下public.hpp#ifndef PUBLIC_H#define PUBLIC_H/*server和client的公共文件*/enum EnMsgType{ LOGIN_MSG = 1,//登录消息 LOGIN_MSG_ACK,//登录响应消息 REG_MSG,//注册消息 REG_MSG_ACK,//注册响应消息};#endif我们完善一下include下的server下的model下的usermodel.hp原创 2021-08-06 11:57:58 · 289 阅读 · 0 评论 -
391-用户注册业务代码和测试
用户注册业务代码我们先完善chatservice.hpp#ifndef CHATSERVICE_H#define CHATSERVICE_H#include <muduo/net/TcpConnection.h>#include <unordered_map>//一个消息ID映射一个事件处理 #include <functional>using namespace std;using namespace muduo;using namespace mu原创 2021-08-06 11:08:52 · 1225 阅读 · 0 评论 -
390-Model数据层代码框架设计
Model数据层代码框架设计数据库的操作和业务代码分离开在业务层看到对象,在数据库层看到数据库的操作。我们要定义相关的一些类,和数据库的表一一对应的,才能把数据库读出来的字段合成一个对象提供给业务方去使用!映射类!我们在inlcude的server下创建一个文件夹:model首先我们在model文件夹下创建文件:user.hpp#ifndef USER_H#define USER_H#include <string>using namespace std;//User表原创 2021-08-06 10:08:28 · 369 阅读 · 0 评论 -
389-MySQL数据库代码封装
我们在上一节中把网络模块和业务模块的代码通过事件回调完全地拆分开。现在我们需要把业务模块的和数据层的代码区分开。(不在业务模块出现数据库的增删改查,增加中间的一层类)我们需要libmysqlclient.so,对外的API方法,连接mysqlserver,进行增删改查。我们在include下的server下创建一个文件夹:db然后完善项目工程目录上的CMakeLists.txt然后我们完善src下的server下的CMakeLists.txt我们在include下的server下的db下原创 2021-08-06 09:40:55 · 512 阅读 · 1 评论 -
388-完成业务模块代码ChatService并且和网络模块耦合度降级处理
完成业务模块代码ChatService我们怎么把网络模块收到的消息派发到业务模块,服务模块。让网络模块的代码和业务模块的代码完全解耦。假设一个用户在做登录业务,messageid,name,passwd我们在include下的server创建头文件:chatservice.hpp#ifndef CHATSERVICE_H#define CHATSERVICE_H#include <muduo/net/TcpConnection.h>#include <unordered_m原创 2021-08-05 21:49:01 · 450 阅读 · 1 评论 -
387-网络模块代码ChatServer
网络模块代码ChatServer首先,我们在include下的server下创建头文件:chatserver.hpp#ifndef CHATSERVER_H#define CHATSERVER_H#include <muduo/net/TcpServer.h>#include <muduo/net/EventLoop.h>using namespace muduo;using namespace muduo::net;//聊天服务器的主类class ChatSe原创 2021-08-05 20:10:13 · 478 阅读 · 0 评论 -
386-基于muduo和nginx的集群聊天服务器的项目工程构建
项目工程目录我们的聊天服务器程序和客户端程序都在一个工程里面,最后在bin生成2个可执行文件,一个是服务器,一个是客户端。配置chatserver(根)下的CMakeLists.txtcmake_minimum_required(VERSION 3.0)project(chat)# 配置编译选项set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)# 配置最终的可执行文件输出的路径set(EXECUTABLE_OUTPUT_PATH ${PROJECT_S原创 2021-08-05 19:35:55 · 498 阅读 · 1 评论 -
385-MySQL环境搭建和编程和项目表的设计
MySQL环境安装设置ubuntu环境安装mysql-server和mysql开发包,包括mysql头文件和动态库文件,命令如下:sudo apt-get install mysql-server =》 安装最新版MySQL服务器sudo apt-get install libmysqlclient-dev =》 安装开发包ubuntu默认安装最新的mysql,但是初始的用户名和密码是自动生成的,按下面步骤修改mysql的root用户密码为123456【step 3】重新用root和12345原创 2021-08-05 11:12:21 · 440 阅读 · 0 评论 -
384-CMake构建集成编译环境
CMake简介使用简单方便,可以跨平台,构建项目编译环境。尤其比直接写Makefile简单(在构建大型工程编译时,需要写大量的文件依赖关系),可以通过简单的CMake生成负责的Makefile文件。CMake安装ubuntu上直接执行 sudo apt install cmake 安装完可以通过cmake -version查看其版本:CMake在Ubuntu的VScode安装插件安装CMake使用介绍cmake命令会执行目录下的CMakeLists.txt配置文件里面的配置项,一个基本的原创 2021-08-05 10:18:56 · 603 阅读 · 0 评论 -
383-muduo网络库编程
muduo网络库编程muduo网络库的底层就是epoll加linux的pthread线程库。所以muduo库只能装在linux环境中。muduo网络库的安装见我的另外一篇博客就可以。我们在做项目的时候,服务器一定要做到高并发,要用到muduo库。但是客户端只是向服务器请求服务,不需要高并发的性能要求。基于muduo的客户端服务器编程muduo网络库的编程很容易,要实现基于muduo网络库的服务器和客户端程序,只需要简单的组合TcpServer和TcpClient就可以,代码实现如下:服务器类的原创 2021-08-04 21:25:08 · 622 阅读 · 0 评论 -
382-Json的介绍和使用
Json的介绍和使用Json是一种轻量级的数据交换格式(也叫数据序列化方式)。Json采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 Json 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。我们在做聊天服务器项目的时候,比如说,我们发送一个聊天的消息,消息的种类很多,用msg_type区分,是登录消息,注册消息,聊天消息,还是加好友,群组的消息。from来自哪里,to给谁说的,msg消息的内容。msg_type:2from转载 2021-08-04 11:05:32 · 693 阅读 · 0 评论 -
381-基于muduo和nginx的集群聊天服务器
开发语言C++需要用到的技术栈Json序列化和反序列化muduo网络库开发nginx源码编译安装和环境部署nginx的tcp负载均衡器配置redis缓存服务器编程实践基于发布-订阅的服务器中间件redis消息队列编程实践MySQL数据库编程CMake构建编译环境Github托管项目项目需求客户端新用户注册客户端用户登录添加好友和添加群组好友聊天群组聊天离线消息nginx配置tcp负载均衡集群聊天系统支持客户端跨服务器通信开发环境ubuntu linux环境安原创 2021-08-04 09:32:33 · 1000 阅读 · 1 评论