Gin + Grpc同时使用(监听同一端口)

时间:2025-02-21 08:19:38

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

	"/gin-gonic/gin"
	"/grpc"
	"/grpc/reflection"
)

type Helloword struct {
	
}

func (c *Helloword) SayHello(ctx , in *) (*, error) {
	("已进入到gRPC实现:", )
	return &{
		Message: "OK",
	}, nil
}

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

	/***** 注册你的grpc服务 *****/
	(grpcServer, &Helloword{})
	(grpcServer)

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

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

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

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

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

package main

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

	"/gin-gonic/gin"
	"/x/net/http2"
	"/x/net/http2/h2c"
	"/grpc"
	"/grpc/reflection"
)

type Helloword struct {
	
}

func (c *Helloword) SayHello(ctx , in *) (*, error) {
	("已进入到gRPC实现:", )
	return &{
		Message: "OK",
	}, nil
}

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

	/***** 注册你的grpc服务 *****/
	(grpcServer, &Helloword{})
	(grpcServer)

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

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

	// 监听端口并处理服务分流
	h2Handler := ((func(w , r *) {
		// 判断协议是否为http/2 && 是grpc
		if  == 2 &&
			(("Content-Type"), "application/grpc") {
			// 按grpc方式来请求
			(w, r)
		} else {
			// 当作普通api
			(w, r)
		}
	}), &{})

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