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

被折叠的 条评论
为什么被折叠?



