golang使用grpc转化为restful

下载包 

go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
go get -u github.com/golang/protobuf/protoc-gen-go
go get -u github.com/gogo/protobuf/gogoproto
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger

proto文件

syntax = "proto3";

package api;

import "github.com/gogo/protobuf@v1.3.2/gogoproto/gogo.proto";
import "google/api/annotations.proto";


message String {
    string value = 1 [(gogoproto.moretags) = 'form:"value" validate:"required"'];
}

service HelloService {
    rpc Hello (String) returns (String){
        option (google.api.http) = {
            get: "/hello"
        };
    };
}

生成代码

--grpc-gateway_out=.  表示会生成http的注册函数

--gofast_out 性能更高

protoc -I. -I$GOPATH/src -I$GOPATH/pkg/mod  --grpc-gateway_out=. --swagger_out=. --gofast_out=plugins=grpc:. hello.proto 

/*
错误日志
protoc  -I. -I$GOPATH/src -I$GOPATH/pkg/mod  --grpc-gateway_out=. --swagger_out=logtostderr=true:. --gofast_out=plugins=grpc:. api.proto 
*/

main函数

func main()  {
	lis, _ := net.Listen("tcp", ":5000")
	grpcServer := grpc.NewServer()
	lapi.RegisterHelloServiceServer(grpcServer, new(svc.Service))

	mux := runtime.NewServeMux()
	_ = lapi.RegisterHelloServiceHandlerFromEndpoint(
		context.Background(), mux, "localhost:5000",
		[]grpc.DialOption{grpc.WithInsecure()},)

	go grpcServer.Serve(lis)
	http.ListenAndServe(":8080", mux)
}

业务函数

type Service struct {}

func (svc *Service) Hello(context.Context, *lapi.String) (*lapi.String, error) {
	fmt.Println("xcxcvx")
	return &lapi.String{Value:"afdaf",}, nil
}

浏览器访问

http://127.0.0.1:8080/hello

{"value":"afdaf"}

rpc客户端访问

func helloClient()  {
	cc, _ := grpc.Dial("localhost:5000", grpc.WithInsecure())
	hellServiceCli := lapi.NewHelloServiceClient(cc)
	r, _ := hellServiceCli.Hello(context.Background(), &lapi.String{Value: "asdfxxx"})
	fmt.Println(r.Value)
}

拦截器

拦截器

func filter(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
	fmt.Println("fileter:", info.FullMethod)
	fmt.Println("fileter:", info.Server)
	fmt.Println("req", req)
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("panic: %v", r)
		}
	}()
	return handler(ctx, req)
}

//初始化grpcServer时加上拦截器
grpcServer := grpc.NewServer(grpc.UnaryInterceptor(filter))

链式拦截器

import "github.com/grpc-ecosystem/go-grpc-middleware"

grpcServer := grpc.NewServer(
		grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
			filter1, filter2,
		)),
		grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
			filter3,
		)),
)

使用TLS 

生成证书pem文件

openssl genrsa -out privkey.pem 2048
openssl req -new -key privkey.pem -out cert.csr -subj "/CN=localhost/O=myo"
openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095 -subj "/CN=localhost/O=myo"

main.go

package main

import (
	"context"
	"crypto/tls"
	"flag"
	"fmt"
	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"grpcl/api"
	svc "grpcl/service"
	cert "grpcl/tls"
	"log"
	"net"
	"net/http"
	"time"
)

var (
	gRPCPort    = flag.Int("grpc-port", 10000, "The gRPC server port")
	gatewayPort = flag.Int("gateway-port", 11000, "The gRPC-Gateway server port")
)

//客户端测试
func helloClient()  {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	cc, _ := grpc.DialContext(ctx, net.JoinHostPort("localhost", "10000"),
		grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(cert.CertPool, "")),
	)
	defer cc.Close()
	hellServiceCli := api.NewHelloServiceClient(cc)
	r, _ := hellServiceCli.Hello(context.Background(), &api.String{Value: "asdfxxx"})
	fmt.Println(r.Value)
}


func main() {
	flag.Parse()
	addr := fmt.Sprintf("localhost:%d", *gRPCPort)
	lis, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatalln("Failed to listen:", err)
	}
	s := grpc.NewServer(
		grpc.Creds(credentials.NewServerTLSFromCert(&cert.Cert)),
	)
	api.RegisterHelloServiceServer(s, &svc.Service{})

	// Serve gRPC Server
	fmt.Println("Serving gRPC on https://", addr)
	go func() {
		log.Fatal(s.Serve(lis))
	}()

	conn, err := grpc.DialContext(
		context.Background(),
		addr,
		grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(cert.CertPool, "")),
		grpc.WithBlock(),
	)
	if err != nil {
		log.Fatalln("Failed to dial server:", err)
	}

	gwmux := runtime.NewServeMux()
	err = api.RegisterHelloServiceHandler(context.Background(), gwmux, conn)
	if err != nil {
		log.Fatalln("Failed to register gateway:", err)
	}

	gatewayAddr := fmt.Sprintf("localhost:%d", *gatewayPort)
	fmt.Printf("Serving gRPC-Gateway on https://%s\n", gatewayAddr)

	gwServer := http.Server{
		Addr: gatewayAddr,
		Handler: gwmux,
		TLSConfig: &tls.Config{
			Certificates: []tls.Certificate{cert.Cert},
		},
	}
	go helloClient()
	log.Fatalln(gwServer.ListenAndServeTLS("", ""))
}

