maven依赖
<properties>
<!-- grpc 版本 -->
<grpc.version>2.10.1.RELEASE</grpc.version>
</properties>
<!-- 客户端添加这个依赖 -->
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-client-spring-boot-starter</artifactId>
<version>${grpc.version}</version>
</dependency>
<!-- 服务端添加这个依赖 -->
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-server-spring-boot-starter</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.47.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.47.0</version>
</dependency>
maven的build配置
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.34.1:exe:${os.detected.classifier}</pluginArtifact>
<!--设置grpc生成代码到指定路径-->
<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
<!--生成代码前是否清空目录-->
<clearOutputDirectory>false</clearOutputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- 设置多个源文件夹 -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<!-- 添加主源码目录 -->
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.basedir}/src/main/gen</source>
<source>${project.basedir}/src/main/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
proto文件在项目中的存放位置如下图:
编译proto,直接在maven标签中点击common中(因为proto和相关依赖是放在common模块中方便其他模块引用)的compile命令,如下图:
user.proto
syntax = "proto3";
import "google/api/annotations.proto";
package api.user.v1;
option go_package = "mid/api/user/v1;v1";
option java_multiple_files = true;
// java包名,下图中有体现
option java_package = "api.user.v1";
service User {
rpc CreateUser (CreateUserRequest) returns (UserReply) {
option (google.api.http) = {
post: "/v1/user"
body: "*"
};
};
rpc UpdateUser (UpdateUserRequest) returns (UserReply) {
option (google.api.http) = {
put: "/v1/user"
body: "*"
};
};
rpc GetUser (GetUserRequest) returns (UserReply) {
option (google.api.http) = {
get: "/v1/user"
};
};
}
message UserInfo {
int32 id = 1;
string nickname = 2;
string mobile = 3;
string token = 4;
}
message CreateUserRequest {
string mobile = 1;
string nickname = 2;
}
message UserReply {
int32 code = 1;
string message = 2;
UserInfo data = 3;
}
message UpdateUserRequest {
string nickname = 2;
}
message GetUserRequest {
int32 id = 1;
}
然后就会在common模块的java目录下生成对应的java文件
服务端grpc相关的yaml配置:
grpc:
server:
port: 32001
客户端grpc相关的yaml配置,negotiation-type: plaintext这个表示传输方式,不然需要配置ssl密钥,比较麻烦:
grpc:
client:
config-center:
negotiation-type: plaintext
enableKeepAlive: true
keepAliveWithoutCalls: true
服务端编写实现类(这里只实现一个方法为例):
package org.xgxy.configcenter.service.impl;
import api.user.v1.*;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;
import java.util.UUID;
@GrpcService
@Slf4j
public class UserGrpcServiceImpl extends UserGrpc.UserImplBase {
@Override
public void createUser(CreateUserRequest request, StreamObserver<UserReply> responseObserver) {
log.info("收到GRPC请求参数:{}", request);
UserReply.Builder userReplyBuilder = UserReply.newBuilder();
userReplyBuilder.setMessage("success-ssssss");
userReplyBuilder.setCode(999999);
userReplyBuilder.setData(
UserInfo.newBuilder()
.setId(33333)
.setMobile("55555555555")
.setNickname("guoboren")
.setToken(UUID.randomUUID().toString())
.build()
);
responseObserver.onNext(userReplyBuilder.build());
responseObserver.onCompleted();
}
@Override
public void updateUser(UpdateUserRequest request, StreamObserver<UserReply> responseObserver) {
super.updateUser(request, responseObserver);
}
@Override
public void getUser(GetUserRequest request, StreamObserver<UserReply> responseObserver) {
super.getUser(request, responseObserver);
}
}
客户端调用:
package org.xgxy.business.controller;
import api.user.v1.CreateUserRequest;
import api.user.v1.UserGrpc;
import api.user.v1.UserReply;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.web.bind.annotation.*;
import java.util.concurrent.ExecutionException;
@RestController
@Slf4j
@RequestMapping("/socket")
public class BusinessController {
@GrpcClient(value = "config-center")
private UserGrpc.UserFutureStub userFutureStub;
@GetMapping("/sendMsg/{uid}/{msg}")
public String sendMsg(@PathVariable("uid") Integer uid, @PathVariable("msg") String msg) {
try {
log.info("发送GRPC请求");
CreateUserRequest.Builder builder = CreateUserRequest.newBuilder();
builder
.setMobile("7777777")
.setNickname("renboguo");
UserReply u = userFutureStub.createUser(builder.build()).get();
log.info("收到GRPC服务器回复:{}", u);
return u.toString();
} catch (InterruptedException | ExecutionException e) {
log.error("GRPC调用错误");
e.printStackTrace();
}
return null;
}
}