proto:
syntax = "proto3";
package gtr.warning;
service DataProvider{
// Sends a request
rpc GetData (GetRequest) returns (DataReply) {}
}
message GetRequest {
string name = 1;
}
message BoatInfo {
int64 id = 1;
string type = 2;
int32 n1 = 3;
int32 n2 = 4;
string name = 5;
string time = 6;
string level = 7;
string info = 8;
}
message Infos {
repeated BoatInfo info = 1;
}
message DataReply {
Infos infos = 1;
}
Makefile:
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
SYSTEM ?= $(HOST_SYSTEM)
CXX = g++
#CPPFLAGS += `pkg-config --cflags protobuf grpc`
CPPFLAGS += -I/usr/local/include -I/usr/include/mysql++ -I/usr/include/mysql
CXXFLAGS += -std=c++11
ifeq ($(SYSTEM),Darwin)
LDFLAGS += -L/usr/local/lib -lprotobuf -lgrpc++ -lgrpc\
-lgrpc++_reflection\
-ldl
else
LDFLAGS += -L/usr/local/lib -lprotobuf -lgrpc++ -lgrpc\
-Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\
-ldl
endif
PROTOC = protoc
GRPC_CPP_PLUGIN = grpc_cpp_plugin
GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
PROTOS_PATH = ./protos
vpath %.proto $(PROTOS_PATH)
all: boat_server boat_client
boat_server: boatwarnings.pb.o boatwarnings.grpc.pb.o boat_server.o
$(CXX) $^ $(LDFLAGS) /usr/lib64/libmysqlpp.so -o $@
boat_client: boatwarnings.pb.o boatwarnings.grpc.pb.o boat_client.o
$(CXX) $^ $(LDFLAGS) -o $@
.PRECIOUS: %.grpc.pb.cc
%.grpc.pb.cc: %.proto
$(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
.PRECIOUS: %.pb.cc
%.pb.cc: %.proto
$(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $<
clean:
rm -f *.o *.pb.cc *.pb.h boat_server
linux : server
//
// Created by Admin on 2018/3/13.
//
#ifndef GRPC_BOAT_BOAT_SERVER_H
#define GRPC_BOAT_BOAT_SERVER_H
#include <iostream>
#include <memory>
#include <string>
#include <grpc++/grpc++.h>
#include <mysql++.h>
#include "boatwarnings.grpc.pb.h"
using grpc::Server;
using grpc::ServerContext;
using grpc::ServerBuilder;
using grpc::Status;
using gtr::warning::DataProvider;
using gtr::warning::GetRequest;
using gtr::warning::DataReply;
using gtr::warning::BoatInfo;
using gtr::warning::Infos;
using mysqlpp::Connection;
using mysqlpp::Query;
using mysqlpp::StoreQueryResult;
class DataService {
public:
DataService(){};
~DataService(){};
bool connectDB(char* dbName,char* dbIP,char* dbUser,char* dbPassword) {
//conn_(false);
conn_.set_option(new mysqlpp::SetCharsetNameOption("utf8"));
return conn_.connect(dbName,dbIP,dbUser,dbPassword);
};
Infos* getData(){
Infos* infos = new Infos();
mysqlpp::StoreQueryResult res;
Query query = conn_.query();
const char* sql = "select * from gtr_tb_boat_warnnigs";
query << sql;
StoreQueryResult ares = query.store();
std::cout << "ares.num_rows() = " << ares.num_rows() << std::endl;
for (size_t i = 0; i < ares.num_rows(); i++)
{
BoatInfo *bInfo = infos->add_info();
bInfo->set_id(ares[i]["id"]);
bInfo->set_type(ares[i]["type"]);
bInfo->set_time(ares[i]["warningtime"]);
bInfo->set_n1(ares[i]["no1"]);
bInfo->set_n2(ares[i]["no2"]);
bInfo->set_name(ares[i]["name"]);
bInfo->set_info(ares[i]["info"]);
bInfo->set_level(ares[i]["level"]);
std::cout << "your data" << std::endl;
std::cout << "id" << ares[i]["id"]<<"\ttype" << ares[i]["type"] << "\twarningtime" << ares[i]["warningtime"];
std::cout <<"no1" << ares[i]["no1"] << "\tno1" << ares[i]["no2"] <<"\tname" <<ares[i]["name"];
std::cout << "info" << ares[i]["info"] << std::endl;
// std::cout << "name: " << ares[i]["name"] << "\tid: " << ares[i]["id"] << "\tstatus: " << ares[i]["status"] << std::endl;
}
return infos;
}
private:
std::string dbName_;
std::string dbUser;
std::string pass_;
std::string dbIP_;
Connection conn_;
};
class DataProviderServiceImpl final : public DataProvider::Service {
Status GetData(ServerContext* context, const GetRequest* request,
DataReply* reply) override {
setInfos();
reply->set_allocated_infos(infos_);
return Status::OK;
}
public:
void setInfos() {
DataService ds;
if(!ds.connectDB("boat","127.0.0.1","root","root")) std::cout << "connenct error \n";
infos_= ds.getData();
}
private:
Infos* infos_;
};
void RunServer() {
std::string server_address("0.0.0.0:50051");
DataProviderServiceImpl service;
//service.setInfos();
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) {
RunServer();
return 0;
}
win grpc编译 : do_build.bat
@echo off
::Release,Debug,RelWithDebInfo
set CMAKE_BUILD_TYPE=%1%
::x86,x64
set PLATFORM=%2%
set OUTPUT_PATH=%3%
set CMAKE_PATH=%4%
if not exist %PLATFORM% (
mkdir %PLATFORM%
)
cd %PLATFORM%
if %PLATFORM% == x86 (
call "%VS140COMNTOOLS%..\..\VC\vcvarsall.bat" x86
)
if %PLATFORM% == x64 (
call "%VS140COMNTOOLS%..\..\VC\vcvarsall.bat" amd64
)
echo cmake -G "NMake Makefiles" -D CMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE% -D EXECUTABLE_OUTPUT_PATH=%OUTPUT_PATH% -D LIBRARY_OUTPUT_PATH=%OUTPUT_PATH% -D CMAKE_C_FLAGS_RELEASE="/MT /WX-" -D CMAKE_CXX_FLAGS_RELEASE="/MT /WX-" -D BUILD_SHARED_LIBS=0 %CMAKE_PATH%
::CMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE% 构建类型(Release,Debug,RelWithDebInfo)
::EXECUTABLE_OUTPUT_PATH=%OUTPUT_PATH% 可执行程序的路径
::LIBRARY_OUTPUT_PATH=%OUTPUT_PATH% 静态库的路径
::CMAKE_C_FLAGS_RELEASE="/MT /WX-" 使用静态运行时库,禁止将警告视为错误
::CMAKE_CXX_FLAGS_RELEASE="/MT /WX-" 使用静态运行时库,禁止将警告视为错误
::BUILD_SHARED_LIBS=0 生成静态库
cmake -G "NMake Makefiles" -D CMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE% -D EXECUTABLE_OUTPUT_PATH=%OUTPUT_PATH% -D LIBRARY_OUTPUT_PATH=%OUTPUT_PATH% -D CMAKE_C_FLAGS_RELEASE="/MT /WX-" -D CMAKE_CXX_FLAGS_RELEASE="/MT /WX-" -D BUILD_SHARED_LIBS=0 %CMAKE_PATH%
nmake grpc grpc++ grpc_cpp_plugin protoc grpc++_unsecure grpc_unsecure
build_x64.bat
@echo off
set CURRENT_DIR=%~dp0
set CMAKE_BUILD_TYPE=Debug
set PLATFORM=x64
set OUTPUT_PATH=%CURRENT_DIR%/x64/debug
set CMAKE_PATH=%CURRENT_DIR%/../
call do_build.bat %CMAKE_BUILD_TYPE% %PLATFORM% %OUTPUT_PATH% %CMAKE_PATH%
@pause
vscode 配置:
配置->配置属性->c++->预处理器
如果是DEBUG版
_DEBUG
如果是release版
NDEBUG
_CONSOLE
_WIN32_WINNT=0x600
_SCL_SECURE_NO_WARNINGS
_CRT_SECURE_NO_WARNINGS
链接器->输入(DEBUG版)
zlibstaticd.lib
libprotobufd.lib
grpc++_unsecure.lib
grpc_unsecure.lib
gpr.lib
ws2_32.lib
RELEASE版
zlibstatic.lib
libprotobuf.lib
grpc++_unsecure.lib
grpc_unsecure.lib
gpr.lib
ws2_32.lib
boat_client.cc
//
// Created by Admin on 2018/3/14.
//
#ifndef GRPC_BOAT_CLIENT_H_
#define GRPC_BOAT_CLIENT_H_
#include <iostream>
#include <memory>
#include <string>
#include <grpc++/grpc++.h>
#include "boatwarnings.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using gtr::warning::DataProvider;
using gtr::warning::GetRequest;
using gtr::warning::DataReply;
using gtr::warning::BoatInfo;
using gtr::warning::Infos;
class DataProviderClient {
public:
DataProviderClient(std::shared_ptr<Channel> channel)
: stub_(DataProvider::NewStub(channel)) {}
// Assembles the client's payload, sends it and presents the response back
// from the server.
Infos GetData(const std::string& user) {
// Data we are sending to the server.
GetRequest request;
request.set_name(user);
// Container for the data we expect from the server.
DataReply reply;
// Context for the client. It could be used to convey extra information to
// the server and/or tweak certain RPC behaviors.
ClientContext context;
// The actual RPC.
Status status = stub_->GetData(&context, request, &reply);
// Act upon its status.
if (status.ok()) {
return reply.infos();
} else {
std::cout << status.error_code() << ": " << status.error_message()
<< std::endl;
return reply.infos();
}
}
private:
std::unique_ptr<DataProvider::Stub> stub_;
};
int main(int argc, char** argv) {
// Instantiate the client. It requires a channel, out of which the actual RPCs
// are created. This channel models a connection to an endpoint (in this case,
// localhost at port 50051). We indicate that the channel isn't authenticated
// (use of InsecureChannelCredentials()).
DataProviderClient dataProviderClient(grpc::CreateChannel(
"localhost:50051", grpc::InsecureChannelCredentials()));
std::string user("world");
Infos reply = dataProviderClient.GetData(user);
std::cout << "Greeter received: " << reply.info_size() << std::endl;
return 0;
}
#endif