2024年C C++最全C++搭建集群聊天室(十八):nginx (2),C C++面试基础题记不住

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

redis.hpp


愿意放哪儿放哪儿,我觉着吧,怎么说redis也是个数据库,就放 db 文件夹下吧。

#ifndef REDIS_H

#define REDIS_H

#include <hiredis/hiredis.h>

#include

#include

using namespace std;

class Redis

{

public:

Redis();

~Redis();

// 连接redis服务器

bool connect();

// 向redis指定的通道channel发布消息

bool publish(int channel, string message);

// 向redis指定的通道subscribe订阅消息

bool subscribe(int channel);

// 向redis指定的通道unsubscribe取消订阅消息

bool unsubscribe(int channel);

// 在独立线程中接收订阅通道中的消息

void observer_channel_message();

// 初始化向业务层上报通道消息的回调对象

void init_notify_handler(function<void(int, string)> fn);

private:

// hiredis同步上下文对象,负责publish消息

redisContext *_publish_context;

// hiredis同步上下文对象,负责subscribe消息

redisContext *_subcribe_context;

// 回调操作,收到订阅的消息,给service层上报

function<void(int, string)> _notify_message_handler;

};

#endif


redis.cpp


这一套,可以在做轻量级集群服务器间通信用,封装好了的。

#include “redis.hpp”

#include

using namespace std;

Redis::Redis():_publish_context(nullptr), _subcribe_context(nullptr){}

Redis::~Redis(){

if (_publish_context != nullptr){

redisFree(_publish_context);

}

if (_subcribe_context != nullptr){

redisFree(_subcribe_context);

}

}

bool Redis::connect(){

// 负责publish发布消息的上下文连接

_publish_context = redisConnect(“127.0.0.1”, 6379);

if (nullptr == _publish_context){

cerr << “connect redis failed!” << endl;

return false;

}

// 负责subscribe订阅消息的上下文连接

_subcribe_context = redisConnect(“127.0.0.1”, 6379);

if (nullptr == _subcribe_context){

cerr << “connect redis failed!” << endl;

return false;

}

// 在单独的线程中,监听通道上的事件,有消息给业务层进行上报

thread t(& {

observer_channel_message();

});

t.detach();

cout << “connect redis-server success!” << endl;

return true;

}

// 向redis指定的通道channel发布消息

bool Redis::publish(int channel, string message){

redisReply *reply = (redisReply *)redisCommand(_publish_context, “PUBLISH %d %s”, channel, message.c_str());

if (nullptr == reply){

cerr << “publish command failed!” << endl;

return false;

}

freeReplyObject(reply);

return true;

}

// 向redis指定的通道subscribe订阅消息

bool Redis::subscribe(int channel){

// SUBSCRIBE命令本身会造成线程阻塞等待通道里面发生消息,这里只做订阅通道,不接收通道消息

// 通道消息的接收专门在observer_channel_message函数中的独立线程中进行

// 只负责发送命令,不阻塞接收redis server响应消息,否则和notifyMsg线程抢占响应资源

if (REDIS_ERR == redisAppendCommand(this->_subcribe_context, “SUBSCRIBE %d”, channel)){

cerr << “subscribe command failed!” << endl;

return false;

}

// redisBufferWrite可以循环发送缓冲区,直到缓冲区数据发送完毕(done被置为1)

int done = 0;

while (!done){

if (REDIS_ERR == redisBufferWrite(this->_subcribe_context, &done)){

cerr << “subscribe command failed!” << endl;

return false;

}

}

// redisGetReply

return true;

}

// 向redis指定的通道unsubscribe取消订阅消息

bool Redis::unsubscribe(int channel){

if (REDIS_ERR == redisAppendCommand(this->_subcribe_context, “UNSUBSCRIBE %d”, channel)){

cerr << “unsubscribe command failed!” << endl;

return false;

}

// redisBufferWrite可以循环发送缓冲区,直到缓冲区数据发送完毕(done被置为1)

int done = 0;

while (!done){

if (REDIS_ERR == redisBufferWrite(this->_subcribe_context, &done)){

cerr << “unsubscribe command failed!” << endl;

return false;

}

}

return true;

}

// 在独立线程中接收订阅通道中的消息

void Redis::observer_channel_message(){

redisReply *reply = nullptr;

while (REDIS_OK == redisGetReply(this->_subcribe_context, (void **)&reply)){

// 订阅收到的消息是一个带三元素的数组

if (reply != nullptr && reply->element[2] != nullptr && reply->element[2]->str != nullptr)

{

// 给业务层上报通道上发生的消息

_notify_message_handler(atoi(reply->element[1]->str) , reply->element[2]->str);

}

freeReplyObject(reply);

}

cerr << “>>>>>>>>>>>>> observer_channel_message quit <<<<<<<<<<<<<” << endl;

}

void Redis::init_notify_handler(function<void(int,string)> fn){

this->_notify_message_handler = fn;

}


chatservice修改


头文件里面自行修改吧,这里放出源文件的修改范围。

构造函数中连接上redis:

// 连接redis服务器

if (_redis.connect()){

// 设置上报消息的回调

_redis.init_notify_handler(std::bind(&ChatService::handleRedisSubscribeMessage, this, _1, _2));

}

登录成功后,向redis消息队列进行订阅:

// id用户登录成功后,向redis订阅channel(id)

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

);

}

登录成功后,向redis消息队列进行订阅:

// id用户登录成功后,向redis订阅channel(id)

[外链图片转存中…(img-E0qo71k6-1715523949564)]
[外链图片转存中…(img-dHnCvKVg-1715523949564)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值