[微服务即时通讯系统]用户管理服务的实现与测试
本文介绍了用户管理子服务的设计与实现。该服务提供用户注册、登录、信息管理等功能,采用模块化架构,包括参数解析、日志记录、服务注册、数据库操作等模块。测试结果显示用户注册功能运行正常,数据能正确存入MySQL和Elasticsearch。系统通过RPC实现服务间通信,支持用户名/手机号两种登录方式,并整合短信验证码服务,实现了完整的用户管理功能。
·
本专栏内容为:项目专栏
💓博主csdn个人主页:小小unicorn
⏩专栏分类:微服务即时通讯系统
🚚代码仓库:小小unicorn的代码仓库🚚
🌹🌹🌹关注我带你学习编程知识
功能设计
用户管理子服务,主要用于管理用户的数据,以及关于用户信息的各项操作,因此在上述项目功能中,用户子服务需要提供以下接口:
- 用户注册:用户输入用户名(昵称),以及密码进行用户名的注册
- 用户登录:用户通过用户名和密码进行登录
- 短信验证码获取:当用户通过手机号注册或登录的时候,需要获取短信验证码
- 手机号注册:用户输入手机号和短信验证码进行手机号的用户注册
- 手机号登录:用户输入手机号和短信验证码进行手机号的用户登录
- 用户信息获取:当用户登录之后,获取个人信息进行展示
- 头像修改:设置用户头像
- 昵称修改:设置用户昵称
- 签名修改:设置用户签名
- 手机号修改:修改用户的绑定手机号
模块划分
- 参数/配置文件解析模块:基于 gflags 框架直接使用进行参数/配置文件解析。
- 日志模块:基于 spdlog 框架封装的模块直接使用进行日志输出。
- 服务注册模块:基于 etcd 框架封装的注册模块直接使用,进行聊天消息存储子服
务的注册。 - 数据库数据操作模块:基于 odb-mysql 数据管理封装的模块,实现关系型数据库
中数据的操作。
a. 用户进行用户名/手机号注册的时候在数据库中进行新增信息
b. 用户修改个人信息的时候修改数据库中的记录
c. 用户登录的时候,在数据库中进行用户名密码的验证 - redis 客户端模块:基于 redis++封装的客户端进行内存数据库数据操作
a. 当用户登录的时候需要为用户创建登录会话,会话信息保存在 redis 服务器中。
b. 当用户手机号进行获取/验证验证码的时候,验证码与对应信息保存在 redis 服务器中 - rpc 服务模块:基于 brpc 框架搭建 rpc 服务器。
- rpc 服务发现与调用模块:基于 etcd 框架与 brpc 框架封装的服务发现与调用模块,
a. 连接文件管理子服务:获取用户信息的时候,用户头像是通过文件的形式存
储在文件子服务中的。
b. 连接消息管理子服务:在打开聊天会话的时候,需要获取最近的一条消息进
行展示。 - ES 客户端模块:基于 elasticsearch 框架实现访问客户端,向 ES 服务器中存储用户简息,以便于用户的搜索
- 短信平台客户端模块:基于短信平台 SDK 封装使用,用于向用户手机号发送指定验证码。
功能模块示意图:

数据管理
关系数据库数据管理:
在关系型数据库中,对于用户子服务来说,总体只进行了一个信息数据的存储与管理,那就是用户信息数据,因此只需要构建好用户信息表,提供好对应的操作即可可。
用户数据表:
包含字段:
- 主键 ID:自动生成
- 用户 ID:用户唯一标识
- 用户昵称:用户的昵称,也可用作登录用户名
- 用户签名:用户对自己的描述吧…
- 登录密码:登录验证
- 绑定手机号:用户可以绑定手机号,绑定后可以通过手机号登录、
- 用户头像文件 ID:头像文件存储的唯一标识,具体头像数据存储在文件子服务
器中。
提供的操作: - 通过昵称获取用户信息
- 通过手机号获取用户信息
- 通过用户 ID 获取用信息
- 新增用户
- 更新用户信息
用户管理测试
我们根据模块进行测试,先测试我们的用户注册功能:

insert into user values(null,'用户1','小猪佩奇','这是一只小猪','123456','手机号1','小猪头像1');
insert into user values(null,'用户2','小猪乔治','这是一只小小猪','123456','手机号2','小猪头像2');

