1. 程式人生 > >grpc+protobuf 的C++ service 例項解析

grpc+protobuf 的C++ service 例項解析

這篇文章將會簡單的描述一下grpc+protobuf 的C++ service的搭建過程,告訴讀者在linux系統下怎樣實現一個service介面的流程。

一、.proto檔案的

實現一個簡單的helloworld回顯功能,首先需要一個.proto檔案,我將它命名為example.proto,檔案內容如下:

	syntax = "proto3";

	message SearchRequest
	{
		string Request = 1;
	}

	message SearchResponse
	{
		string Response = 2;
	}

	service SearchService {
  		rpc Search (SearchRequest) returns (SearchResponse);
	}

二、自動生成程式碼

使用example.proto檔案自動生成grpc和protobuf的程式碼

protoc --cpp_out=./ examples.proto
protoc --grpc_out=./ --plugin=protoc-gen-grpc=/usr/local/bin/grpc_cpp_plugin examples.proto
這兩個命令將會生成四個檔案,examples.grpc.pb.cc、examples.grpc.pb.h、examples.pb.cc、examples.pb.h。

三、伺服器程式碼

#include <iostream>
#include <memory>
#include <string>

#include <grpc++/grpc++.h>
#include <grpc/grpc.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>

#include "examples.grpc.pb.h"

using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;

class SearchRequestImpl final : public SearchService::Service {
  Status Search(ServerContext* context, const SearchRequest* request,
                  SearchResponse* reply) override {
    std::string prefix("Hello ");
    reply->set_response(prefix + request->request());
    return Status::OK;
  }
};

void RunServer() {
  std::string server_address("0.0.0.0:50051");
  SearchRequestImpl service;

  ServerBuilder builder;
  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
  builder.RegisterService(&service);
  std::unique_ptr<Server> server(builder.BuildAndStart());
  std::cout << "Server listening on " << server_address << std::endl;

  server->Wait();
}

int main(int argc, char** argv) {
  RunServer();

  return 0;
}

四、客戶端程式碼

#include <iostream>
#include <memory>
#include <string>

#include <grpc++/grpc++.h>
#include <grpc/support/log.h>

#include "examples.grpc.pb.h"

using grpc::Channel;
using grpc::ClientAsyncResponseReader;
using grpc::ClientContext;
using grpc::CompletionQueue;
using grpc::Status;


class ExampleClient {
 public:
  explicit ExampleClient(std::shared_ptr<Channel> channel)
      : stub_(SearchService::NewStub(channel)) {}
 
  std::string Search(const std::string& user) {
 
    SearchRequest request;
    request.set_request(user);
 
    SearchResponse reply;
   
    ClientContext context;

    CompletionQueue cq;

    Status status;

    std::unique_ptr<ClientAsyncResponseReader<SearchResponse> > rpc(
        stub_->AsyncSearch(&context, request, &cq));

    rpc->Finish(&reply, &status, (void*)1);
    void* got_tag;
    bool ok = false;
  
    GPR_ASSERT(cq.Next(&got_tag, &ok));

   
    GPR_ASSERT(got_tag == (void*)1);
  
    GPR_ASSERT(ok);

    if (status.ok()) {
      return reply.response();
    } else {
      return "RPC failed";
    }
  }

 private:
 
  std::unique_ptr<SearchService::Stub> stub_;
};

int main(int argc, char** argv) {
  ExampleClient client(grpc::CreateChannel(
      "localhost:50051", grpc::InsecureChannelCredentials()));
  std::string user("world");
  std::string reply = client.Search(user);  // The actual RPC call!
  std::cout << "client received: " << reply << std::endl;

  return 0;
}

五、Makefile檔案
subdir = ./

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

SOURCES = $(wildcard $(subdir)*.cc)
SRCOBJS = $(patsubst %.cc,%.o,$(SOURCES))
CC = g++

%.o:%.cc
	$(CC) -std=c++11 -I/usr/local/include -pthread -c $< -o [email protected]

all: client server

client:	examples.grpc.pb.o examples.pb.o examples_client.o
	$(CC) $^ -L/usr/local/lib `pkg-config --libs grpc++ grpc` -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed -lprotobuf -lpthread -ldl -lssl -o [email protected]

server:	examples.grpc.pb.o examples.pb.o examples_server.o
	$(CC) $^ -L/usr/local/lib `pkg-config --libs grpc++ grpc` -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed -lprotobuf -lpthread -ldl -lssl -o [email protected]
#chmod 777 [email protected]

clean:
	sudo rm *.o
六、執行

執行./server啟動service,在另一個埠執行./client 打印出:client received: Hello world表示兩邊已通,grpc+protobuf 搭建完成。


相關推薦

grpc+protobufC++ service 例項解析

這篇文章將會簡單的描述一下grpc+protobuf 的C++ service的搭建過程,告訴讀者在linux系統下怎樣實現一個service介面的流程。 一、.proto檔案的 實現一個簡單的helloworld回顯功能,首先需要一個.proto檔案,我將它命名為exa

c++ coredump例項解析

一、背景     經過重重除錯後,看到編譯成功的那一刻,內心充滿歡喜。當程式一執行,卻經常出現coredump的情況,此時內心是崩潰的。我想程式設計師經常會碰到這種情況,尤其使用c++語言編寫程式碼,由於沒有自動記憶體管理,經常會出現coredump情況,主要原因有以下幾

gRPC快速入門(二)——Protobuf序列化原理解析

gRPC快速入門(二)——Protobuf序列化原理解析 一、Protobuf序列化原理簡介 1、序列化 序列化是將資料結構或物件轉換成二進位制位元組流的過程。Protobuf對於不同的欄位型別採用不同的編碼方式和資料儲存方式對訊息欄位進行序列化,以確保得到高效緊湊的資料壓縮。Protobuf序列化過程

C++類和物件例項解析

C++既是面向物件也是面向過程的語言,在這裡就有一個重要的概念——類。         何謂類?類是對物件的一種抽象,舉例來講:每一個實實在在存在的人就是一個物件,人有很多共同的特徵(一個頭,兩條腿,能走,能跑),這具有共同特徵的人就成為一個類。類是一個抽象的名詞,每一個人(即物件)是這個類的例項。   

C#】錯誤“System.NullReferenceException:未將物件引用設定到物件的例項解析

錯誤原因分析   首先,你要知道,在.net裡面所有操作的變數都是物件。   一般的標示符,如int,string,char等等,最後都會轉換為System名稱空間下面的類名(如Int32,String,Char等等),當然類例項化的就更不用說了。物件就必然

C#使用SOAP獲取webservice例項解析

程式碼如下: using System.IO; using System.Xml; using System.Net; namespace ConsoleApplicationTest2 { class SOAPTest {

vector的用法例項解析C++

本文例項展示了C++中的vector用法,分享給大家供大家參考。具體如下: 一、概述 vector是C++標準模板庫中的部分內容,它是一個多功能的,能夠操作多種資料結構和演算法的模板類和函式庫。vector是一個容器,它能夠存放各種型別的物件,簡單地說,vector是一個能

C#依賴注入例項解析

1.5 實現依賴注入1.5.1 背景介紹 設計模式中,尤其是結構型模式很多時候解決的就是物件間的依賴關係,變依賴具體為依賴抽象。平時開發中如果發現客戶程式依賴某個(或某類)物件,我們常常會對它們進行一次抽象,形成抽象的抽象類、介面,這樣客戶程式就

C語言 記憶體分配 地址 指標 陣列 引數 例項解析

指標簡介 : 指標式儲存變數地址的變數; -- 增加閱讀難度 : 指標 和 goto 語句會增加程式的理解難度, 容易出現錯誤; -- ANSI C : American National Standards Institute 美國國家標準學會, 即標準

C/C++ Windwos VS2015 gRPC protobuf 編譯

gRPC是什麼就不介紹了,下面直接進入如何正確編譯gRPC一、準備和獲取原始碼:Builds gRPC C and C++ with boringssl.Install Visual Studio 2015 or 2017 (Visual C++ compiler will

例項解析C++/CLI程式程序之間的通訊

  作者:謝啟東編譯   現在,把大型軟體專案分解為一些相互動的小程式似乎變得越來越普遍,程式各部分之間的通訊可使用某種型別的通訊協議,這些程式可能執行在不同的機器上、不同的作業系統中、以不同的語言編寫,但也有可能只在同一臺機器上,實際上,這些程式可看成是同一程式中的不同執行

USB Type-C工作原理解析

說明 是否 forms dfp 其他 耗時 def 左右 del 自從蘋果發布了新MacBook,USB Type-C接口就成為了熱議對象。我來從硬件角度解析下這個USB Type-C,以便大家更好的了解USB Type-C的工作原理。特色尺寸小,支持正反插,速度快(10G

C++】cmdline —— 輕量級的C++命令行解析

pre eas 很好 -- 創建 tar mod ans valid 平時用C++寫一些命令行工具,須要解析命令行的輸入參數,這是一項繁瑣而且easy出錯的工作,我們不應該將主要精力放在這上面。能夠考慮使用開源的庫。以下的cmdline就是當中很好用

使用C#和HtmlAgilityPack解析HTML

load() 需要 有一個 Coding -c href .net tar doc   近期,有一個需求,需要解析HTML頁面,讀取一些需要的數據後,插入本地數據庫。我知道可以通過正則表達式實現,然而正則表達式之於我,就像匯編語言之於我,一樣。我知道它是幹什麽的,我也知道它

C#事件の事件解析

intern 處理機 信息 nta 語句 args handler poi pri 事件(event)是基於windows消息處理機制的類,封裝的更好,讓開發者無須知道底層的消息處理機制,就可以開發出強大的基於事件的應用程序來。委托(delegate)委托可以理解成為函數指

C#將Json解析成DateTable的方法

設計 功能 lec 獲取數據 one 分享圖片 ring bsp cas 本文實例講述了C#將Json解析成DateTable的方法。分享給大家供大家參考。具體實現方法如下: 代碼如下: #region 將 Json 解析成 DateTable /// /// 將

Android Service完全解析,關於服務你所需知道的一切(下)

並且 無法 數據類型 界面 其它 wid logcat listen 程序崩潰 文章轉載至:http://blog.csdn.net/guolin_blog/article/details/9797169 這是郭霖寫的.......就是寫 "第一行代碼"的那個厲害人物,大

C++ 內存解析

char 保留 就是 語句 代碼 選擇 包括 大小 是我 一、內存基本構成可編程內存在基本上分為這樣的幾大部分:靜態存儲區、堆區和棧區。他們的功能不同,對他們使用方式也就不同。 靜態存儲區:內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。它主要存放靜態

spring 官方文件的介面理解整理(四)型別轉換spring例項解析

上篇文章解析了spring型別轉換的介面和他們的分工,怎麼通過設計模式實現轉換功能。 這篇需要些上篇的知識,如果沒有看可以從這兒跳轉spring 官方文件的介面理解整理(三)型別轉換 一、準備新建Maven專案,pom.xml內容如下 <properties>

c/c++使用cJson解析未知內容的json字串

關於json我這裡就不做綴飾,這裡給出連結百度百科json 我這裡只介紹下json中的符號格式 ① { } : 雙括號表示一個json物件。例如:{"name":"ljl"},這代表一個name為ljl的物件 ②[ ] : 中括號表示陣列。例如:[{"name","ljl"},{"m