簡介
grpc是一個高效能、開源和通用的 RPC 框架,面向移動和 HTTP/2 設計。目前提供 C、Java 和 Go 語言版本,分別是:grpc, grpc-java, grpc-go. 其中 C 版本支援 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支援.
gRPC 基於 HTTP/2 標準設計,帶來諸如雙向流、流控、頭部壓縮、單 TCP 連線上的多複用請求等特。這些特性使得其在移動裝置上表現更好,更省電和節省空間佔用。
開發環境配置
首先配置maven引用jar包,匯入全部grpc用的包,也可不全部匯入,我這裡求方便。
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-all</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>複製程式碼
然後引入protobuf檔案解析和程式碼生成:
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireUpperBoundDeps/>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>複製程式碼
引入後,在idea中maven projects中的plugins中就會看到protobuf
,在這個裡面就能生成所需要的java檔案。到“lifecycle”中執行compile或者執行maven命令“mvn compile”,就能生成需要的java檔案。
注:定義的protobuf檔案要與“java,resources”同級。
入門例項
grpc Client:
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import java.util.concurrent.TimeUnit;
public class HelloWorldClient {
private final ManagedChannel channel;
private static final GreeterGrpc.GreeterBlockingStub blockingStub;
HelloWorldClient(String host, int port) {
this.channel = ManagedChannelBuilder.forAddress(host, port)
.usePlaintext()
.build();
blockingStub = GreeterGrpc.newBlockingStub(channel);
}
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
public static void main(String[] args) throws Exception {
HelloWorldClient client = new HelloWorldClient("localhost", 50051);
try {
blockingStub.sayHello(HelloRequest.newBuilder().setName("hello").build();)
} finally {
client.shutdown();
}
}
}
複製程式碼
grpc-server
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import java.io.IOException;
import java.util.logging.Logger;
public class HelloWorldServer {
private static final Logger logger = Logger.getLogger(HelloWorldServer.class.getName());
private Server server;
private void start() throws IOException {
int port = 50051;
server = ServerBuilder.forPort(port)
.addService(new GreeterImpl())
.build()
.start();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
HelloWorldServer.this.stop();
}
});
}
private void stop() {
if (server != null) {
server.shutdown();
}
}
/**
* 等待主執行緒終止,因為GRPC庫使用守護程式執行緒。
*/
private void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
final HelloWorldServer server = new HelloWorldServer();
server.start();
server.blockUntilShutdown();
}
static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
}
複製程式碼
官方入門例項詳見:https://github.com/grpc/grpc-java/tree/master/examples/src/main/java/io/grpc/examples/helloworld
雙向流
server :
Map<String,StreamObserver<Object> > streamObserverMap = new HashMap();
static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
//客戶端呼叫時,將observer儲存起
streamObserverMap.put("sayHello",responseObserver);
}
} /**
* 傳送訊息
*/
public void sendMsgToclient() {
//使用時,從儲存的streamObserver呼叫onNext()
StreamObserver<Object> streamObserver = streamObserverMap.get("sayHello");
streamObserver.onNext();
//這裡注意不要呼叫onCompleted()方法,onCompleted()會將流關閉。當然如果這個流不用了你可以關閉
// responseObserver.onCompleted();
}
複製程式碼
Client:
//客戶端要在連線上服務端的時候要顯示的呼叫sendMsg方法,作為流的註冊
public static void main(String[] args) throws Exception {
HelloWorldClient client = new HelloWorldClient("localhost", 50051);
try {
//註冊StreamObserver
blockingStub.sayHello(HelloRequest.newBuilder().setName("").build())
} finally {
client.shutdown();
}
}複製程式碼
參考:grpc官方文件(http://doc.oschina.net/grpc?t=58008)