学习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) {// 异步任务通常在堆上分配Controller和 EchoResponse, 我这里为了简化直接在栈上分配的,并且生命周期比HandleResponse长,所以不用unique_ptr自动回收资源// 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是立即返回的,不影响后续执行}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/799791.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024.3.27力扣每日一题——统计将重叠区间合并成组的方案数

2024.3.27 题目来源我的题解方法一 排序合并区间快速幂方法二 官方区间合并 题目来源 力扣每日一题&#xff1b;题序&#xff1a;2580 我的题解 方法一 排序合并区间快速幂 先将ranges按第一个元素升序&#xff0c;再按第二个元素升序。然后采用合并区间的方式进行区间合并&…

maya获取所有节点的初始位置

目录 maya获取所有节点的初始位置 获取所有节点的 动画旋转位置 maya获取所有节点的初始位置 import maya.cmds as cmdsdef get_initial_pose(root_node):"""获取根节点及其所有子节点的初始姿态位置。参数:- root_node: 根节点的名称。返回值:- 一个包含节点…

[C++][算法基础]模拟堆(堆)

维护一个集合&#xff0c;初始时集合为空&#xff0c;支持如下几种操作&#xff1a; I x&#xff0c;插入一个数 x&#xff1b;PM&#xff0c;输出当前集合中的最小值&#xff1b;DM&#xff0c;删除当前集合中的最小值&#xff08;数据保证此时的最小值唯一&#xff09;&…

【云开发笔记NO.23】初步了解CODING-TSF-TKE

CODING-TSF-TKE的集成涉及的是腾讯云的产品。具体来说&#xff1a; CODING-TSF-TKE是腾讯云&#xff0c;腾讯公司提供的云服务。 定义&#xff1a; CODING&#xff1a;是腾讯云旗下一站式DevOps研发管理平台。它提供代码托管、项目协同、测试管理、持续集成、制品库、持续部署…

UE小:UE5.3无法创建C++工程

当您在使用Unreal Engine (UE) 构建项目时&#xff0c;如果遇到以下问题&#xff1a; Running C:/Program Files/Epic Games/UE\_5.3/Engine/Build/BatchFiles/Build.bat -projectfiles -project"C:/UEProject/Shp\_1/Shp\_1.uproject" -game -rocket -progress Usi…

如何在JavaScript中提高性能

在JavaScript中提高性能是一个涉及多个方面的任务&#xff0c;包括代码优化、数据结构选择、异步编程、避免全局查找、内存管理等。以下是一些关键的策略和技巧&#xff0c;可以帮助你提高JavaScript代码的性能&#xff1a; 1. 优化循环 使用for循环代替forEach&#xff0c;特…

设计模式:责任链模式

责任链模式是一种行为设计模式,允许你将请求沿着一条链传递,直到一个对象处理它为止。这种模式包含了一些处理对象,每个对象都包含逻辑来处理特定类型的命令或请求。如果一个对象不能处理该请求,它就会将请求传递给链中的下一个对象,如此类推。 定义 责任链模式通过定义…

python之正则表达式(2)

1、贪婪量词和懒惰量词 贪婪量词&#xff1a;也就是尽可能多的匹配字符 懒惰量词&#xff1a;尽可能少的匹配字符&#xff08;在现在的计算机语言中大多默认为贪婪量词若想要使用 懒惰量词就需要在后面加上&#xff1f;即可&#xff09; 代码示例&#xff1a; import rep …

JavaScript - 你遇到过哪几种Javascript的错误类型

难度级别:中级及以上 提问概率:50% 我们在开发Javascript代码的时候,经常一不小心就会遇到各种各样的异常,浏览器也会及时给出错误信息,那么一般会遇到哪几种异常情况呢,我们来看一下。 1 ReferenceError错误 ReferenceError几乎是最…

代码随想录训练营day29

第七章 回溯算法 part05 1.LeetCode. 递增子序列 1.1题目链接&#xff1a;491.递增子序列 文章讲解&#xff1a;代码随想录 视频讲解&#xff1a;B站卡哥视频 1.2思路&#xff1a;这个递增子序列比较像是取有序的子集。而且本题也要求不能有相同的递增子序列。这又是子集&a…

当MogDB遇到标量子查询中有limit或rownum怎么办

在过去的一些项目中&#xff0c;我们发现对于标量子查询带limit或者rownum的情况下&#xff0c;Oracle的性能非常高效&#xff0c;而MogDB的性能似乎差强人意&#xff0c;那么如果在使用MogDB的过程中遇到了这样的场景&#xff0c;该如何进行优化呢&#xff1f; 这里我们来给大…

光伏EPC项目管理系统的综合性管理理念和功能优势。

光伏EPC项目管理系统是一种适用于工程项目的管理软件&#xff0c;它强调在整个项目周期中的综合性管理理念&#xff0c;涵盖了从规划、设计、采购、施工到交付等全过程&#xff0c;帮助用户实现高效的项目管理。 1.增强项目团队之间的协作与沟通&#xff1a;光伏EPC项目管理系统…

【二分查找】Leetcode 搜索插入位置

题目解析 35. 搜索插入位置 这道题就是寻找target的目标位置&#xff0c;如果nums中包含target直接返回索引&#xff1b;如果不包含&#xff0c;需要返回target存放的合适位置 注意这道题有一个细节地方需要注意&#xff1a;如果现在target没有在nums中出现&#xff0c;并且目…

Electron 打包自定义NSIS脚本为安装向导增加自定义页面增加输入框

Electron 打包工具有很多&#xff0c;如Electron-build、 Electron Forge 等&#xff0c;这里使用Electron-build&#xff0c;而Electron-build使用了nsis组件来创建安装向导&#xff0c;默认情况nsis安装向导不能自定义安装向导界面&#xff0c;但是nsis提供了nsis脚本可以扩展…

ESP32调试笔记

目录 基于Thonny和micropythonESP32-CAM开发板无法连接Thonnyesp32cam局域网图传esp32代码上位机代码 基于Thonny和micropython ESP32-CAM开发板无法连接Thonny esp32cam有两个模式&#xff1a;下载模式、运行模式 两种模式的接线不同 IO0 短路 GND ! 正是因为两种模式接线…

Cloak斗篷技术:FP独立站的隐身术

FP商家常常面临着一个难题&#xff1a;如何在满足各大主流平台如Facebook、Google、TikTok等严格审核的同时&#xff0c;又能向买家展示真正想要推广的商品内容&#xff1f; Cloak斗篷技术正是为解决这一难题而诞生的。 简而言之&#xff0c;Cloak斗篷技术就如同给网页穿上了一…

[AI in sec]-039 DNS隐蔽信道的检测-特征构建

DNS隐蔽信道是什么 DCC是指利用DNS数据包中的可定义字段秘密传递信息的通道。其中,“DNS 协议”是目前网络上使用的标准域名解析协议;“可定义字段”是DNS 数据包中的 QNAME 字段、RDATA 字段及RawUDP字段。利用DNS数据包可以构建2种信道:存储信道及时间信道。DCC可以被用于…

nginx配置实例-动静分离

目录 一、相关概念 1.1动静分离概念 1.2动静分离的两种实现方法 二、实例配置 2.1 准备工作&#xff1a;在linux系统中准备静态资源&#xff0c;方便后面做测试 2.2 修改nginx配置文件 2.3 在浏览器测试 一、相关概念 1.1动静分离概念 将动态请求跟静态请求分开&#xf…

大模型在金融行业的应用场景和落地路径

大家好&#xff0c;我是爱编程的喵喵。双985硕士毕业&#xff0c;现担任全栈工程师一职&#xff0c;热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。…

李沐20_卷积层里的填充和步幅——自学笔记

填充和步幅 给定32✖32的输入图像&#xff0c;应用5✖5大小的卷积核&#xff08;第一层输出28✖28&#xff0c;第7层输出大小是4✖4&#xff0c;即每一层都-4&#xff09; 更大的卷积核可以更快地减小输出大小&#xff1a;形状从nk✖nk减少到(nh-kn1)✖(nw-kw1) 1.填充 在输…