gRPC使用实例

发布时间 2023-05-30 17:28:32作者: 田野与天

当然!这是三个使用Java实现的gRPC示例代码,用于演示gRPC的基本用法和通信模式:

示例1:简单的Unary RPC

在此示例中,客户端向服务器发送请求,并接收单个响应。

gRPC服务定义文件(.proto文件):

syntax = "proto3";

package com.example.grpcdemo;

service GreetingService {
    rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
    string name = 1;
}

message HelloResponse {
    string message = 1;
}

服务器实现类

import io.grpc.*;
import com.example.grpcdemo.*;

public class GreetingServiceImpl extends GreetingServiceGrpc.GreetingServiceImplBase {
    @Override
    public void sayHello(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {
        String message = "Hello, " + request.getName() + "!";
        HelloResponse response = HelloResponse.newBuilder().setMessage(message).build();

        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
}

服务器启动类

import io.grpc.*;
import java.io.IOException;

public class Server {
    public static void main(String[] args) throws IOException, InterruptedException {
        Server server = ServerBuilder.forPort(50051)
                .addService(new GreetingServiceImpl())
                .build();

        server.start();

        System.out.println("Server started.");

        server.awaitTermination();
    }
}

客户端实现类

import io.grpc.*;
import com.example.grpcdemo.*;

public class GreetingClient {
    public static void main(String[] args) {
        ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
                .usePlaintext()
                .build();

        GreetingServiceGrpc.GreetingServiceBlockingStub stub = GreetingServiceGrpc.newBlockingStub(channel);

        HelloRequest request = HelloRequest.newBuilder().setName("John").build();
        HelloResponse response = stub.sayHello(request);

        System.out.println(response.getMessage());

        channel.shutdown();
    }
}

在示例1中,我们定义了一个名为GreetingService的gRPC服务,其中包含一个名为SayHello的RPC方法。

服务器实现类GreetingServiceImpl继承自生成的GreetingServiceGrpc.GreetingServiceImplBase类,并重写了sayHello方法。在该方法中,我们根据请求中的名称构造响应消息,并通过StreamObserver发送响应。

服务器启动类通过ServerBuilder创建服务器,并将GreetingServiceImpl作为服务添加到服务器中。然后,启动服务器并等待终止。

客户端实现类GreetingClient创建一个与服务器的连接,并使用生成的GreetingServiceGrpc.GreetingServiceBlockingStub来发送请求并接收响应。最后,打印响应消息。

运行服务器和客户端代码后,您将看到客户端成功向服务器发送请求,并接收到响应消息。

示例2:Server Streaming RPC

在此示例中,客户端向服务器发送请求,并接收一系列的响应流。

gRPC服务定义文件(.proto文件):

syntax = "proto3";

package com.example.grpcdemo;

service NumberService {
    rpc GetNumbers (NumberRequest) returns (stream NumberResponse);
}

message NumberRequest {
    int32 count = 1;
}

message Number

Response {
    int32 number = 1;
}

服务器实现类

import io.grpc.*;
import com.example.grpcdemo.*;

public class NumberServiceImpl extends NumberServiceGrpc.NumberServiceImplBase {
    @Override
    public void getNumbers(NumberRequest request, StreamObserver<NumberResponse> responseObserver) {
        int count = request.getCount();

        for (int i = 0; i < count; i++) {
            NumberResponse response = NumberResponse.newBuilder().setNumber(i + 1).build();
            responseObserver.onNext(response);
        }

        responseObserver.onCompleted();
    }
}

服务器启动类客户端实现类与示例1中的代码相同。

在示例2中,我们定义了一个名为NumberService的gRPC服务,其中包含一个名为GetNumbers的RPC方法。

服务器实现类NumberServiceImpl继承自生成的NumberServiceGrpc.NumberServiceImplBase类,并重写了getNumbers方法。在该方法中,我们根据请求中的count字段循环生成一系列的响应,并通过StreamObserver逐个发送响应。

客户端代码与示例1中的客户端代码相同。

运行服务器和客户端代码后,您将看到客户端成功向服务器发送请求,并接收到一系列的响应流。

示例3:Client Streaming RPC

在此示例中,客户端通过流式方式向服务器发送一系列的请求,并接收单个响应。

gRPC服务定义文件(.proto文件):

syntax = "proto3";

package com.example.grpcdemo;

service SumService {
    rpc CalculateSum (stream NumberRequest) returns (SumResponse);
}

message NumberRequest {
    int32 number = 1;
}

message SumResponse {
    int32 sum = 1;
}

服务器实现类

import io.grpc.*;
import com.example.grpcdemo.*;

public class SumServiceImpl extends SumServiceGrpc.SumServiceImplBase {
    @Override
    public void calculateSum(StreamObserver<SumResponse> responseObserver) {
        StreamObserver<NumberRequest> requestObserver = new StreamObserver<NumberRequest>() {
            int sum = 0;

            @Override
            public void onNext(NumberRequest request) {
                int number = request.getNumber();
                sum += number;
            }

            @Override
            public void onError(Throwable t) {
                // 处理错误
            }

            @Override
            public void onCompleted() {
                SumResponse response = SumResponse.newBuilder().setSum(sum).build();
                responseObserver.onNext(response);
                responseObserver.onCompleted();
            }
        };

        responseObserver.onNext(requestObserver);
    }
}

服务器启动类客户端实现类与示例1中的代码相同。

在示例3中,我们定义了一个名为SumService的gRPC服务,其中包含一个名为CalculateSum的RPC方法。

服务器实现类SumServiceImpl继承自生成的SumServiceGrpc.SumServiceImplBase类,并重写了calculateSum方法。在该方法中,我们通过创建一个新的StreamObserver来处理客户端发送的一系列NumberRequest请求。在每个请求到达时,我们提取出数字并计算它们的总和。当请求流结束时,我们构造一个SumResponse响应,并通过responseObserver发送响应。

客户端代码与示例1中的客户端

代码相同。

运行服务器和客户端代码后,您可以使用客户端通过流式方式发送一系列数字,并接收到总和的响应。

这些示例代码演示了gRPC在Java中的基本用法和通信模式。请确保您已正确配置gRPC和相关依赖项,并根据需要更改主机和端口。