主要參考網上一些資料以及grpc源碼中的示例,暫未包含異步
- 編譯參考:
參考文檔1:https://www.cnblogs.com/lontoken/p/6377048.html
參考文檔2:https://yq.aliyun.com/articles/243432
參考文檔3:https://www.cnblogs.com/oloroso/p/11121922.html
我主要參考的第一篇,但版本有些老,新版本可以參考後兩篇,若使用編譯好的庫可以參考本文的工程
使用步驟:
- proto文件,這裏我寫了個例子,包括交互接口和輸入輸出信息結構
Protobuf3語言指南:https://blog.csdn.net/u011518120/article/details/54604615
- 自動生成grpc和protobuf的代碼
首先將proto文件拷貝到protoc.exe文件目錄下,打開命令行工具,cd到該目錄,運行以下兩行代碼:
protoc.exe --cpp_out=./ TransMsg.proto
protoc.exe --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin.exe TransMsg.proto
在該目錄下生成以下文件:
- 服務端代碼示例
.h文件
#ifndef _ZZXG_Server_H__
#define _ZZXG_Server_H__
#include <iostream>
#include <memory>
#include <string>
#include <grpc++/grpc++.h>
#include "TransMsg.grpc.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using TransMsg::RequestInfo;
using TransMsg::ReplyInfo;
using TransMsg::MutInterface;
class ZZXG_Server final: public MutInterface::Service
{
public:
ZZXG_Server();
~ZZXG_Server();
public:
Status RequestMsg(ServerContext* context, const RequestInfo* request, ReplyInfo* reply)override;
};
static void InitServer();
#endif // _ZZXG_Server_H__
.cpp文件
#include "ZZXG_Server.h"
ZZXG_Server::ZZXG_Server()
{
}
ZZXG_Server::~ZZXG_Server()
{
}
Status ZZXG_Server::RequestMsg(ServerContext* context, const RequestInfo* request, ReplyInfo* reply)
{
reply->set_asktype(request->asktype());
reply->set_asknum(request->asknum());
std::string reinfo = request->askname();
reply->set_remsg(reinfo);
return Status::OK;
}
void InitServer()
{
std::string server_address("0.0.0.0:50051");
ZZXG_Server service;
ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
// Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
server->Wait();
}
int main(int argc, char** argv)
{
InitServer();
return 0;
}
- 客戶端代碼示例
.h文件
#ifndef _ZZXG_Client_H__
#define _ZZXG_Client_H__
#include <iostream>
#include <memory>
#include <string>
#include <grpc++/grpc++.h>
#include "TransMsg.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using TransMsg::RequestInfo;
using TransMsg::ReplyInfo;
using TransMsg::MutInterface;
class ZZXG_Client
{
public:
ZZXG_Client(std::shared_ptr<Channel> channel);
~ZZXG_Client();
public:
std::string Request(int askType, std::string askName, int askNum);
private:
std::unique_ptr<MutInterface::Stub> stub_;
};
#endif //_ZZXG_Client_H__
.cpp文件
#include "ZZXG_Client.h"
ZZXG_Client::ZZXG_Client(std::shared_ptr<Channel> channel)
:stub_(MutInterface::NewStub(channel))
{}
ZZXG_Client::~ZZXG_Client()
{}
std::string ZZXG_Client::Request(int askType,std::string askName,int askNum)
{
// 定義請求對象,並賦值.
RequestInfo request;
request.set_asktype(askType);
request.set_asknum(askNum);
request.set_askname(askName);
// 返回對象定義.
ReplyInfo reply;
// Context for the client. It could be used to convey extra information to
// the server and/or tweak certain RPC behaviors.
ClientContext context;
// 調用請求函數.
Status status = stub_->RequestMsg(&context, request, &reply);
// 返回狀態.
if (status.ok())
{
return reply.remsg();
}
else
{
std::cout << status.error_code() << ": " << status.error_message()
<< std::endl;
return "RPC failed";
}
}
int main(int argc, char** argv)
{
ZZXG_Client client(grpc::CreateChannel("127.0.0.1:50051", grpc::InsecureChannelCredentials()));
std::string reply = client.Request(1,"xbgsdgsdgsdgsdgsdgsdgsdgsdgsdgsdgsd",1);
std::cout << "ZZXG_Client received: " << reply << std::endl;
while(1)
{
Sleep(1);
}
return 0;
}
源碼工程:鏈接:https://pan.baidu.com/s/1kaAS0-PX6DLr4bsCMmrDCQ
提取碼:olx1
其中nuget 主要用於加載依賴,如果沒有網絡加載,可以將加載的包添加路徑進行加載主要包括openssl和zlib,包括不同平臺lib庫和dll庫,(若自己編譯了相應版本的庫,可直接添加到依賴中)
下載地址: https://pan.baidu.com/s/1JWHWd3_ylNbMdFCQaRJojg
提取碼:mu7n
nuget添加程序包:
1、VS2015打開工程--》工具—》Nuget程序包管理器—》程序包管理器設置—》程序包源 新增一個名稱和路徑,設置路徑爲存放包文件夾的位置
2、工具—》Nuget程序包管理器—》管理解決方案的NuGet程序包,選擇剛添加的程序包,安裝到所需要的解決方案中
遇到問題:傳輸字符串含中文時傳輸不成功
注意:傳輸字符串結構 string時,不能包含中文,序列化的時候會出現截斷數據,string這個類型帶有檢查功能,把protobuf中存在中文的string字段類型 改爲bytes
string的序列化函數多以下代碼
(參考:https://www.cnblogs.com/a9999/p/7283244.html)