【聊天室后端服务器开发】消息转发子服务

基本逻辑

功能实现流程

  • 服务注册和发现
    • 通过服务注册模块将服务注册到服务中心
    • 通过服务发现模块进行服务发现,管理可用的用户子服务
  • 消息传递流程
    • 客户端通过调用RPC方法,传递请求消息
    • 服务根据请求获取用户信息、构建消息对象、查询聊天会话成员
    • 消息通过消息队列(RabbitMQ)进行持久化,确保消息的可靠传递
  • RPC服务
    • 通过实现RPC接口,处理客户端请求并返回结果
  • 消息队列 
    • 消息发布到消息队列中,其他服务可以对该队列中的消息进一步处理

具体实现

 数据管理

ODB

#pragma once
#include <string>
#include <cstddef> 
#include <odb/core.hxx>

namespace mag {
#pragma db object table("chat_session_member")
class ChatSessionMember {
    public:
        ChatSessionMember(){}
        ChatSessionMember(const std::string &ssid, const std::string &uid):
            _session_id(ssid), _user_id(uid){}
            ~ChatSessionMember(){}

        std::string session_id() const { return _session_id; }
        void session_id(std::string &ssid)  { _session_id = ssid; }
        
        std::string user_id() const { return _user_id; }
        void user_id(std::string &uid)  { _user_id = uid; }
    private:
        friend class odb::access;
        #pragma db id auto
        unsigned long _id;
        #pragma db type("varchar(64)") index 
        std::string _session_id;
        #pragma db type("varchar(64)") 
        std::string _user_id;
};
}

 mysql数据库操作,针对于聊天会话成员表

  • 新增单个会话成员
  • 新增多个会话成员
  • 删除单个会话成员
  • 删除多个会话成员
  • 获取会话成员
#pragma once
#include "mysql.hpp"
#include "chat_session_member.hxx"
#include "chat_session_member-odb.hxx"

namespace mag
{
class ChatSessionMemeberTable{
    public:
        using ptr = std::shared_ptr<ChatSessionMemeberTable>;
        ChatSessionMemeberTable(const std::shared_ptr<odb::core::database> &db):_db(db){}
        //新增单个会话成员
        bool append(ChatSessionMember &csm) {
            try {
                odb::transaction trans(_db->begin());
                _db->persist(csm);
                trans.commit();
            }catch (std::exception &e) {
                LOG_ERROR("新增单会话成员失败 {}-{}:{}!", 
                    csm.session_id(), csm.user_id(), e.what());
                return false;
            }
            return true;
        }
        //新增多个会话成员
        bool append(std::vector<ChatSessionMember> &csm_lists) {
            try {
                odb::transaction trans(_db->begin());
                for (auto &csm : csm_lists) {
                    _db->persist(csm);
                }
                trans.commit();
            }catch (std::exception &e) {
                LOG_ERROR("新增多会话成员失败 {}-{}:{}!", 
                    csm_lists[0].session_id(), csm_lists.size(), e.what());
                return false;
            }
            return true;
        }
        //删除会话中指定成员
         bool remove(ChatSessionMember &csm) {
            try {
                odb::transaction trans(_db->begin());
                typedef odb::query<ChatSessionMember> query;
                typedef odb::result<ChatSessionMember> result;
                _db->erase_query<ChatSessionMember>(query::session_id == csm.session_id() &&
                    query::user_id == csm.user_id());
                trans.commit();
            }catch (std::exception &e) {
                LOG_ERROR("删除单会话成员失败 {}-{}:{}!", 
                    csm.session_id(), csm.user_id(), e.what());
                return false;
            }
            return true;
        }
        //删除会话中所有成员信息
        //删除会话的所有成员信息
        bool remove(const std::string &ssid) {
            try {
                odb::transaction trans(_db->begin());
                typedef odb::query<ChatSessionMember> query;
                typedef odb::result<ChatSessionMember> result;
                _db->erase_query<ChatSessionMember>(query::session_id == ssid);
                trans.commit();
            }catch (std::exception &e) {
                LOG_ERROR("删除会话所有成员失败 {}:{}!", ssid, e.what());
                return false;
            }
            return true;
        }
        //获取所有成员信息
        std::vector<std::string> members(const std::string &ssid) {
            std::vector<std::string> res;
            try {
                odb::transaction trans(_db->begin());
                typedef odb::query<ChatSessionMember> query;
                //result 模版类,专门用于存储从数据库中返回的多个对象,提供了迭代器方便查询
                typedef odb::result<ChatSessionMember> result;
                result r(_db->query<ChatSessionMember>(query::session_id == ssid));
                for (result::iterator i(r.begin()); i != r.end(); ++i) {
                    res.push_back(i->user_id());
                }
                trans.commit();
            }catch (std::exception &e) {
                LOG_ERROR("获取会话成员失败:{}-{}!", ssid, e.what());
            }
            return res;
        }

