基础教程-简单案例(快入入门java-grpc框架)
参考官方入门案例教程:里面我看proto编译,其实直接用maven就能直接将.proto文件编译成java代码。
快速入门 | Java | gRPC 框架
https://grpc.org.cn/docs/languages/java/quickstart/
目录结构
src/
├── main/
│   ├── proto/
│   │   └── hello.proto                # Proto 文件
│   ├── java/
│   │   ├── com/yuan/springboot/grpc/
│   │   │   ├── HelloServiceImpl.java # 服务端实现
│   │   │   ├── GrpcServer.java       # 服务端主类
│   │   │   ├── GrpcClient.java       # 客户端实现
│   │   │   ├── MainApplication.java  # 项目入口(可选)
 
Step 1: 配置maven依赖
 <properties>
        <grpc.version>1.6.1</grpc.version>
        <protobuf.version>3.3.0</protobuf.version>
</properties>
<dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty</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>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>${protobuf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
 <build>
        <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.0</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:${protobuf.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>
        </plugins>
    </build> 
Step 2: 创建 Proto 文件
注意:
将你的 hello.proto 文件放在 src/main/proto/hello.proto 路径下。
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.yuan.springboot.grpc";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";
package helloworld;
message HelloRequest {
  string name = 1;
}
message HelloResponse {
  string message = 1;
}
service HelloService {
  rpc sayHello(HelloRequest) returns (HelloResponse);
}
 
通过maven的compile直接就能编译如图:

Step 3: 实现服务端
HelloServiceImpl.java(com.yuan.springboot.grpc)
package com.yuan.springboot.grpc;
import io.grpc.stub.StreamObserver;
/**
 * @author liuyuan on 2025/1/15
 * 服务端实现
 */
public class HelloServiceImpl extends HelloServiceGrpc.HelloServiceImplBase {
    @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();
    }
} 
GrpcServer.java(com.yuan.springboot.grpc)
package com.yuan.springboot.grpc;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import java.io.IOException;
/**
 * @author liuyuan on 2025/1/15
 * 服务端主类
 */
public class GrpcServer {
    public static void main(String[] args) throws IOException, InterruptedException {
        Server server = ServerBuilder.forPort(9090)
                .addService(new HelloServiceImpl())
                .build();
        System.out.println("Server started on port 9090");
        server.start();
        server.awaitTermination();
    }
} 
Step 4: 实现客户端
GrpcClient.java(com.yuan.springboot.grpc)
package com.yuan.springboot.grpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
/**
 * @author liuyuan on 2025/1/15
 * 客户端实现
 */
public class GrpcClient {
    public static void main(String[] args) {
        // 创建 gRPC 通道
        ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 9090)
                .usePlaintext(true)
                .build();
        // 创建存根
        HelloServiceGrpc.HelloServiceBlockingStub stub = HelloServiceGrpc.newBlockingStub(channel);
        // 构造请求
        HelloRequest request = HelloRequest.newBuilder()
                .setName("World")
                .build();
        // 调用远程方法
        HelloResponse response = stub.sayHello(request);
        System.out.println("Response from server: " + response.getMessage());
        // 关闭通道
        channel.shutdown();
    }
} 
Step 5: 启动服务端和客户端
1、在 IntelliJ IDEA 中运行 GrpcServer.java,启动服务端,如图:

2、在 IntelliJ IDEA 中运行 GrpcClient.java,启动客户端,如图:

基础教程-定义rpc方法
在服务定义中定义 rpc 方法,指定它们的请求和响应类型。gRPC 允许你定义四种服务方法
1. 简单 RPC (Simple RPC)
- 方法名: 
sayHello - 描述: 客户端发送一个请求,服务器返回一个响应。
 
rpc sayHello(HelloRequest) returns (HelloResponse);
2. 服务器端流式 RPC (Server-side Streaming RPC)
- 方法名: 
streamHelloResponses - 描述: 客户端发送一个请求,服务器返回一个流,客户端从流中读取多个响应。
 
