Go语言开发gRpc服务,springboot2.x客户端调用

Golang开发gRpc服务

  1. 首先本机安装proto客户端,并配置环境变量
  2. 创建golang项目 结构如下图

Go语言开发gRpc服务,springboot2.x客户端调用_第1张图片

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.服务端终端显示如下图

当前服务正常~

Springboot创建gRpc服务端和客户端

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文件复制到项目中,目录结构如下

Go语言开发gRpc服务,springboot2.x客户端调用_第2张图片

3.mvn compile之后 proto插件会根据当前proto文件生成对应的类,如下图

Go语言开发gRpc服务,springboot2.x客户端调用_第3张图片

4.接下来的四个文件 是springboot的启动类 grpc客户端 grpc服务端 和一个控制器,用来测试效果

Go语言开发gRpc服务,springboot2.x客户端调用_第4张图片

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来访问控制器提供的两个接口

Go语言开发gRpc服务,springboot2.x客户端调用_第5张图片

访问testgo时,我们通过客户端请求了Go语言开发的服务端

接下来我们访问testjava

Go语言开发gRpc服务,springboot2.x客户端调用_第6张图片

我们请求了当前项目下启动的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文件保持一致。

 

你可能感兴趣的:(Go语言开发gRpc服务,springboot2.x客户端调用)