    private:
        std::shared_ptr<odb::core::database> _db; 

    };
}

业务逻辑实现

  • 获取请求信息:从请求中提取关键信息(请求ID、用户ID、聊天会话ID等)
  • 用户服务调用:通过RPC调用获取目标用户信息
  • 消息构建:构建消息对象并从数据库获取目标用户
  • 消息发布:将消息发布到消息队列以便传递给目标用户
  • 响应构造:构造响应,包括消息和目标用户信息,并返回给客户端

其他搭建RPC与前面业务逻辑类似

void GetTransmitTarget(google::protobuf::RpcController* controller,
                       const ::mag::NewMessageReq* request,
                       ::mag::GetTransmitTargetRsp* response,
                       ::google::protobuf::Closure* done) override{
                        //RPC调用后释放资源    
                        brpc::ClosureGuard rpc_guard(done);
                        //错误处理
                        auto err_response = [this, response](const std::string &rid, const std::string &errmsg) -> void {
                        response->set_request_id(rid);
                        response->set_success(false);
                        response->set_errmsg(errmsg);
                        return;
                    };

                    //请求中获取信息
                    std::string rid = request->request_id();
                    std::string uid = request->user_id();
                    std::string chat_ssid = request->chat_session_id();
                    const MessageContent &content = request->message();

                    //选择服务通道
                    auto channel = _mm_channels->choose(_user_service_name);
                    if (!channel) {
                        LOG_ERROR("{}-{} 没有可供访问的用户子服务节点!", rid, _user_service_name);
                        return err_response(rid, "没有可供访问的用户子服务节点!");
                    }                       

                    //RPC调用用户子服务获取用户信息
                    UserService_Stub stub(channel.get());
                    GetUserInfoReq req;
                    GetUserInfoRsp rsp;
                    req.set_request_id(rid);
                    req.set_user_id(uid);
                    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(chat_ssid);
                    message.set_timestamp(time(nullptr));
                    message.mutable_sender()->CopyFrom(rsp.user_info());
                    message.mutable_message()->CopyFrom(content);

                    //获取消息转发的目标用户列表,从mysql数据库中获取
                    auto target_list = _mysql_session_member_table->members(chat_ssid);

                    //发布消息到消息队列
                    bool ret = _mq_client->publish(_exchange_name, message.SerializeAsString(), _routing_key);
                    if (ret == false) {
                        LOG_ERROR("{} - 持久化消息发布失败:{}!", request->request_id(), cntl.ErrorText());
                        return err_response(request->request_id(), "持久化消息发布失败:!");
                    }

                    //组织成功响应
                    response->set_request_id(rid);
                    response->set_success(true);
                    response->mutable_message()->CopyFrom(message);
                    //将目标用户的ID列表添加到响应中,表示消息需要发送给哪些用户
                    for (const auto &id : target_list) {
                        response->add_target_id_list(id);
                    }

        }

功能测试

数据管理测试

数据插入测试

