学习brpc:echo服务

2024-04-07 12:44
文章标签 服务 学习 echo brpc

本文主要是介绍学习brpc:echo服务,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Echo同步客户端

server 端

#include <gflags/gflags.h>
#include <json2pb/pb_to_json.h>
#include <brpc/server.h>
#include "butil/endpoint.h"
#include "echo.pb.h"// flags,用于配置server
DEFINE_bool(echo_attachment, true, "Echo attachment as well");
DEFINE_int32(port, 8000, "TCP Port of this server");
DEFINE_string(listen_addr, "", "Server listen address, may be IPV4/IPV6/UDS."" If this is set, the flag port will be ignored");
DEFINE_int32(idle_timeout_s, -1, "Connection will be closed if there is no ""read/write operations during the last `idle_timeout_s'");class EchoServiceImpl : public example::EchoService {
public:EchoServiceImpl() = default;virtual ~EchoServiceImpl() = default;// response完成后执行的回调static void CallAfterRpc(brpc::Controller* controller, const google::protobuf::Message* req, const google::protobuf::Message* res) {std::string req_str, res_str;// 此时cntl/req/res均没有被析构json2pb::ProtoMessageToJson(*req, &req_str, NULL);json2pb::ProtoMessageToJson(*res, &res_str, NULL);LOG(INFO) << "Got "<< "req:" << req_str<< "and res:" << res_str;
}void Echo (google::protobuf::RpcController* controller,const example::EchoRequest* request,example::EchoResponse* response,google::protobuf::Closure* done) override {brpc::Controller* cntl = static_cast<brpc::Controller*>(controller); // 强转brpc::ClosureGuard done_guard(done); // RAII//日志LOG(INFO) << "Received request[log_id=" << cntl->log_id() << "] from " << cntl->remote_side() << " to " << cntl->local_side()<< ": " << request->message()<< " (attached=" << cntl->request_attachment() << ")";// 生成响应response->set_message("Echo: " + request->message());// 如果有捎带数据,也发送回去if(FLAGS_echo_attachment) {cntl->response_attachment().append(cntl->request_attachment());}// 设置response完成后的回调函数cntl->set_after_rpc_resp_fn(std::bind(EchoServiceImpl::CallAfterRpc,std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));}};int main(int argc, char* argv[]) {// 初始化gflagsGFLAGS_NS::ParseCommandLineFlags(&argc, &argv, true);brpc::Server server;EchoServiceImpl service_impl; // 添加服务,,brpc::SERVER_OWNS_SERVICE 表示server是否拥有 service_impl,通常为false    if(server.AddService(&service_impl, brpc::SERVER_OWNS_SERVICE) != 0) {LOG(ERROR) << "Fail to add service";return -1;}// 监听节点, 默认监听所有地址butil::EndPoint point;if(FLAGS_listen_addr.empty()) {point = butil::EndPoint(butil::IP_ANY, FLAGS_port);} else {// 解析监听地址if(butil::str2endpoint(FLAGS_listen_addr.c_str(), &point) != 0) {LOG(ERROR) << "Invalid listen address:" << FLAGS_listen_addr;return -1;}}// 设置配置brpc::ServerOptions options;    options.idle_timeout_sec = FLAGS_idle_timeout_s; // 开启server(异步的)if(server.Start(point, &options) != 0) {LOG(ERROR) << "Fail to start EchoServer";return -1;}// 等待直到退出server.RunUntilAskedToQuit(); return 0;}

client 端

#include <cstdio>
#include <gflags/gflags.h>
#include <butil/logging.h>
#include <butil/time.h>
#include <brpc/channel.h>
#include "echo.pb.h"DEFINE_string(attachment, "attach", "Carry this along with requests");
DEFINE_string(protocol, "baidu_std", "Protocol type. Defined in src/brpc/options.proto");
DEFINE_string(connection_type, "", "Connection type. Available values: single, pooled, short");
DEFINE_string(server, "0.0.0.0:8000", "IP Address of server");
DEFINE_string(load_balancer, "", "The algorithm for load balancing");
DEFINE_int32(timeout_ms, 100, "RPC timeout in milliseconds");
DEFINE_int32(max_retry, 3, "Max retries(not including the first RPC)"); 
DEFINE_int32(interval_ms, 1000, "Milliseconds between consecutive requests");int main(int argc, char* argv[]) {GFLAGS_NS::ParseCommandLineFlags(&argc, &argv, true);// 配置brpc::ChannelOptions options;options.protocol = FLAGS_protocol;options.connection_type = FLAGS_connection_type;options.timeout_ms = FLAGS_timeout_ms/*milliseconds*/;options.max_retry = FLAGS_max_retry;// 初始化channelbrpc::Channel channel;if((channel.Init(FLAGS_server.c_str(), FLAGS_load_balancer.c_str(), &options)) != 0) {LOG(ERROR) << "Fail to initialize channel";return -1;}// channel的封装类,线程间共享example::EchoService_Stub stub(&channel); // 准备请求响应example::EchoRequest request;example::EchoResponse response;brpc::Controller cntl; char buf[128];printf("请输入:");scanf("%s",buf);request.set_message(buf);// 捎带数据cntl.request_attachment().append(FLAGS_attachment);// Cluster 设置为空,表示同步执行,函数会阻塞,直到结果返回,或者超时stub.Echo(&cntl, &request, &response, NULL);if(cntl.Failed()) {LOG(WARNING) << cntl.ErrorText(); // 通常这只是WARNING,为了演示才直接返回return -1;}// 正确输出LOG(INFO) << "Received response from " << cntl.remote_side()<< " to " << cntl.local_side()<< ": " << response.message() << " (attached="<< cntl.response_attachment() << ")"<< " latency=" << cntl.latency_us() << "us";}

Echo 异步客户端

server端代码与同步端端server一致。

client端

#include <cstdio>
#include <gflags/gflags.h>
#include <butil/logging.h>
#include <butil/time.h>
#include <brpc/channel.h>
#include <google/protobuf/stubs/callback.h>
#include "brpc/callback.h"
#include "bthread/bthread.h"
#include "echo.pb.h"DEFINE_string(attachment, "attach", "Carry this along with requests");
DEFINE_string(protocol, "baidu_std", "Protocol type. Defined in src/brpc/options.proto");
DEFINE_string(connection_type, "", "Connection type. Available values: single, pooled, short");
DEFINE_string(server, "0.0.0.0:8000", "IP Address of server");
DEFINE_string(load_balancer, "", "The algorithm for load balancing");
DEFINE_int32(timeout_ms, 100, "RPC timeout in milliseconds");
DEFINE_int32(max_retry, 3, "Max retries(not including the first RPC)"); 
DEFINE_int32(interval_ms, 1000, "Milliseconds between consecutive requests");void HandleResponse(brpc::Controller *cntl, example::EchoResponse* response) {// 异步调用需要自己管理cntl 和 response 的生命周期?!// 不应该管理// std::unique_ptr<brpc::Controller> cntl_guard(cntl);// std::unique_ptr<example::EchoResponse> response_guard(response);if(cntl->Failed()) {LOG(ERROR) << "Fail to send EchoRequest, " << cntl->ErrorText();return;}// 故意等一段时间bthread_usleep(10);// 日志LOG(INFO) << "Received response from " << cntl->remote_side()<< ": " << response->message() << " (attached="<< cntl->response_attachment() << ")"<< " latency=" << cntl->latency_us() << "us";}int main(int argc, char* argv[]) {GFLAGS_NS::ParseCommandLineFlags(&argc, &argv, true);// 配置brpc::ChannelOptions options;options.protocol = FLAGS_protocol;options.connection_type = FLAGS_connection_type;options.timeout_ms = FLAGS_timeout_ms/*milliseconds*/;options.max_retry = FLAGS_max_retry;// 初始化channelbrpc::Channel channel;if((channel.Init(FLAGS_server.c_str(), FLAGS_load_balancer.c_str(), &options)) != 0) {LOG(ERROR) << "Fail to initialize channel";return -1;}// channel的封装类,线程间共享example::EchoService_Stub stub(&channel); // 准备请求响应example::EchoRequest request;example::EchoResponse response;brpc::Controller cntl; char buf[128];printf("请输入:");scanf("%s",buf);request.set_message(buf);// 捎带数据cntl.request_attachment().append(FLAGS_attachment);// 设置异步回调函数google::protobuf::Closure* done = brpc::NewCallback(&HandleResponse, &cntl, &response);// Cluster 非空,表示异步执行,接收完消息后调用donestub.Echo(&cntl, &request, &response, done);// 继续执行while(true) {bthread_usleep(5);printf("do something\n"); // 可以看到,stub.Echo是立即返回的,不影响后续执行}}

这篇关于学习brpc:echo服务的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/882628

相关文章

sysmain服务可以禁用吗? 电脑sysmain服务关闭后的影响与操作指南

《sysmain服务可以禁用吗?电脑sysmain服务关闭后的影响与操作指南》在Windows系统中,SysMain服务(原名Superfetch)作为一个旨在提升系统性能的关键组件,一直备受用户关... 在使用 Windows 系统时,有时候真有点像在「开盲盒」。全新安装系统后的「默认设置」,往往并不尽编

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

Nginx中配置使用非默认80端口进行服务的完整指南

《Nginx中配置使用非默认80端口进行服务的完整指南》在实际生产环境中,我们经常需要将Nginx配置在其他端口上运行,本文将详细介绍如何在Nginx中配置使用非默认端口进行服务,希望对大家有所帮助... 目录一、为什么需要使用非默认端口二、配置Nginx使用非默认端口的基本方法2.1 修改listen指令

SysMain服务可以关吗? 解决SysMain服务导致的高CPU使用率问题

《SysMain服务可以关吗?解决SysMain服务导致的高CPU使用率问题》SysMain服务是超级预读取,该服务会记录您打开应用程序的模式,并预先将它们加载到内存中以节省时间,但它可能占用大量... 在使用电脑的过程中,CPU使用率居高不下是许多用户都遇到过的问题,其中名为SysMain的服务往往是罪魁

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

解决若依微服务框架启动报错的问题

《解决若依微服务框架启动报错的问题》Invalidboundstatement错误通常由MyBatis映射文件未正确加载或Nacos配置未读取导致,需检查XML的namespace与方法ID是否匹配,... 目录ruoyi-system模块报错报错详情nacos文件目录总结ruoyi-systnGLNYpe

Nginx进行平滑升级的实战指南(不中断服务版本更新)

《Nginx进行平滑升级的实战指南(不中断服务版本更新)》Nginx的平滑升级(也称为热升级)是一种在不停止服务的情况下更新Nginx版本或添加模块的方法,这种升级方式确保了服务的高可用性,避免了因升... 目录一.下载并编译新版Nginx1.下载解压2.编译二.替换可执行文件,并平滑升级1.替换可执行文件

Spring Boot 与微服务入门实战详细总结

《SpringBoot与微服务入门实战详细总结》本文讲解SpringBoot框架的核心特性如快速构建、自动配置、零XML与微服务架构的定义、演进及优缺点,涵盖开发环境准备和HelloWorld实战... 目录一、Spring Boot 核心概述二、微服务架构详解1. 微服务的定义与演进2. 微服务的优缺点三

RabbitMQ消息总线方式刷新配置服务全过程

《RabbitMQ消息总线方式刷新配置服务全过程》SpringCloudBus通过消息总线与MQ实现微服务配置统一刷新,结合GitWebhooks自动触发更新,避免手动重启,提升效率与可靠性,适用于配... 目录前言介绍环境准备代码示例测试验证总结前言介绍在微服务架构中,为了更方便的向微服务实例广播消息,