rpc streamHelloResponses(HelloRequest) returns (stream HelloResponse);
3. 客户端流式 RPC (Client-side Streaming RPC)
- 方法名: 
uploadHelloRequests - 描述: 客户端发送一个请求流,服务器返回一个单一的响应。
 
rpc uploadHelloRequests(stream HelloRequest) returns (HelloResponse);
4. 双向流式 RPC (Bidirectional Streaming RPC)
- 方法名: 
chatHello - 描述: 客户端和服务器通过流进行双向通信,客户端和服务器可以独立发送和接收消息。
 
rpc chatHello(stream HelloRequest) returns (stream HelloResponse);
四种rpc方法案例
step1 proto文件
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.yuan.springboot.grpc";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";
package helloworld;
message HelloRequest {
  string name = 1;
}
message HelloResponse {
  string message = 1;
}
service HelloService {
  // 简单 RPC
  rpc sayHello(HelloRequest) returns (HelloResponse);
  // 服务器端流式 RPC (Server-side Streaming RPC)
  rpc streamHelloResponses(HelloRequest) returns (stream HelloResponse);
  // 客户端流式 RPC (Client-side Streaming RPC)
  rpc uploadHelloRequests(stream HelloRequest) returns (HelloResponse);
  // 双向流式 RPC (Bidirectional Streaming RPC)
  rpc chatHello(stream HelloRequest) returns (stream HelloResponse);
} 
step2 实现定义的rpc方法(服务端实现)
public class HelloServiceImpl extends HelloServiceGrpc.HelloServiceImplBase {
    @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();
    }
    @Override
    public void streamHelloResponses(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {
        String name = request.getName();
        for (int i = 1; i <= 5; i++) {
            HelloResponse response = HelloResponse.newBuilder()
                    .setMessage("Hello, " + name + "! Message " + i)
                    .build();
            responseObserver.onNext(response);
            // 模拟延迟
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        responseObserver.onCompleted();
    }
    @Override
    public StreamObserver<HelloRequest> uploadHelloRequests(StreamObserver<HelloResponse> responseObserver) {
        return new StreamObserver<HelloRequest>() {
            private final StringBuilder messages = new StringBuilder();
            @Override
            public void onNext(HelloRequest request) {
                messages.append("Hello, ").append(request.getName()).append("\n");
            }
            @Override
            public void onError(Throwable t) {
                t.printStackTrace();
            }
            @Override
            public void onCompleted() {
                HelloResponse response = HelloResponse.newBuilder()
                        .setMessage(messages.toString())
                        .build();
                responseObserver.onNext(response);
                responseObserver.onCompleted();
            }
        };
    }
    @Override
    public StreamObserver<HelloRequest> chatHello(StreamObserver<HelloResponse> responseObserver) {
        return new StreamObserver<HelloRequest>() {
            @Override
            public void onNext(HelloRequest request) {
                String message = "Hello, " + request.getName();
                HelloResponse response = HelloResponse.newBuilder()
                        .setMessage(message)
                        .build();
                responseObserver.onNext(response);
            }
            @Override
            public void onError(Throwable t) {
                t.printStackTrace();
            }
            @Override
            public void onCompleted() {
                responseObserver.onCompleted();
            }
        };
    }
    
} 
step3 客户端实现
public class HelloClient {
    private final HelloServiceGrpc.HelloServiceBlockingStub blockingStub;
    private final HelloServiceGrpc.HelloServiceStub asyncStub;
    public HelloClient(String host, int port) {
        // 创建 gRPC 通道
        ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port)
                .usePlaintext(true) // 不使用 SSL,开发环境下推荐
                .build();
        // 创建不同类型的 stub
        blockingStub = HelloServiceGrpc.newBlockingStub(channel);
        asyncStub = HelloServiceGrpc.newStub(channel);
    }
    // 简单 RPC 示例
    public void simpleRpc(String name) {
        HelloRequest request = HelloRequest.newBuilder().setName(name).build();
        HelloResponse response = blockingStub.sayHello(request);
        System.out.println("Response from server: " + response.getMessage());
    }
    // 服务器端流式 RPC 示例
    public void serverStreamingRpc(String name) {
        HelloRequest request = HelloRequest.newBuilder().setName(name).build();
        asyncStub.streamHelloResponses(request, new io.grpc.stub.StreamObserver<HelloResponse>() {
            @Override
            public void onNext(HelloResponse response) {
                System.out.println("Stream response: " + response.getMessage());
            }
            @Override
            public void onError(Throwable t) {
                t.printStackTrace();
            }
            @Override
            public void onCompleted() {
                System.out.println("Stream completed");
            }
        });
    }
    // 客户端流式 RPC 示例
    public void clientStreamingRpc() {
        io.grpc.stub.StreamObserver<HelloRequest> requestObserver = asyncStub.uploadHelloRequests(
                new io.grpc.stub.StreamObserver<HelloResponse>() {
                    @Override
                    public void onNext(HelloResponse response) {
                        System.out.println("Response from server: " + response.getMessage());
                    }
                    @Override
                    public void onError(Throwable t) {
                        t.printStackTrace();
                    }
                    @Override
                    public void onCompleted() {
                        System.out.println("Stream completed");
                    }
                });
        requestObserver.onNext(HelloRequest.newBuilder().setName("Alice").build());
        requestObserver.onNext(HelloRequest.newBuilder().setName("Bob").build());
        requestObserver.onCompleted();
    }
    // 双向流式 RPC 示例
    public void bidirectionalStreamingRpc() {
        io.grpc.stub.StreamObserver<HelloRequest> requestObserver = asyncStub.chatHello(
                new io.grpc.stub.StreamObserver<HelloResponse>() {
                    @Override
                    public void onNext(HelloResponse response) {
                        System.out.println("Response from server: " + response.getMessage());
                    }
                    @Override
                    public void onError(Throwable t) {
                        t.printStackTrace();
                    }
                    @Override
                    public void onCompleted() {
                        System.out.println("Stream completed");
                    }
                });
        requestObserver.onNext(HelloRequest.newBuilder().setName("Alice").build());
        requestObserver.onNext(HelloRequest.newBuilder().setName("Bob").build());
        requestObserver.onCompleted();
    }
} 
step4 案例测试
public class MainTest {
    @Test
    public void testRpcMethod_simpleRpc(){
        HelloClient client = new HelloClient("localhost", 9090);
        // 简单 RPC 调用
        client.simpleRpc("Alice");
    }
    @Test
    public void testRpcMethod_serverStreamingRpc() throws InterruptedException {
        HelloClient client = new HelloClient("localhost", 9090);
        // 服务器端流式 RPC 调用
        client.serverStreamingRpc("Bob");
        TimeUnit.SECONDS.sleep(6);
    }
    @Test
    public void testRpcMethod_clientStreamingRpc() throws InterruptedException {
        HelloClient client = new HelloClient("localhost", 9090);
        // 客户端流式 RPC 调用
        client.clientStreamingRpc();
        TimeUnit.SECONDS.sleep(3);
    }
    @Test
    public void testRpcMethod_bidirectionalStreamingRpc() throws InterruptedException {
        HelloClient client = new HelloClient("localhost", 9090);
        // 双向流式 RPC 调用
        client.bidirectionalStreamingRpc();
        TimeUnit.SECONDS.sleep(3);
    }
} 
 
总结
以上代码示例分别实现了四种 RPC 类型:
- 简单 RPC:一次请求-响应。
 - 服务器端流式 RPC:服务器返回一个流。
 - 客户端流式 RPC:客户端发送一个流。
 - 双向流式 RPC:客户端和服务器同时发送和接收流。
 
每种 RPC 类型的实现方式清晰,适用于不同的业务场景。



