void append_test(mag::ChatSessionMemeberTable &tb) {
    mag::ChatSessionMember csm1("会话ID1", "用户ID1");
    tb.append(csm1);
    mag::ChatSessionMember csm2("会话ID1", "用户ID2");
    tb.append(csm2);
    mag::ChatSessionMember csm3("会话ID2", "用户ID3");
    tb.append(csm3);
}

批量插入测试

void multi_append_test(mag::ChatSessionMemeberTable &tb) {
    mag::ChatSessionMember csm1("会话ID3", "用户ID1");
    mag::ChatSessionMember csm2("会话ID3", "用户ID2");
    mag::ChatSessionMember csm3("会话ID3", "用户ID3");
    std::vector<mag::ChatSessionMember> list = {csm1, csm2, csm3};
    tb.append(list);
}

移除测试

void remove_test(mag::ChatSessionMemeberTable &tb){
    mag::ChatSessionMember csm3("会话ID2", "用户ID3");
    tb.remove(csm3);
}

获取指定成员的所有信息

void ss_members(mag::ChatSessionMemeberTable &tb){
    auto res = tb.members("会话ID1");
    for(auto &id : res){
        std::cout<< id <<std::endl;
    }
}

移除所有ID3的信息

void remove_all(mag::ChatSessionMemeberTable &tb) {
    tb.remove("会话ID3");
}

整体测试

用户客户端增加信息测试

#include "etcd.hpp"
#include "channel.hpp"
#include "utils.hpp"
#include <gflags/gflags.h>
#include <gtest/gtest.h>
#include <thread>
#include "user.pb.h"
#include "base.pb.h"

DEFINE_bool(run_mode, false, "程序的运行模式,false-调试; true-发布;");
DEFINE_string(log_file, "", "发布模式下,用于指定日志的输出文件");
DEFINE_int32(log_level, 0, "发布模式下,用于指定日志输出等级");

DEFINE_string(etcd_host, "http://127.0.0.1:2379", "服务注册中心地址");
DEFINE_string(base_service, "/service", "服务监控根目录");
DEFINE_string(user_service, "/service/user_service", "服务监控根目录");

mag::ServiceManager::ptr user_channels;

void reg_user(const std::string &nickname, const std::string &pswd){
    //获取信道
    auto channel = user_channels->choose(FLAGS_user_service);
    ASSERT_TRUE(channel);
    
    //构建用户注册请求
    mag::UserRegisterReq req;
    req.set_request_id(mag::uuid());
    req.set_nickname(nickname);
    req.set_password(pswd);

    //发送注册请求并接受响应
    mag::UserRegisterRsp rsp;
    brpc::Controller cntl;
    mag::UserService_Stub stub(channel.get());
    stub.UserRegister(&cntl, &req, &rsp, nullptr);

    // 断言请求成功
    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());

}

void set_user_avatar(const std::string &uid, const std::string &avatar){
    //获取用户服务通信信道
    auto channel = user_channels->choose(FLAGS_user_service);
    ASSERT_TRUE(channel);

    //构建用户头像请求
    mag::SetUserAvatarReq req;
    req.set_request_id(mag::uuid());
    req.set_user_id(uid);
    req.set_session_id("测试登录会话ID");
    req.set_avatar(avatar);

    //发送设置头像请求并接收响应
    mag::SetUserAvatarRsp rsp;
    brpc::Controller cntl;
    mag::UserService_Stub stub(channel.get());
    stub.SetUserAvatar(&cntl, &req, &rsp, nullptr);

    // 断言请求成功
    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());
}

