# gRPC ###### tags: `gPRC` `python` `kotlin` gRPC主要是一個透過http/2來通訊的遠端呼叫程式,透過google發明的proto buffer語言來描述資料結構,再折成各個語言的形狀。 不得不說上手挺容易的 首先看一下proto檔案 ```protobuf= syntax = "proto3"; // 下面這個是我為了介接kotlin所用的 option java_multiple_files = true; option java_package = "io.quarkus.example"; option java_outer_classname = "HelloWorldProto"; package helloworld; service Greeter { // 你想使用的方法 rpc SayHello (HelloRequest) returns (HelloReply) {} } // 資料結構,後面的數字是為了防止打亂資料結構所給的資料順序 message HelloRequest { string name = 1; } message HelloReply { string message = 1; } ``` ## Server 寫好proto檔案後可以讓他自動跑出來對應語言的程式,以py來說是 ```bash= python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./helloworld.proto ``` 那些點可以視作在你現在的位置。 輸入之後會出現兩個檔案 ``` hellowoeld_pb2_grpc.py hellowoeld_pb2.py ``` 再來創建一個service.py檔案 ```python= from proto.helloworld_pb2_grpc import GreeterServicer, add_GreeterServicer_to_server from proto.helloworld_pb2 import HelloReply import grpc import logging import asyncio class HelloService(GreeterServicer): def SayHello(self, request, context): name = request.name # 從client端發來的request,裡面name的資料 print(context.peer()) # 這個可以偷看client IP return HelloReply(message=f"Hello {name}") async def serve(): server = grpc.aio.server() add_GreeterServicer_to_server(HelloService(), server) server.add_insecure_port("[::]:50051") await server.start() await server.wait_for_termination() if __name__ == "__main__": logging.basicConfig(level=logging.INFO) asyncio.run(serve()) ``` 再來只要 ```bash= python service.py ``` 就可以開始你的gRPC的server端了 --- ## Client 另一邊用kotlin來展示 proto檔案一樣用上面那個 使用maven實作 ```bash= mvn compile ``` 只要這樣maven就會幫你直接轉換 資料會在 ``` target |_gemerated-sources |_grpc ``` 這裡面 再來在你的專案內創造一個HelloResource.kt ```kotlin= import javax.inject.Inject import javax.ws.rs.GET import javax.ws.rs.Path import javax.ws.rs.PathParam import javax.ws.rs.Produces import javax.ws.rs.core.MediaType @Path("/hello") class HelloResource { @Inject @GrpcService("hello") var client: GreeterBlockingStub? = null @GET @Produces(MediaType.TEXT_PLAIN) fun hello(): String { return "hello" } @GET @Path("/{name}") fun hello(@PathParam("name") name: String?): String { return client!!.sayHello(HelloRequest.newBuilder().setName("name").build()).message } } // 這是以一個param直接傳遞資料的形式,做成為服務可以不用給router。 ``` 另外要binding port,在你的application.properties裡面加入 ``` quarkus.grpc.clients.hello.host = localhost quarkus.grpc.clients.hello.port = 50051 ``` 再來只要 ```bash= $ mvn compile quarkus:dev ``` 就可以在localhost:50051/hello/quarkus內看到 ``` Hello quarkus ```