user_client.cc
#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", "服务监控根目录");
bite_im::ServiceManager::ptr _user_channels; // 定义智能指针
bite_im::UserInfo user_info; // 数据定义
std::string login_ssid;
std::string new_nickname = "亲爱的猪妈妈";
TEST(用户子服务测试, 用户注册测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
user_info.set_nickname("猪爸爸");
bite_im::UserRegisterReq req;
req.set_request_id(bite_im::uuid());
req.set_nickname(user_info.nickname());
req.set_password("123456");
bite_im::UserRegisterRsp rsp;
brpc::Controller cntl;
// rpc调用
bite_im::UserService_Stub stub(channel.get());
stub.UserRegister(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
}
int main(int argc, char *argv[])
{
testing::InitGoogleTest(&argc, argv);
google::ParseCommandLineFlags(&argc, &argv, true);
bite_im::init_logger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);
// 1. 先构造Rpc信道管理对象
_user_channels = std::make_shared<bite_im::ServiceManager>(); // 构造
_user_channels->declared(FLAGS_user_service);
auto put_cb = std::bind(&bite_im::ServiceManager::onServiceOnline, _user_channels.get(), std::placeholders::_1, std::placeholders::_2);
auto del_cb = std::bind(&bite_im::ServiceManager::onServiceOffline, _user_channels.get(), std::placeholders::_1, std::placeholders::_2);
// 2. 构造服务发现对象
bite_im::Discovery::ptr dclient = std::make_shared<bite_im::Discovery>(FLAGS_etcd_host, FLAGS_base_service, put_cb, del_cb);
// user_info.set_nickname("猪妈妈");
// user_info.set_user_id("1d56-513d8e49-0002");
// user_info.set_description("这是一个美丽的猪妈妈");
// user_info.set_phone("15929917272");
// user_info.set_avatar("猪妈妈头像数据");
LOG_DEBUG("开始测试!");
return RUN_ALL_TESTS();
}
编译我们的程序:
编译成功之后,打开我们的文件服务,以及用户服务,测试客户端:



在es这边我们也是可以查新到数据的!
这里说明我们的用户注册模块式没问题的!
接下来测试用户登录,获取用户信息,设置用户头像,设置用户签名以及设置用户昵称昵称:
```user_client.cc``
#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", "服务监控根目录");
bite_im::ServiceManager::ptr _user_channels; // 定义智能指针
bite_im::UserInfo user_info; // 数据定义
std::string login_ssid;
std::string new_nickname = "亲爱的猪妈妈";
//这里我们数据已经添加好了,直接注释掉即可
// TEST(用户子服务测试, 用户注册测试)
// {
// auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
// ASSERT_TRUE(channel);
// user_info.set_nickname("猪妈妈");
// bite_im::UserRegisterReq req;
// req.set_request_id(bite_im::uuid());
// req.set_nickname(user_info.nickname());
// req.set_password("123456");
// bite_im::UserRegisterRsp rsp;
// brpc::Controller cntl;
// // rpc调用
// bite_im::UserService_Stub stub(channel.get());
// stub.UserRegister(&cntl, &req, &rsp, nullptr);
// ASSERT_FALSE(cntl.Failed());
// ASSERT_TRUE(rsp.success());
// }
TEST(用户子服务测试, 用户登录测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::UserLoginReq req;
req.set_request_id(bite_im::uuid());
req.set_nickname("猪妈妈");
req.set_password("123456");
bite_im::UserLoginRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.UserLogin(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
login_ssid = rsp.login_session_id();
}
TEST(用户子服务测试, 用户头像设置测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::SetUserAvatarReq req;
req.set_request_id(bite_im::uuid());
req.set_user_id(user_info.user_id());
req.set_session_id(login_ssid);
req.set_avatar(user_info.avatar());
bite_im::SetUserAvatarRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.SetUserAvatar(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
}
TEST(用户子服务测试, 用户签名设置测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::SetUserDescriptionReq req;
req.set_request_id(bite_im::uuid());
req.set_user_id(user_info.user_id());
req.set_session_id(login_ssid);
req.set_description(user_info.description());
bite_im::SetUserDescriptionRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.SetUserDescription(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
}
TEST(用户子服务测试, 用户昵称设置测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::SetUserNicknameReq req;
req.set_request_id(bite_im::uuid());
req.set_user_id(user_info.user_id());
req.set_session_id(login_ssid);
req.set_nickname(new_nickname);
bite_im::SetUserNicknameRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.SetUserNickname(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
}
TEST(用户子服务测试, 用户信息获取测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::GetUserInfoReq req;
req.set_request_id(bite_im::uuid());
req.set_user_id(user_info.user_id());
req.set_session_id(login_ssid);
bite_im::GetUserInfoRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.GetUserInfo(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
ASSERT_EQ(user_info.user_id(), rsp.user_info().user_id());
ASSERT_EQ(new_nickname, rsp.user_info().nickname());
ASSERT_EQ(user_info.description(), rsp.user_info().description());
ASSERT_EQ("", rsp.user_info().phone());
ASSERT_EQ(user_info.avatar(), rsp.user_info().avatar());
}
int main(int argc, char *argv[])
{
google::ParseCommandLineFlags(&argc, &argv, true);
bite_im::init_logger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);
// 1. 先构造Rpc信道管理对象
_user_channels = std::make_shared<bite_im::ServiceManager>(); // 构造
_user_channels->declared(FLAGS_user_service);
auto put_cb = std::bind(&bite_im::ServiceManager::onServiceOnline, _user_channels.get(), std::placeholders::_1, std::placeholders::_2);
auto del_cb = std::bind(&bite_im::ServiceManager::onServiceOffline, _user_channels.get(), std::placeholders::_1, std::placeholders::_2);
// 2. 构造服务发现对象
bite_im::Discovery::ptr dclient = std::make_shared<bite_im::Discovery>(FLAGS_etcd_host, FLAGS_base_service, put_cb, del_cb);
user_info.set_nickname("猪妈妈");
user_info.set_user_id("1882-74802db0-0001");
user_info.set_description("这是一个美丽的猪妈妈");
user_info.set_phone("15929917272");
user_info.set_avatar("猪妈妈头像数据");
testing::InitGoogleTest(&argc, argv);
LOG_DEBUG("开始测试!");
return RUN_ALL_TESTS();
}
编译运行:




接下来测试批量用户信息的获取测试:user_client.cc
#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", "服务监控根目录");
bite_im::ServiceManager::ptr _user_channels; // 定义智能指针
bite_im::UserInfo user_info; // 数据定义
std::string login_ssid;
std::string new_nickname = "亲爱的猪妈妈";
// TEST(用户子服务测试, 用户注册测试)
// {
// auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
// ASSERT_TRUE(channel);
// user_info.set_nickname("猪妈妈");
// bite_im::UserRegisterReq req;
// req.set_request_id(bite_im::uuid());
// req.set_nickname(user_info.nickname());
// req.set_password("123456");
// bite_im::UserRegisterRsp rsp;
// brpc::Controller cntl;
// // rpc调用
// bite_im::UserService_Stub stub(channel.get());
// stub.UserRegister(&cntl, &req, &rsp, nullptr);
// ASSERT_FALSE(cntl.Failed());
// ASSERT_TRUE(rsp.success());
// }
TEST(用户子服务测试, 用户登录测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::UserLoginReq req;
req.set_request_id(bite_im::uuid());
req.set_nickname("亲爱的猪妈妈");
req.set_password("123456");
bite_im::UserLoginRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.UserLogin(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
login_ssid = rsp.login_session_id();
}
TEST(用户子服务测试, 用户头像设置测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::SetUserAvatarReq req;
req.set_request_id(bite_im::uuid());
req.set_user_id(user_info.user_id());
req.set_session_id(login_ssid);
req.set_avatar(user_info.avatar());
bite_im::SetUserAvatarRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.SetUserAvatar(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
}
TEST(用户子服务测试, 用户签名设置测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::SetUserDescriptionReq req;
req.set_request_id(bite_im::uuid());
req.set_user_id(user_info.user_id());
req.set_session_id(login_ssid);
req.set_description(user_info.description());
bite_im::SetUserDescriptionRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.SetUserDescription(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
}
TEST(用户子服务测试, 用户昵称设置测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::SetUserNicknameReq req;
req.set_request_id(bite_im::uuid());
req.set_user_id(user_info.user_id());
req.set_session_id(login_ssid);
req.set_nickname(new_nickname);
bite_im::SetUserNicknameRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.SetUserNickname(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
}
TEST(用户子服务测试, 用户信息获取测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::GetUserInfoReq req;
req.set_request_id(bite_im::uuid());
req.set_user_id(user_info.user_id());
req.set_session_id(login_ssid);
bite_im::GetUserInfoRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.GetUserInfo(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
ASSERT_EQ(user_info.user_id(), rsp.user_info().user_id());
ASSERT_EQ(new_nickname, rsp.user_info().nickname());
ASSERT_EQ(user_info.description(), rsp.user_info().description());
ASSERT_EQ("", rsp.user_info().phone());
ASSERT_EQ(user_info.avatar(), rsp.user_info().avatar());
}
// 设置用户头像接口
void set_user_avatar(const std::string &uid, const std::string &avatar)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::SetUserAvatarReq req;
req.set_request_id(bite_im::uuid());
req.set_user_id(uid);
req.set_session_id(login_ssid);
req.set_avatar(avatar);
bite_im::SetUserAvatarRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.SetUserAvatar(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
}
TEST(用户子服务测试, 批量用户信息获取测试)
{
set_user_avatar("用户1", "小猪佩奇的头像数据");
set_user_avatar("用户2", "小猪乔治的头像数据");
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::GetMultiUserInfoReq req;
req.set_request_id(bite_im::uuid());
req.add_users_id("用户1");
req.add_users_id("用户2");
req.add_users_id("a83b-2d93ce70-0000");
bite_im::GetMultiUserInfoRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.GetMultiUserInfo(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
auto users_map = rsp.mutable_users_info();
bite_im::UserInfo fuser = (*users_map)["a83b-2d93ce70-0000"];
ASSERT_EQ(fuser.user_id(), "a83b-2d93ce70-0000");
ASSERT_EQ(fuser.nickname(), "猪爸爸");
ASSERT_EQ(fuser.description(), "");
ASSERT_EQ(fuser.phone(), "");
ASSERT_EQ(fuser.avatar(), "");
bite_im::UserInfo puser = (*users_map)["用户1"];
ASSERT_EQ(puser.user_id(), "用户1");
ASSERT_EQ(puser.nickname(), "小猪佩奇");
ASSERT_EQ(puser.description(), "这是一只小猪");
ASSERT_EQ(puser.phone(), "手机号1");
ASSERT_EQ(puser.avatar(), "小猪佩奇的头像数据");
bite_im::UserInfo quser = (*users_map)["用户2"];
ASSERT_EQ(quser.user_id(), "用户2");
ASSERT_EQ(quser.nickname(), "小猪乔治");
ASSERT_EQ(quser.description(), "这是一只小小猪");
ASSERT_EQ(quser.phone(), "手机号2");
ASSERT_EQ(quser.avatar(), "小猪乔治的头像数据");
}
int main(int argc, char *argv[])
{
google::ParseCommandLineFlags(&argc, &argv, true);
bite_im::init_logger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);
// 1. 先构造Rpc信道管理对象
_user_channels = std::make_shared<bite_im::ServiceManager>(); // 构造
_user_channels->declared(FLAGS_user_service);
auto put_cb = std::bind(&bite_im::ServiceManager::onServiceOnline, _user_channels.get(), std::placeholders::_1, std::placeholders::_2);
auto del_cb = std::bind(&bite_im::ServiceManager::onServiceOffline, _user_channels.get(), std::placeholders::_1, std::placeholders::_2);
// 2. 构造服务发现对象
bite_im::Discovery::ptr dclient = std::make_shared<bite_im::Discovery>(FLAGS_etcd_host, FLAGS_base_service, put_cb, del_cb);
user_info.set_nickname("亲爱的猪妈妈");
user_info.set_user_id("1882-74802db0-0001");
user_info.set_description("这是一个美丽的猪妈妈");
user_info.set_phone("15929917272");
user_info.set_avatar("猪妈妈头像数据");
testing::InitGoogleTest(&argc, argv);
LOG_DEBUG("开始测试!");
return RUN_ALL_TESTS();
}
编译运行:

接下来我们测试手机验证码的相关信息:user_client.cc
#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", "服务监控根目录");
bite_im::ServiceManager::ptr _user_channels; // 定义智能指针
bite_im::UserInfo user_info; // 数据定义
std::string login_ssid;
std::string new_nickname = "亲爱的猪妈妈";
// TEST(用户子服务测试, 用户注册测试)
// {
// auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
// ASSERT_TRUE(channel);
// user_info.set_nickname("猪妈妈");
// bite_im::UserRegisterReq req;
// req.set_request_id(bite_im::uuid());
// req.set_nickname(user_info.nickname());
// req.set_password("123456");
// bite_im::UserRegisterRsp rsp;
// brpc::Controller cntl;
// // rpc调用
// bite_im::UserService_Stub stub(channel.get());
// stub.UserRegister(&cntl, &req, &rsp, nullptr);
// ASSERT_FALSE(cntl.Failed());
// ASSERT_TRUE(rsp.success());
// }
TEST(用户子服务测试, 用户登录测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::UserLoginReq req;
req.set_request_id(bite_im::uuid());
req.set_nickname("亲爱的猪妈妈");
req.set_password("123456");
bite_im::UserLoginRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.UserLogin(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
login_ssid = rsp.login_session_id();
}
TEST(用户子服务测试, 用户头像设置测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::SetUserAvatarReq req;
req.set_request_id(bite_im::uuid());
req.set_user_id(user_info.user_id());
req.set_session_id(login_ssid);
req.set_avatar(user_info.avatar());
bite_im::SetUserAvatarRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.SetUserAvatar(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
}
TEST(用户子服务测试, 用户签名设置测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::SetUserDescriptionReq req;
req.set_request_id(bite_im::uuid());
req.set_user_id(user_info.user_id());
req.set_session_id(login_ssid);
req.set_description(user_info.description());
bite_im::SetUserDescriptionRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.SetUserDescription(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
}
TEST(用户子服务测试, 用户昵称设置测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::SetUserNicknameReq req;
req.set_request_id(bite_im::uuid());
req.set_user_id(user_info.user_id());
req.set_session_id(login_ssid);
req.set_nickname(new_nickname);
bite_im::SetUserNicknameRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.SetUserNickname(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
}
TEST(用户子服务测试, 用户信息获取测试)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::GetUserInfoReq req;
req.set_request_id(bite_im::uuid());
req.set_user_id(user_info.user_id());
req.set_session_id(login_ssid);
bite_im::GetUserInfoRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.GetUserInfo(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
ASSERT_EQ(user_info.user_id(), rsp.user_info().user_id());
ASSERT_EQ(new_nickname, rsp.user_info().nickname());
ASSERT_EQ(user_info.description(), rsp.user_info().description());
ASSERT_EQ("", rsp.user_info().phone());
ASSERT_EQ(user_info.avatar(), rsp.user_info().avatar());
}
// 设置用户头像接口
void set_user_avatar(const std::string &uid, const std::string &avatar)
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::SetUserAvatarReq req;
req.set_request_id(bite_im::uuid());
req.set_user_id(uid);
req.set_session_id(login_ssid);
req.set_avatar(avatar);
bite_im::SetUserAvatarRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.SetUserAvatar(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
}
TEST(用户子服务测试, 批量用户信息获取测试)
{
set_user_avatar("用户1", "小猪佩奇的头像数据");
set_user_avatar("用户2", "小猪乔治的头像数据");
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::GetMultiUserInfoReq req;
req.set_request_id(bite_im::uuid());
req.add_users_id("用户1");
req.add_users_id("用户2");
req.add_users_id("a83b-2d93ce70-0000");
bite_im::GetMultiUserInfoRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.GetMultiUserInfo(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
auto users_map = rsp.mutable_users_info();
bite_im::UserInfo fuser = (*users_map)["a83b-2d93ce70-0000"];
ASSERT_EQ(fuser.user_id(), "a83b-2d93ce70-0000");
ASSERT_EQ(fuser.nickname(), "猪爸爸");
ASSERT_EQ(fuser.description(), "");
ASSERT_EQ(fuser.phone(), "");
ASSERT_EQ(fuser.avatar(), "");
bite_im::UserInfo puser = (*users_map)["用户1"];
ASSERT_EQ(puser.user_id(), "用户1");
ASSERT_EQ(puser.nickname(), "小猪佩奇");
ASSERT_EQ(puser.description(), "这是一只小猪");
ASSERT_EQ(puser.phone(), "手机号1");
ASSERT_EQ(puser.avatar(), "小猪佩奇的头像数据");
bite_im::UserInfo quser = (*users_map)["用户2"];
ASSERT_EQ(quser.user_id(), "用户2");
ASSERT_EQ(quser.nickname(), "小猪乔治");
ASSERT_EQ(quser.description(), "这是一只小小猪");
ASSERT_EQ(quser.phone(), "手机号2");
ASSERT_EQ(quser.avatar(), "小猪乔治的头像数据");
}
// 获取验证码接口
std::string code_id;
void get_code()
{
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::PhoneVerifyCodeReq req;
req.set_request_id(bite_im::uuid());
req.set_phone_number(user_info.phone());
bite_im::PhoneVerifyCodeRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.GetPhoneVerifyCode(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
code_id = rsp.verify_code_id();
}
TEST(用户子服务测试, 手机号注册)
{
get_code();
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::PhoneRegisterReq req;
req.set_request_id(bite_im::uuid());
req.set_phone_number(user_info.phone());
req.set_verify_code_id(code_id);
std::cout << "手机号注册,输入验证码:" << std::endl;
std::string code;
std::cin >> code;
req.set_verify_code(code);
bite_im::PhoneRegisterRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.PhoneRegister(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
}
TEST(用户子服务测试, 手机号登录)
{
std::this_thread::sleep_for(std::chrono::seconds(3)); // 睡上3秒钟
get_code();
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::PhoneLoginReq req;
req.set_request_id(bite_im::uuid());
req.set_phone_number(user_info.phone());
req.set_verify_code_id(code_id);
std::cout << "手机号登录,输入验证码:" << std::endl;
std::string code;
std::cin >> code;
req.set_verify_code(code);
bite_im::PhoneLoginRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.PhoneLogin(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
std::cout << "手机登录会话ID:" << rsp.login_session_id() << std::endl;
}
TEST(用户子服务测试, 手机号设置)
{
std::this_thread::sleep_for(std::chrono::seconds(10));
get_code();
auto channel = _user_channels->choose(FLAGS_user_service); // 获取通信信道
ASSERT_TRUE(channel);
bite_im::SetUserPhoneNumberReq req;
req.set_request_id(bite_im::uuid());
std::cout << "手机号设置时,输入用户ID:" << std::endl;
std::string user_id;
std::cin >> user_id;
req.set_user_id(user_id);
req.set_phone_number("18888888888");
req.set_phone_verify_code_id(code_id);
std::cout << "手机号设置时,输入验证码:" << std::endl;
std::string code;
std::cin >> code;
req.set_phone_verify_code(code);
bite_im::SetUserPhoneNumberRsp rsp;
brpc::Controller cntl;
bite_im::UserService_Stub stub(channel.get());
stub.SetUserPhoneNumber(&cntl, &req, &rsp, nullptr);
ASSERT_FALSE(cntl.Failed());
ASSERT_TRUE(rsp.success());
}
int main(int argc, char *argv[])
{
google::ParseCommandLineFlags(&argc, &argv, true);
bite_im::init_logger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);
// 1. 先构造Rpc信道管理对象
_user_channels = std::make_shared<bite_im::ServiceManager>(); // 构造
_user_channels->declared(FLAGS_user_service);
auto put_cb = std::bind(&bite_im::ServiceManager::onServiceOnline, _user_channels.get(), std::placeholders::_1, std::placeholders::_2);
auto del_cb = std::bind(&bite_im::ServiceManager::onServiceOffline, _user_channels.get(), std::placeholders::_1, std::placeholders::_2);
// 2. 构造服务发现对象
bite_im::Discovery::ptr dclient = std::make_shared<bite_im::Discovery>(FLAGS_etcd_host, FLAGS_base_service, put_cb, del_cb);
user_info.set_nickname("猪妈妈");
user_info.set_user_id("1882-74802db0-0001");
user_info.set_description("这是一个美丽的猪妈妈");
user_info.set_phone("15929917272");
user_info.set_avatar("猪妈妈头像数据");
testing::InitGoogleTest(&argc, argv);
LOG_DEBUG("开始测试!");
return RUN_ALL_TESTS();
}
编译运行:
客户端:



更多推荐
所有评论(0)