3.新建一个helloworld.proto文件,内容如下
syntax = "proto3";
package helloworld;
option java_package = "com.example.grpc.helloworld";
option java_multiple_files = true;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
这个文件稍后还会用在springboot项目中
4.使用命令将proto文件生成成go文件,命令如下
# proto文件编译为go文件命令
// protoc --go_out=plugins=grpc:{输出目录} {proto文件}
protoc --go_out=plugins=grpc:./helloworld/ ./helloworld.proto
5.在server文件夹下 新建main.go,作为gRpc的服务端
/*
@Time : 2020/5/25 15:01
@Author : wkang
@File : server
@Description:
*/
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
"log"
"net"
pb "../helloworld"
)
const (
port = ":50051"
)
// server is used to implement helloworld.GreeterServer.
type server struct{}
// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
fmt.Println("######### get client request name :"+in.Name)
return &pb.HelloReply{Message: "GO gRpc服务的响应为: Hello " + in.Name}, nil
}
func main() {
lis, err := net.Listen("tcp", port)
fmt.Println(port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
// Register reflection service on gRPC server.
reflection.Register(s)
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
6.服务端创建成功,我们在server文件夹下运行终端 输入命令启动服务
go run main.go
7.可以看到服务启动成功,我打印了一下端口号
8.我们可以初始化一个客户端,来看看服务端是否正常,在client文件夹下,添加main.go,代码如下
/*
@Time : 2020/5/25 15:01
@Author : wkang
@File : server
@Description:
*/
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
"log"
"net"
pb "../helloworld"
)
const (
port = ":50051"
)
// server is used to implement helloworld.GreeterServer.
type server struct{}
// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
fmt.Println("######### get client request name :"+in.Name)
return &pb.HelloReply{Message: "GO gRpc服务的响应为: Hello " + in.Name}, nil
}
func main() {
lis, err := net.Listen("tcp", port)
fmt.Println(port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
// Register reflection service on gRPC server.
reflection.Register(s)
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
9.在client文件夹下 启动客户端服务,可在命令行界面看到响应
10.服务端终端显示如下图
当前服务正常~
1.首先我们新建一个sprongboot项目,修改pom文件如下
4.0.0
com.example
grpc-java-demo
0.0.1-SNAPSHOT
jar
grpc-java-demo
Demo project for Spring Boot gRpc
org.springframework.boot
spring-boot-starter-parent
2.3.0.RELEASE
UTF-8
UTF-8
1.8
3.0.0
1.6.1
0.6.1
org.springframework.boot
spring-boot-starter-web
io.github.lognet
grpc-spring-boot-starter
${grpc-spring-boot-starter.version}
org.springframework.boot
spring-boot-starter-test
test
kr.motd.maven
os-maven-plugin
${os-maven-plugin.version}
org.springframework.boot
spring-boot-maven-plugin
org.xolstice.maven.plugins
protobuf-maven-plugin
${protobuf-maven-plugin.version}
com.google.protobuf:protoc:3.5.1-1:exe:${os.detected.classifier}
grpc-java
io.grpc:protoc-gen-grpc-java:1.16.1:exe:${os.detected.classifier}
compile
compile-custom
2.将开始创建好的proto文件复制到项目中,目录结构如下
3.mvn compile之后 proto插件会根据当前proto文件生成对应的类,如下图
4.接下来的四个文件 是springboot的启动类 grpc客户端 grpc服务端 和一个控制器,用来测试效果
5.GrpcJavaDemoApplication 启动文件
package com.example.grpcjavademo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GrpcJavaDemoApplication {
public static void main(String[] args) {
SpringApplication.run(GrpcJavaDemoApplication.class, args);
}
}
6.HelloWorldClient客户端文件
package com.example.grpcjavademo.grpc;
import com.example.grpc.helloworld.GreeterGrpc;
import com.example.grpc.helloworld.HelloReply;
import com.example.grpc.helloworld.HelloRequest;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class HelloWorldClient {
private static final Logger LOGGER =
LoggerFactory.getLogger(com.example.grpcjavademo.grpc.HelloWorldClient.class);
private GreeterGrpc.GreeterBlockingStub helloWorldServiceBlockingStubForGo;
private GreeterGrpc.GreeterBlockingStub helloWorldServiceBlockingStubForJava;
@PostConstruct
private void init() {
//初始化一个连接Go grpc的客户端
ManagedChannel managedChannelForGo = ManagedChannelBuilder
.forAddress("127.0.0.1", 50051).usePlaintext().build();
helloWorldServiceBlockingStubForGo =
GreeterGrpc.newBlockingStub(managedChannelForGo);
//初始化一个连接Java grpc的客户端
ManagedChannel managedChannelForJava = ManagedChannelBuilder
.forAddress("127.0.0.1", 6565).usePlaintext().build();
helloWorldServiceBlockingStubForJava =
GreeterGrpc.newBlockingStub(managedChannelForJava);
}
public String sayHello(String name,String server) {
HelloRequest person = HelloRequest.newBuilder().setName(name).build();
LOGGER.info("client sending {}", person);
String res="";
if (server=="go"){
HelloReply greeting =
helloWorldServiceBlockingStubForGo.sayHello(person);
LOGGER.info("client received {}", greeting);
res=greeting.getMessage();
}
if (server=="java"){
HelloReply greeting =
helloWorldServiceBlockingStubForJava.sayHello(person);
LOGGER.info("client received {}", greeting);
res=greeting.getMessage();
}
return res;
}
}
在这里我们初始化了两个客户端,分别连接不同的端口,一个用来连接测试上面Go创建的grpc服务,一个用来连接测试java创建的gRpc服务
7.服务端文件HelloWorldServiceImpl
package com.example.grpcjavademo.grpc;
import com.example.grpc.helloworld.GreeterGrpc;
import com.example.grpc.helloworld.HelloReply;
import com.example.grpc.helloworld.HelloRequest;
import io.grpc.stub.StreamObserver;
import org.lognet.springboot.grpc.GRpcService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@GRpcService
public class HelloWorldServiceImpl
extends GreeterGrpc.GreeterImplBase {
private static final Logger LOGGER =
LoggerFactory.getLogger(com.example.grpcjavademo.grpc.HelloWorldServiceImpl.class);
@Override
public void sayHello(HelloRequest request,
StreamObserver responseObserver) {
LOGGER.info("server received {}", request);
String message = "Java gRpc服务的响应为: Hello " + request.getName() + "!";
HelloReply greeting =
HelloReply.newBuilder().setMessage(message).build();
LOGGER.info("server responded {}", greeting);
responseObserver.onNext(greeting);
responseObserver.onCompleted();
}
}
8.用来测试的控制器
package com.example.grpcjavademo.controller;
import com.example.grpcjavademo.grpc.HelloWorldClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("/home")
public class HomeController {
@Resource
private HelloWorldClient helloWorldClient;
//连接Go的gRpc服务端
@GetMapping("/testgo")
public String testGo(){
String s = helloWorldClient.sayHello("World","go");
return s;
}
//连接java(当前项目)的gRpc服务端
@GetMapping("/testjava")
public String testJava(){
String s = helloWorldClient.sayHello("World","java");
return s;
}
}
9.启动项目,我们使用postman来访问控制器提供的两个接口
访问testgo时,我们通过客户端请求了Go语言开发的服务端
接下来我们访问testjava
我们请求了当前项目下启动的grpc。
至此完结,因为不复杂,所以没有写的很详细,可以查看两个项目的源码
go gRpc客户端和服务端的demo https://github.com/flyingkoala/grpc-go-demo
springboot gRpc客户端和服务端的demo https://github.com/flyingkoala/grpc-java-demo
最后ps一下踩到的坑
1.go语言开发grpc用到的框架,因为被qiang的原因,可能在下载的过程中麻烦一些,方法可以自行百度一下,无非就是gopm、代理、git下载到本地自行安装这几种。
2.proto文件保持一致。