GithubHelp home page GithubHelp logo

zcy421593 / grpc_cb Goto Github PK

View Code? Open in Web Editor NEW

This project forked from jinq0123/grpc_cb

0.0 2.0 0.0 539 KB

C++ gRPC library with callback interface.

License: Apache License 2.0

CMake 0.50% Makefile 17.97% Batchfile 0.04% Lua 0.98% Python 0.59% C++ 79.51% C 0.41%

grpc_cb's Introduction

gRPC_cb

C++ gRPC library with callback interface. Depend on grpc but not on grpc++. It is a replacement of grpc++. Easier to use.

Build

  1. Copy grpc as third-party/grpc, and build grpc.
  2. Use build/grpc_cb.sln or build/Makefile to build grpc_cb.

Done

  • grpc_cpp_cb_plugin
  • grpc_cb library
  • helloworld example
  • route_guide example

Todo

  1. Lua binding. Convert grpc_byte_buffer to string, which is needed by lua.
  2. Connect and disconnect event.
  3. Export for unity.
  4. Compression
  5. Security
  6. Metadata
  7. Support message types other than protobuffer.

Tutorial

Tutorial shows some codes in the route_guide example. See doc/advanced_usage.md for more usage examples.

Defining the service

See examples/protos/route_guide.proto.

// Interface exported by the server.
service RouteGuide {
  // A simple RPC.
  rpc GetFeature(Point) returns (Feature) {}

  // A server-to-client streaming RPC.
  rpc ListFeatures(Rectangle) returns (stream Feature) {}

  // A client-to-server streaming RPC.
  rpc RecordRoute(stream Point) returns (RouteSummary) {}

  // A Bidirectional streaming RPC.
  rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
}
...

Generating client and server code

examples/protos/generate.bat is an example to generate client and server interfaces from .proto file, which runs:

	protoc -I . --cpp_out=../cpp_cb/route_guide route_guide.proto
	protoc -I . --grpc_out=../cpp_cb/route_guide --plugin=protoc-gen-grpc=grpc_cpp_cb_plugin.exe route_guide.proto

This generates the following files in directory examples/cpp_cb/route_guide

  • route_guide.pb.h, generated message classes header
  • route_guide.pb.cc, the implementation of message classes
  • route_guide.grpc_cb.pb.h, generated service classes header
  • route_guide.grpc_cb.pb.cc, the implementation of service classes

The generated namespace RouteGuide contains

  • a Stub class for clients to call.
  • a Service class for servers to implement.

Creating the client

See examples/cpp_cb/route_guide/route_guide_cb_client.cc.

Creating a stub

  1. Create a shared Channel, specifying the server address.

    ChannelSptr channel(new Channel("localhost:50051"));
  2. Instantiate a Stub

    Stub stub(channel);

Calling service methods

  • Blocking call
    • Simple RPC: BlockingGetFeature()

       Point point = MakePoint(0, 0);
       Feature feature;
       Status status = stub.BlockingGetFeature(point, &feature);
    • Server-side streaming RPC: SyncListFeatures()

       auto sync_reader(stub_->SyncListFeatures(rect));
       while (sync_reader.ReadOne(&feature)) {
       	cout << feature.name() << endl;
       }
       Status status = sync_reader.RecvStatus();
    • Client-side streaming RPC: SyncRecordRoute()

       auto sync_writer(stub_->SyncRecordRoute());
       for (int i = 0; i < kPoints; i++) {
       	const Feature& f = GetRandomFeature();
       	if (!sync_writer.Write(f.location())) {
       		// Broken stream.
       		break;
       	}
       }
       
       // Recv reponse and status.
       RouteSummary stats;
       Status status = sync_writer.Close(&stats);
    • Bidirectional streaming RPC: SyncRouteChat()

       auto sync_reader_writer(stub_->SyncRouteChat());
       auto f = std::async(std::launch::async, [sync_reader_writer]() {
       	RunWriteRouteNote(sync_reader_writer);
       });
      
       RouteNote server_note;
       while (sync_reader_writer.ReadOne(&server_note))
       	PrintServerNote(server_note);
      
       f.wait();
       Status status = sync_reader_writer.RecvStatus();
       void RunWriteRouteNote(Stus::RouteChat_SyncReaderWriter sync_reader_writer) {
       	std::vector<RouteNote> notes{ ... };
       	for (const RouteNote& note : notes) {
       		sync_reader_writer.Write(note);
       		RandomSleep();
       	}
       	sync_reader_writer.CloseWriting();
       }
  • Asycn call
    • Simple RPC: AsyncGetFeature()

      • With response callback

         Point point = MakePoint(0, 0);
         stub.AsyncGetFeature(point,
         	[](const Feature& feature) {
         		PrintFeature(feature);
         	});
      • Ignoring response

         stub.AsyncGetFeature(point);
      • With error callback

         stub.AsyncGetFeature(point,
         	[](const Feature& feature) { PrintFeature(feature); },
         	[](const Status& err) {
         		cout << err.GetDetails() << endl;
         	});  // AsyncGetFeature()
    • Run the stub

      • Async calls need

         stub.BlockingRun();  // until stub.Shutdown()
      • It can run in other thread.

      • It can be before or after async calls.

      • stub.Shutdown() or ~Stub() to end stub.BlockingRun().

    • Server-side streaming RPC: AsyncListFeatures()

       stub.AsyncListFeatures(rect,
       	[](const Feature& feature) {
       		cout << feature.name() << endl;
       	},
       	[&stub](const Status& status) {
       		stub.Shutdown();  // To break BlockingRun().
       	});
       stub.BlockingRun();  // until stub.Shutdown()
    • Client-side streaming RPC: AsyncRecordRoute()

       auto async_writer = stub.AsyncRecordRoute();
       for (int i = 0; i < kPoints; i++) {
       	const Feature& f = GetRandomFeature();
       	if (!async_writer.Write(f.location())) {
       		break;
       	}
       }
       // Recv reponse and status.
       async_writer.Close([](const Status& status, const RouteSummary& resp) {
       	if (status.ok())
       		cout << resp.point_count() << endl;
       });
    • Bidirectional streaming RPC: AsyncRouteChat()

       std::atomic_bool bReaderDone = false;
       auto async_reader_writer(
       	stub.AsyncRouteChat([&bReaderDone](const Status& status) {
       		bReaderDone = true;
       	}));
       
       async_reader_writer.ReadEach(
       	[](const RouteNote& note) { PrintServerNote(note); });
      
       std::vector<RouteNote> notes{ ... };
       for (const RouteNote& note : notes) {
       	async_reader_writer.Write(note);
       }
       async_reader_writer.CloseWriting();

