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.结语

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


相关推荐
大树882 小时前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 小时前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质3 小时前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
小宇宙Zz3 小时前
Maven依赖冲突
java·服务器·maven
Inhand陈工4 小时前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智4 小时前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_4 小时前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
古城小栈5 小时前
Unix 与 Linux 异同小叙
linux·服务器·unix
施努卡机器视觉5 小时前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造
程序猿阿伟5 小时前
《Chrome离线扩展安装的底层逻辑与场景落地指南》
服务器·网络·chrome