IM项目——消息转发子服务

目录

1.引言

2.代码实现

3.结语


1.引言

消息转发子服务,人不如其名,它干的不是消息转发,而是告诉网关要将收到的消息转发给哪些用户,除此之外,还将消息进行组装,得到完整的信息后,转发给消息队列,供消息管理子服务从消息队列中消费,进行持久化存储。

2.代码实现

消息转发子服务仅仅提供了一个接口,它完成的就是上面提到功能。

实现流程:首先要提取出请求中的用户ID,明确是谁发的,然后还要提取出所属的聊天会话,这样才能够知道这些消息发给谁,其次就是对这条消息进行封装,转发给消息队列,最后就是遍历会话成员表chat_session_member获取这个会话的所有成员,然后通过响应告诉网关转发列表即可。

cpp 复制代码
void GetTransmitTarget(google::protobuf::RpcController* controller,
            const ::pcz::NewMessageReq* request,
            ::pcz::GetTransmitTargetRsp* response,
            ::google::protobuf::Closure* done) override {

            brpc::ClosureGuard rpc_guard(done);
            //组织错误响应
            auto err_response = [response](const std::string& id, const std::string& errmsg) {
                response->set_request_id(id);
                response->set_success(false);
                response->set_errmsg(errmsg);
            };
            //从请求中提取用户ID,消息内容,所属聊天会话
            std::string user_id = request->user_id();
            const MessageContent& content = request->message();
            std::string session_id = request->chat_session_id();
            //根据user_id获取用户的完整信息,通过channel_manager获取用户连接信息
            auto channel = _channel_manager->choose(_user_service_name);
            if (!channel) {
                err_response(request->request_id(), "获取用户服务信道失败");
                LOG_ERROR("获取用户服务信道失败 user_id={}", user_id);
                return;
            }
            //通过RPC调用用户服务,获取用户的连接信息
            UserService_Stub stub(channel.get());
            GetUserInfoReq req;
            GetUserInfoRsp rsp;
            req.set_request_id(request->request_id());
            req.set_user_id(user_id);
            brpc::Controller cntl;
            stub.GetUserInfo(&cntl, &req, &rsp, nullptr);
            if (cntl.Failed() == true || rsp.success() == false) {
                LOG_ERROR("{} - 用户子服务调用失败:{}!", request->request_id(), cntl.ErrorText());
                return err_response(request->request_id(), "用户子服务调用失败!");
            }
            //组织消息发送到消息队列
            MessageInfo message;
            message.set_message_id(uuid());
            message.set_chat_session_id(session_id);
            message.set_timestamp(time(nullptr));
            message.mutable_sender()->CopyFrom(rsp.user_info());
            message.mutable_message()->CopyFrom(content);
            bool publish_ok = _mq_client->publish(
                _exchange_name, message.SerializeAsString(), _routing_key
            );
            if (!publish_ok) {
                err_response(request->request_id(), "消息发布失败");
                LOG_ERROR("消息发布失败 user_id={}", user_id);
                return;
            }
            //组织响应
            //获取消息转发列表
            auto member_list = _mysql_session_member_table->members(session_id);
            for (const auto& member : member_list) {
                // 排除发送者自己,避免向自己转发
                if (member == user_id) continue;
                response->add_target_id_list(member);
            }
            response->set_request_id(request->request_id());
            response->mutable_message()->CopyFrom(message);
            response->set_success(true);
        }

3.结语

这个消息转发子服务的功能比较单一,所以篇幅很短。


相关推荐
-Try hard-1 天前
Linuv软件编程 | Shell命令
linux·运维·服务器
释怀不想释怀1 天前
Linux快捷键,软件安装启动
linux·运维·服务器
zhengfei6111 天前
自动化快速评估工具
运维·自动化
Hello World . .1 天前
Linux:软件编程
linux·运维·服务器·vim
老师用之于民1 天前
【DAY21】Linux软件编程基础&Shell 命令、脚本及系统管理实操
linux·运维·chrome·经验分享·笔记·ubuntu
路由侠内网穿透.1 天前
本地部署代码托管解决方案 Gitea 并实现外部访问( Windows 版本)
运维·服务器·网络协议·gitea
serve the people1 天前
python环境搭建 (十三) tenacity重试库
服务器·python·php
jake don1 天前
GPU服务器搭建大模型指南
服务器·人工智能
江畔何人初1 天前
pod的内部结构
linux·运维·云原生·容器·kubernetes
齐鲁大虾1 天前
Linux下用什么编程语言方便开发B/S架构程序
linux·运维·架构