int main(int argc, char *argv[])
{
    // 解析命令行参数
    google::ParseCommandLineFlags(&argc, &argv, true);
    
    // 初始化日志
    init_logger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);

    // 创建 ServiceManager 实例并声明用户服务
    user_channels = std::make_shared<mag::ServiceManager>();
    user_channels->declared(FLAGS_user_service);

    // 绑定服务上线和下线的回调
    auto put_cb = std::bind(&mag::ServiceManager::onServiceOnline, user_channels.get(), std::placeholders::_1, std::placeholders::_2);
    auto del_cb = std::bind(&mag::ServiceManager::onServiceOffline, user_channels.get(), std::placeholders::_1, std::placeholders::_2);
    
    // 构造服务发现客户端
    mag::Discovery::ptr dclient = std::make_shared<mag::Discovery>(FLAGS_etcd_host, FLAGS_base_service, put_cb, del_cb);
    
    // 注册用户测试
    // reg_user("小猪佩奇", "123456");
    // reg_user("小猪乔治", "123456");

    // 设置用户头像
    set_user_avatar("8d25-14d9ff25-0000", "猪爸爸头像数据");
    set_user_avatar("0b24-e341f8f9-0001", "猪妈妈头像数据");
    
}

发送消息到消息队列

root@hcss-ecs-b4a9:/home/chatServer/chatServer/src/server/transmite/build# ./transmite_client
[default-logger][16:26:31][1242866][debug   ][/home/chatServer/chatServer/src/server/transmite/../common/channel.hpp:96] /service/file_service-127.0.0.1:10002 服务上线了,但是当前并不关心!
[default-logger][16:26:31][1242866][debug   ][/home/chatServer/chatServer/src/server/transmite/../common/channel.hpp:96] /service-127.0.0.1:9090 服务上线了,但是当前并不关心!
[default-logger][16:26:31][1242866][debug   ][/home/chatServer/chatServer/src/server/transmite/../common/channel.hpp:113] /service/transmite_service-127.0.0.1:10004 服务上线新节点,进行添加管理!
[default-logger][16:26:31][1242866][debug   ][/home/chatServer/chatServer/src/server/transmite/../common/channel.hpp:96] /service/user_service-127.0.0.1:10003 服务上线了,但是当前并不关心!
[default-logger][16:26:31][1242866][info    ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:25] 尝试发送字符串消息。用户ID: 8d25-14d9ff25-0000, 会话ID: 会话ID1, 消息内容: 吃饭了吗?
[default-logger][16:26:31][1242866][debug   ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:32] 成功获取服务通信通道,服务: /service/transmite_service
[default-logger][16:26:31][1242866][debug   ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:47] 请求已构建:request_id=d42c-31e9e768-0000, user_id=8d25-14d9ff25-0000, chat_session_id=会话ID1, message_type=STRING, content=吃饭了吗?
[default-logger][16:26:32][1242866][info    ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:58] RPC调用成功,响应成功:true
[default-logger][16:26:32][1242866][info    ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:25] 尝试发送字符串消息。用户ID: 0b24-e341f8f9-0001, 会话ID: 会话ID1, 消息内容: 吃的盖浇饭!!
[default-logger][16:26:32][1242866][debug   ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:32] 成功获取服务通信通道,服务: /service/transmite_service
[default-logger][16:26:32][1242866][debug   ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:47] 请求已构建:request_id=a9b2-f32b92b8-0001, user_id=0b24-e341f8f9-0001, chat_session_id=会话ID1, message_type=STRING, content=吃的盖浇饭!!
[default-logger][16:26:32][1242866][info    ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:58] RPC调用成功,响应成功:true
//
///发送字符串消息
//
void string_message(const std::string &uid, const std::string &sid, const std::string &msg)
{
    LOG_INFO("尝试发送字符串消息。用户ID: {}, 会话ID: {}, 消息内容: {}", uid, sid, msg);

    auto channel = sm->choose(FLAGS_transmite_service);
    if (!channel) {
        std::cout << "获取通信信道失败!" << std::endl;
        return;
    }
    LOG_DEBUG("成功获取服务通信通道,服务: {}", FLAGS_transmite_service);


    //构建RPC stub
    mag::MsgTransmitService_Stub stub(channel.get());

    //构建请求和接收响应
    mag::NewMessageReq req;
    mag::GetTransmitTargetRsp rsp;
    req.set_request_id(mag::uuid());
    req.set_user_id(uid);
    req.set_chat_session_id(sid);
    req.mutable_message()->set_message_type(mag::MessageType::STRING);
    req.mutable_message()->mutable_string_message()->set_content(msg);

    LOG_DEBUG("请求已构建:request_id={}, user_id={}, chat_session_id={}, message_type=STRING, content={}",
              req.request_id(), req.user_id(), req.chat_session_id(), req.message().string_message().content());


    //发送请求并处理响应
    brpc::Controller cntl;
    stub.GetTransmitTarget(&cntl, &req, &rsp, nullptr);

    if (cntl.Failed()) {
        LOG_ERROR("RPC调用失败: {}", cntl.ErrorText());
    } else {
        LOG_INFO("RPC调用成功,响应成功:{}", rsp.success() ? "true" : "false");
    }

    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());
}