cert.go

package cert

import (
	"crypto/tls"
	"crypto/x509"
	"log"
)

var (
	// Cert is a self signed certificate
	Cert tls.Certificate
	// CertPool contains the self signed certificate
	CertPool *x509.CertPool
)

func init() {
	var err error
	Cert, err = tls.LoadX509KeyPair("tls/cacert.pem", "tls/privkey.pem")
	if err != nil {
		log.Fatalln("Failed to parse key pair:", err)
	}
	Cert.Leaf, err = x509.ParseCertificate(Cert.Certificate[0])
	if err != nil {
		log.Fatalln("Failed to parse certificate:", err)
	}

	CertPool = x509.NewCertPool()
	CertPool.AddCert(Cert.Leaf)
}

浏览器访问

https://localhost:11000/hello

参考https://github.com/gogo/grpc-example

### 回答1: 很高兴为您提供帮助!关于Go语言中的GRPC教程,您可以参考Go官方文档中的GRPC教程:https://grpc.io/docs/tutorials/basic/go/,也可以参考GitHub上的一些开源项目,如https://github.com/grpc/grpc-go。 ### 回答2: GolangGRPC教程是关于如何使用Google开发的gRPC框架来构建高效的分布式系统的指南。GRPC是一种远程过程调用(RPC)框架,主要用于在客户端和服务器之间进行通信。 GolangGRPC教程首先介绍了GRPC的基本概念和原理,例如客户端和服务器之间的通信方式以及如何定义服务和消息。然后,教程详细介绍了如何在Golang中安装和配置GRPC的软件开发工具包,并提供了一些示例代码来说明如何创建GRPC服务器和客户端。 接下来,教程会教你如何使用protobuf(Protocol Buffers)作为GRPC的数据格式,protobuf是一种轻量级且语言无关的数据序列化机制。你将学会如何定义消息和服务接口,以及如何使用protobuf生成Golang的代码。 在教程的后半部分,你将学习如何使用GRPC的不同功能,如流式传输、服务器端流式和客户端流式,以及双向流式。这些功能可以让你更灵活地设计和实现你的分布式系统。 此外,教程还涉及了如何使用拦截器(interceptors)来实现自定义的认证、日志记录和错误处理等功能。你将了解如何在GRPC中实现服务端和客户端的拦截器,并掌握如何在应用程序中使用它们。 最后,教程还会介绍一些关于GRPC的最佳实践,例如如何处理错误、优化性能和处理并发等问题。这些实践可以帮助你在开发和维护GRPC应用程序时更高效和可靠。 总之,GolangGRPC教程提供了一种简单且强大的方式来构建分布式系统,并为你提供了充足的示例代码和实践经验来帮助你理解和应用GRPC框架。无论是初学者还是有经验的开发者,都能受益于这个教程。 ### 回答3: GolangGRPC教程是介绍Go语言中的GRPC框架的教程。GRPC是一种高性能、开源的远程过程调用(RPC)框架,支持多种编程语言,包括Go语言。 在GRPC教程中,首先会介绍GRPC的基本概念和架构。GRPC使用Protocol Buffers(简称Protobuf)作为接口定义语言(IDL),用于定义服务接口和消息格式。它提供了强类型的接口定义和支持多种语言的代码生成工具。通过IDL的定义,可以自动生成客户端和服务器端代码,大大简化了跨服务通信的开发工作。 接下来的教程将详细介绍如何使用GRPC构建客户端和服务器端。通过定义GRPC服务的接口和消息格式,可以方便地在不同的服务之间进行通信。教程会演示如何编写服务器端代码,实现服务接口的具体逻辑,并将其注册到GRPC框架中。同时,还会演示如何编写客户端代码,通过GRPC调用服务器端提供的服务,并处理返回的结果。 GRPC教程还会介绍一些高级特性,例如流式处理、认证和安全性等。流式处理支持客户端流、服务器端流和双向流,可以实现更复杂的通信模式。认证和安全性可以通过TLS/SSL等机制来保护通信的安全性。 在学习GRPC教程时,你将会了解到GRPC的优势和如何使用GRPC来构建可扩展和高性能的分布式系统。通过GRPC,你可以轻松地实现跨语言的服务调用,并利用其丰富的特性来满足不同的业务需求。 总之,GolangGRPC教程是一个很好的学习资源,能够帮助你掌握GRPC框架的基本概念和使用方法,并在实际项目中应用它来构建高效可靠的分布式系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值