Creating the server

See examples/cpp_cb/route_guide/route_guide_server.cc.

Implementing RouteGuide service

  1. Define a RouteGuideImpl class that implements the generated RouteGuide::Service interface. Service is always asynchronous.

    class RouteGuideImpl final : public routeguide::RouteGuide::Service {
    	...
    }
  2. Simple RPC: GetFeature()

    • Reply immediately

       void GetFeature(const Point& point,
       		const GetFeature_Replier& replier) override {
       	Feature feature;
       	feature.set_name("...");
       	replier.Reply(feature);
       }
    • Reply later

       void GetFeature(const Point& point,
       		const GetFeature_Replier& replier) override {
       	GetFeature_Replier replier_copy(replier);
       	std::thread thd([replier_copy]() {
       		Sleep(1000);
       		Feature feature;
       		feature.set_name("...");
       		replier_copy.Reply(feature);
       	});
       	thd.detach();
       }
  3. Server-side streaming RPC: ListFeatures()

    void ListFeatures(const routeguide::Rectangle& rectangle,
    		ListFeatures_Writer writer) override {
    	std::thread t([writer]() {
    		for (const Feature& f : feature_vector) {
    			if (!writer.Write(f)) break;
    			Sleep(1000);
    		}
    	});  // thread t
    	t.detach();
    }
  4. Client-side streaming RPC: RecordRoute()

    • Should return a shared reader:

       RecordRoute_ReaderSptr RecordRoute(
       	RecordRoute_Replier replier) override {
       	return std::make_shared<RecordRoute_ReaderImpl>(feature_vector_);
       }  // RecordRoute()
    • Should implement a RecordRoute_Reader:

       class RecordRoute_ReaderImpl
       		: public routeguide::RouteGuide::Service::RecordRoute_Reader {
       	...
       }
    • Implement virtual methods

      • OnMsg(const Request& msg)
        • Default noop.
      • OnError(const Status& status)
        • Default replys error.
      • OnEnd()
        • Default noop.
  5. Bidirectional streaming RPC: RouteChat()

    • Should return a shared reader.
       RouteChat_ReaderSptr RouteChat(RouteChat_Writer writer) override {
       	return std::make_shared<Reader>();
       }
    • Implement a reader.
       class Reader : public RouteChat_Reader {
       	protected:
       		void OnMsg(const RouteNote& msg) override {
       			for (const RouteNote& n : received_notes_) {
       				GetWriter().Write(n);
       			}  // for
       			received_notes_.push_back(msg);
       		}  // OnMsg()
       		
       		void OnEnd() override {
       			RouteChat_Writer writer = GetWriter();
       			std::thread t([writer]() {
       				std::this_thread::sleep_for(std::chrono::seconds(1));
       				writer.Write(RouteNote());
       			});
       			t.detach();
       		}  // OnEnd()
       
       	private:
       		std::vector<RouteNote> received_notes_;
       };  // class Reader

Starting the server

  1. Instantiate server and add listening port.

    Server svr;
    svr.AddListeningPort("0.0.0.0:50051");
  2. Instantiate service and register to server.

    RouteGuideImpl service(db_path);
    svr.RegisterService(service);
  3. Blocking run server.

    svr.BlockingRun();

grpc_cb's People

Contributors

jinq0123 avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.