发送图片消息

[default-logger][16:50:40][1244626][info    ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:66] 尝试发送图片消息。用户ID: 8d25-14d9ff25-0000, 会话ID: 会话ID1, 图片内容: 可爱表情图片数据
[default-logger][16:50:40][1244626][debug   ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:73] 成功获取服务通信通道,服务: /service/transmite_service
[default-logger][16:50:40][1244626][debug   ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:84] 请求已构建:request_id=67a4-cbc665a7-0002, user_id=8d25-14d9ff25-0000, chat_session_id=会话ID1, message_type=IMAGE, image_content=可爱表情图片数据
[default-logger][16:50:40][1244626][info    ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:93] RPC调用成功,响应成功:true
///
///发送图片消息
//
void image_message(const std::string &uid, const std::string &sid, const std::string &msg) {
    LOG_INFO("尝试发送图片消息。用户ID: {}, 会话ID: {}, 图片内容: {}", uid, sid, msg);

    auto channel = sm->choose(FLAGS_transmite_service);
    if (!channel) {
        std::cout << "获取通信信道失败!" << std::endl;
        return;
    }
    LOG_DEBUG("成功获取服务通信通道,服务: {}", FLAGS_transmite_service);

    mag::MsgTransmitService_Stub stub(channel.get());
    mag::NewMessageReq req;
    mag::GetTransmitTargetRsp rsp;
    req.set_request_id(mag::uuid());
    req.set_user_id(uid);
    req.set_chat_session_id(sid);
    req.mutable_message()->set_message_type(mag::MessageType::IMAGE);
    req.mutable_message()->mutable_image_message()->set_image_content(msg);

    LOG_DEBUG("请求已构建:request_id={}, user_id={}, chat_session_id={}, message_type=IMAGE, image_content={}",
              req.request_id(), req.user_id(), req.chat_session_id(), req.message().image_message().image_content());

    brpc::Controller cntl;
    stub.GetTransmitTarget(&cntl, &req, &rsp, nullptr);

    if (cntl.Failed()) {
        LOG_ERROR("RPC调用失败: {}", cntl.ErrorText());
    } else {
        LOG_INFO("RPC调用成功,响应成功:{}", rsp.success() ? "true" : "false");
    }

    ASSERT_FALSE(cntl.Failed());
    ASS

发送语音消息

[default-logger][16:50:40][1244626][info    ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:104] 尝试发送语音消息。用户ID: 8d25-14d9ff25-0000, 会话ID: 会话ID1, 语音文件内容: 动听猪叫声数据
[default-logger][16:50:40][1244626][debug   ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:111] 成功获取服务通信通道,服务: /service/transmite_service
[default-logger][16:50:40][1244626][debug   ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:122] 请求已构建:request_id=b704-a3615a54-0003, user_id=8d25-14d9ff25-0000, chat_session_id=会话ID1, message_type=SPEECH, file_contents=动听猪叫声数据
[default-logger][16:50:40][1244626][info    ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:131] RPC调用成功,响应成功:true
///
///发送语音消息
//
void speech_message(const std::string &uid, const std::string &sid, const std::string &msg) {
    LOG_INFO("尝试发送语音消息。用户ID: {}, 会话ID: {}, 语音文件内容: {}", uid, sid, msg);

    auto channel = sm->choose(FLAGS_transmite_service);
    if (!channel) {
        std::cout << "获取通信信道失败!" << std::endl;
        return;
    }
    LOG_DEBUG("成功获取服务通信通道,服务: {}", FLAGS_transmite_service);

    mag::MsgTransmitService_Stub stub(channel.get());
    mag::NewMessageReq req;
    mag::GetTransmitTargetRsp rsp;
    req.set_request_id(mag::uuid());
    req.set_user_id(uid);
    req.set_chat_session_id(sid);
    req.mutable_message()->set_message_type(mag::MessageType::SPEECH);
    req.mutable_message()->mutable_speech_message()->set_file_contents(msg);

    LOG_DEBUG("请求已构建:request_id={}, user_id={}, chat_session_id={}, message_type=SPEECH, file_contents={}",
              req.request_id(), req.user_id(), req.chat_session_id(), req.message().speech_message().file_contents());

    brpc::Controller cntl;
    stub.GetTransmitTarget(&cntl, &req, &rsp, nullptr);

    if (cntl.Failed()) {
        LOG_ERROR("RPC调用失败: {}", cntl.ErrorText());
    } else {
        LOG_INFO("RPC调用成功,响应成功:{}", rsp.success() ? "true" : "false");
    }

    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());
}

