总共提供了两种实现方式,主要区分来自于是否支持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())
}
}