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

2020/07/04 16:44
阅读数 7K

接下来重点讲如何创建并通过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
}

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 {
		panic(err.Error())
	}
	out,err := s.webClient.WebService(context.Background(),in)
	if err != nil {
		panic(err.Error())
	}
	txt.JSON(200,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
就可以看到响应了

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部