grpc+gin+proto,使用http调用rpc接口

本文介绍了如何在Go中结合gRPC、gin和protobuf来创建及通过HTTP调用RPC接口。首先展示了proto定义,接着生成web.pb.go文件。然后详细讲解了服务端web_server.go的实现,并提供了客户端web_client.go的代码示例。最后,说明可以通过浏览器以HTTP形式传参调用接口并获取响应。

接下来重点讲如何创建并通过http 使用rpc接口 。
proto代码

syntax = "proto3";
package proto.web.web.proto;

option go_package = "pb;pb";

// 进入
message ComeIn {
	string name = 1; 	// 名称
	string trait = 2;	// ip
}

// 离开
message GetOut {
	string name = 1;	// 名称
	string ip 	= 2;	// ip
}

service Web {
	rpc  WebService(ComeIn) returns (GetOut);
}

生成web.pb.go文件
需要下载可运行的exe文件,根据提示下载即可

protoc  --go_out=plugins=grpc:. proto/web/*.proto

web_server.go代码
服务端代码

var _ pb.WebServer = &Server{}

type Server {}

func (s *Server) WebService(ctx context.Context, c*pb.ComeIn) (*pb.GetOut, error) {
	return &pb.GetOut{Name:c.Name,Ip:c.Ip}, nil
}

func main (){
	web := grpc.NewServer()
	pb.RegisterWebServer(web, &Server{})
	lis, err := net.Listen("tcp", ":8089")
	if err != nil {
		panic(err)
	}
	// 协程启动
	go func() {
		if err := web.Serve(lis); err != nil {panic(err)}
	}()
	// 自动优雅停止,tpc避免占用资源
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
	for {
		s := <-c
		switch s {
		case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
			web.GracefulStop()
			return
		}
	}
}

web_client.go
客户端代码


type Server struct {
	engine       *gin.Engine
	webClient	pb.WebServerClient
}

// 创建一个rpc 客户端启动器 
func InitWebServer(addr string) pb.WebServerClient{
	ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second))
	defer cancel()
	conn, err := grpc.DialContext(ctx, addr,
		[]grpc.DialOption{
			grpc.WithInsecure(),
			grpc.WithInitialWindowSize(grpcInitialWindowSize),
			grpc.WithInitialConnWindowSize(grpcInitialConnWindowSize),
			grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(grpcMaxCallMsgSize)),
			grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(grpcMaxSendMsgSize)),
			grpc.WithBackoffMaxDelay(grpcBackoffMaxDelay),
			grpc.WithKeepaliveParams(keepalive.ClientParameters{
				Time:                grpcKeepAliveTime,
				Timeout:             grpcKeepAliveTimeout,
				PermitWithoutStream: true,
			}),
			grpc.WithBalancerName(roundrobin.Name),
		}...)
	if err != nil {
		panic(err)
	}
	return pb.NewWebServerClient(conn)
}

// 使用rpc接口
func (s *Server) CallWeb(txt *gin.Context){
	var in *pb.ComeIn{}
	if err := txt.BindJSON(&in);err != nil {// 接收到的值赋值给 ComeIn中,如果字段错误会报无法给name为:xxx字段赋值
		panic(err.Error()) 
	}
	out,err := s.webClient.WebService(context.Background(),in) // 此处调用rpc
	if err != nil {
		panic(err.Error()) 
	}
	txt.JSON(http.StatusOK,out) // 成功响应
}

// http 服务,使用gin包
func NewHttp(httpAddr string,rpcAddr string){
	h := gin.Default()
	go func(){
		if err := r.Run(httpAddr); err != nil {panic(err)}
	}()
	s := Server{
		engine:     h
		webClient:	InitWebServer(rpcAddr) // 端口要一致,否则报错 rpc 没有注册
	}
	s.engine.Get(/hello,s.CallWeb)// 注册http路由
}


func main (){
	NewHttp(":4399",":8089")
}


通过浏览器输入
ip+:端口?name=xxx&ip=xxx
就可以看到响应了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值