1.创建maven项目,并在pom.xml中增加相关依赖,完整pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.edu.tju</groupId>
<artifactId>grpc-hello</artifactId>
<version>1.0.0</version>
<properties>
<grpc-version>1.15.0</grpc-version>
</properties>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-core</artifactId>
<version>${grpc-version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>${grpc-version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc-version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc-version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.下载protobuf编译器(protoc.exe)和grpc插件(protoc-gen-grpc-java-1.15.0-windows-x86_64.exe),并在同一目录新建hello.proto文件,
syntax = "proto3";
option java_multiple_files = true;
option java_package = "cn.edu.tju";
option java_outer_classname = "HelloProto";
package hello;
service MyGreeter{
rpc GetHello (HelloRequest) returns (HelloResponse) {}
}
message HelloRequest{
string language=1;
string name=2;
}
message HelloResponse{
string language=1;
string name=2;
}
运行命令行程序并切换到上述目录,分别执行两个命令,
protoc hello.proto --plugin=protoc-gen-grpc-java=protoc-gen-grpc-java-1.15.0-windows-x86_64.exe --grpc-java_out=.
protoc hello.proto --java_out=.
3.将生成的文件拷贝到idea的java目录.
4.创建服务端启动类和客户端启动类:
package cn.edu.tju;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
public class MyHelloServer {
private static final Logger logger = Logger.getLogger(MyHelloServer.class.getName());
private Server server;
private void start() throws IOException {
int port = 50052;
server = ServerBuilder.forPort(port)
.addService(new MyGreeterImpl())
.build()
.start();
logger.info("服务器启动,监听端口:" + port);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.err.println("正在关闭grpc服务......");
try {
MyHelloServer.this.stop();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
System.err.println("服务器已关闭");
}
});
}
private void stop() throws InterruptedException {
if (server != null) {
server.shutdown().awaitTermination(30, TimeUnit.SECONDS);
}
}
private void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
MyHelloServer server = new MyHelloServer();
server.start();
server.blockUntilShutdown();
}
static class MyGreeterImpl extends MyGreeterGrpc.MyGreeterImplBase {
@Override
public void getHello(HelloRequest req, StreamObserver<HelloResponse> responseObserver) {
String language=req.getLanguage();
HelloResponse reply=null;
if(language.equals("1")){
reply = HelloResponse.newBuilder().setName("Hello, " + req.getName()).build();
}else{
reply = HelloResponse.newBuilder().setName("您好, " + req.getName()).build();
}
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
}
package cn.edu.tju;
import io.grpc.Channel;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MyHelloClient {
private static final Logger logger = Logger.getLogger(MyHelloClient.class.getName());
private final MyGreeterGrpc.MyGreeterBlockingStub blockingStub;
public MyHelloClient(Channel channel) {
blockingStub = MyGreeterGrpc.newBlockingStub(channel);
}
public void greet(String name,String language) {
logger.info("Will try to greet " + name + " by language "+language+" ...");
HelloRequest request = HelloRequest.newBuilder().setName(name).setLanguage(language).build();
HelloResponse response;
try {
response = blockingStub.getHello(request);
} catch (Exception ex) {
logger.info(ex.getMessage());
return;
}
logger.info("来自服务器的响应: " + response.getName());
}
public static void main(String[] args) throws Exception {
String user = "爱因斯坦";
String language="2";
String target = "localhost:50052";
ManagedChannel channel = ManagedChannelBuilder.forTarget(target)
.usePlaintext()
.build();
try {
MyHelloClient client = new MyHelloClient(channel);
client.greet(user,language);
}catch (Exception ex){
System.out.println(ex.getMessage());
}
finally {
channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
}
}
}
目录结构如下:
5.先后运行服务端程序和客户端程序,可以看到服务端和客户端分别输出如下: