总共提供了两种实现方式,主要区分来自于是否支持TLS的配置,这个和Go的HTTP标准库实现有关,http标准库会为配置了证书的http服务自动选用http/2协议,grpc建立在http/2协议上,所以没有配置SSL证书时请勿使用方式一

方式一、该方式仅限给Gin配置了SSL证书

package main

import (
	"context"
	"fmt"
	"grpc-test/helloword"
	"log"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"
)

type Helloword struct {
	helloword.UnimplementedGreeterServer
}

func (c *Helloword) SayHello(ctx context.Context, in *helloword.HelloRequest) (*helloword.HelloReply, error) {
	fmt.Println("已进入到gRPC实现:", in.Name)
	return &helloword.HelloReply{
		Message: "OK",
	}, nil
}

// 入口
func main() {
	// 初始化grpc服务
	grpcServer := grpc.NewServer()

	/***** 注册你的grpc服务 *****/
	helloword.RegisterGreeterServer(grpcServer, &Helloword{})
	reflection.Register(grpcServer)

	// 初始化一个空Gin路由
	router := gin.New()

	/***** 添加你的api路由吧 *****/
	router.Any("/hello", func(ctx *gin.Context) {
		fmt.Println("已进入到HTTP实现")
		ctx.JSON(200, map[string]interface{}{
			"code": 200,
			"msg:": "success",
		})
	})

	// 监听端口并处理服务分流
	httpHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// 判断协议是否为http/2 && 是grpc
		if r.ProtoMajor == 2 &&
			strings.HasPrefix(r.Header.Get("Content-Type"), "application/grpc") {
			// 按grpc方式来请求
			grpcServer.ServeHTTP(w, r)
		} else {
			// 当作普通api
			router.ServeHTTP(w, r)
		}
	})

	// 监听HTTP服务
	err := http.ListenAndServeTLS(
		"0.0.0.0:8080",
		"你的SSL证书路径",
		"你的SSL私钥路径",
		httpHandler,
	)
	if err != nil {
		log.Println("http server done:", err.Error())
	}
}

方式二、当你不需要使用SSL证书或SSL证书配置在Nginx等服务上时

package main

import (
	"context"
	"fmt"
	"grpc-test/helloword"
	"log"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
	"golang.org/x/net/http2"
	"golang.org/x/net/http2/h2c"
	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"
)

type Helloword struct {
	helloword.UnimplementedGreeterServer
}

func (c *Helloword) SayHello(ctx context.Context, in *helloword.HelloRequest) (*helloword.HelloReply, error) {
	fmt.Println("已进入到gRPC实现:", in.Name)
	return &helloword.HelloReply{
		Message: "OK",
	}, nil
}

// 入口
func main() {
	// 初始化grpc服务
	grpcServer := grpc.NewServer()

	/***** 注册你的grpc服务 *****/
	helloword.RegisterGreeterServer(grpcServer, &Helloword{})
	reflection.Register(grpcServer)

	// 初始化一个空Gin路由
	router := gin.New()

	/***** 添加你的api路由吧 *****/
	router.Any("/hello", func(ctx *gin.Context) {
		fmt.Println("已进入到HTTP实现")
		ctx.JSON(200, map[string]interface{}{
			"code": 200,
			"msg:": "success",
		})
	})

	// 监听端口并处理服务分流
	h2Handler := h2c.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// 判断协议是否为http/2 && 是grpc
		if r.ProtoMajor == 2 &&
			strings.HasPrefix(r.Header.Get("Content-Type"), "application/grpc") {
			// 按grpc方式来请求
			grpcServer.ServeHTTP(w, r)
		} else {
			// 当作普通api
			router.ServeHTTP(w, r)
		}
	}), &http2.Server{})

	// 监听HTTP服务
	if err := http.ListenAndServe(":8080", h2Handler); err != nil {
		log.Println("http server done:", err.Error())
	}
}