发送文件消息

[default-logger][16:50:40][1244626][info    ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:143] 尝试发送文件消息。用户ID: 8d25-14d9ff25-0000, 会话ID: 98d4-87a1ebfd-0003, 文件名: 猪爸爸的文件名称, 文件大小: 24
[default-logger][16:50:40][1244626][debug   ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:150] 成功获取服务通信通道,服务: /service/transmite_service
[default-logger][16:50:40][1244626][debug   ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:163] 请求已构建:request_id=24f5-4b4e0e57-0004, user_id=8d25-14d9ff25-0000, chat_session_id=98d4-87a1ebfd-0003, message_type=FILE, filename=猪爸爸的文件名称, file_size=24
[default-logger][16:50:40][1244626][info    ][/home/chatServer/chatServer/src/server/transmite/test/transmite_client.cc:172] RPC调用成功,响应成功:true
///
///发送文件消息
//
void file_message(const std::string &uid, const std::string &sid, 
    const std::string &filename, const std::string &content) {
    LOG_INFO("尝试发送文件消息。用户ID: {}, 会话ID: {}, 文件名: {}, 文件大小: {}", uid, sid, filename, content.size());

    auto channel = sm->choose(FLAGS_transmite_service);
    if (!channel) {
        std::cout << "获取通信信道失败!" << std::endl;
        return;
    }
    LOG_DEBUG("成功获取服务通信通道,服务: {}", FLAGS_transmite_service);

    mag::MsgTransmitService_Stub stub(channel.get());
    mag::NewMessageReq req;
    mag::GetTransmitTargetRsp rsp;
    req.set_request_id(mag::uuid());
    req.set_user_id(uid);
    req.set_chat_session_id(sid);
    req.mutable_message()->set_message_type(mag::MessageType::FILE);
    req.mutable_message()->mutable_file_message()->set_file_contents(content);
    req.mutable_message()->mutable_file_message()->set_file_name(filename);
    req.mutable_message()->mutable_file_message()->set_file_size(content.size());

    LOG_DEBUG("请求已构建:request_id={}, user_id={}, chat_session_id={}, message_type=FILE, filename={}, file_size={}",
              req.request_id(), req.user_id(), req.chat_session_id(), filename, content.size());

    brpc::Controller cntl;
    stub.GetTransmitTarget(&cntl, &req, &rsp, nullptr);

    if (cntl.Failed()) {
        LOG_ERROR("RPC调用失败: {}", cntl.ErrorText());
    } else {
        LOG_INFO("RPC调用成功,响应成功:{}", rsp.success() ? "true" : "false");
    }

    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值