亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

gRPC快速入門(四)——gRPC快速入門

發布時間:2020-06-21 18:38:48 來源:網絡 閱讀:2949 作者:天山老妖S 欄目:軟件技術

gRPC快速入門(四)——gRPC快速入門

一、gRPC簡介

1、gRPC簡介

gRPC是一個高性能、通用的開源RPC框架,基于ProtoBuf(Protocol Buffers)序列化協議開發,且支持眾多開發語言,目前提供C、Java和Go語言版本,分別是grpc、grpc-java、grpc-go。gRPC提供了一種簡單的方法來精確地定義服務和為iOS、Android和后臺支持服務自動生成可靠性很強的客戶端功能庫。gRPC基于HTTP/2標準設計,帶來諸如雙向流、流控、頭部壓縮、單TCP連接上的多復用請求等特性,使得gRPC在移動設備上表現更好、更省電和節省空間占用。

2、gRPC的優點

gRPC優點如下:
(1)平臺無關,語言無關,可擴展;
(2)提供了友好的動態庫,使用簡單;
(3)解析速度快,比對應的XML快約20-100倍;
(4)序列化數據非常簡潔、緊湊,與XML相比,其序列化之后的數據量約為1/3到1/10。

3、gRPC安裝

官方推薦安裝命令:
go get google.golang.org/grpc
國內網絡環境由于GFW原因,不能直接訪問google服務器,報錯如下:
package google.golang.org/grpc: unrecognized import path "google.golang.org/grpc" (https fetch: Get https://google.golang.org/grpc?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
因此,在國內網絡環境下推薦直接從GitHub下載相應依賴進行安裝。

git clone https://github.com/grpc/grpc-go.git $GOPATH/src/google.golang.org/grpc
git clone https://github.com/golang/net.git $GOPATH/src/golang.org/x/net
git clone https://github.com/golang/text.git $GOPATH/src/golang.org/x/text
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
git clone https://github.com/google/go-genproto.git $GOPATH/src/google.golang.org/genproto
git clone https://github.com/golang/sys $GOPATH/src/golang.org/x/sys

安裝gRPC:
go install google.golang.org/grpc

二、gRPC使用

1、gRPC使用流程

gRPC使用流程如下:
(1)編寫.proto描述文件。
(2)編譯生成.pb.go文件。
(3)服務端實現約定的接口并提供服務。
(4)客戶端按照約定調用方法請求服務。

2、proto service定義

一個RPC service是一個能夠通過參數和返回值進行遠程調用的方法。由于gRPC通過將數據編碼成Protocal Buffer來實現傳輸,因此,使用者可以通過Protocal Buffers interface definitioin language(IDL)來定義service method,同時將參數和返回值也定義成Protocal Buffer message類型。gRPC源碼目錄提供了多個使用示例,本文使用helloworld示例作為模板,helloworld示例目錄位于google.golang.org/grpc/examples/helloworld
在$GOPATH/src目錄下創建helloworld目錄,包含proto、server、client子目錄。proto目錄下創建helloworld.proto文件。
helloworld.proto:

syntax = "proto3";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

helloworld.proto文件中定義了一個Greeter Service,服務包含一個SayHello方法,同時聲明了HelloRequest和HelloReply消息結構用于請求和響應。客戶端使用HelloRequest參數調用SayHello方法請求服務端,服務端響應HelloReply消息。

3、生成Go代碼

根據定義的RPC service,利用protocal buffer compiler,即protoc生成相應的服務器端和客戶端的Go代碼,生成的代碼中包含了客戶端能夠進行RPC的方法以及服務器端需要進行實現的接口。
在$GOPATH/src/helloworld/proto目錄下生成gRPC對應的Go代碼的命令如下:
protoc --go_out=plugins=grpc:. helloworld.proto
將在目錄下生成helloworld.pb.go文件,內容如下:

// Code generated by protoc-gen-go. DO NOT EDIT.
// source: helloworld.proto

package helloworld

import (
    context "context"
    fmt "fmt"
    proto "github.com/golang/protobuf/proto"
    grpc "google.golang.org/grpc"
    math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

// The request message containing the user's name.
type HelloRequest struct {
    Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

func (m *HelloRequest) Reset()         { *m = HelloRequest{} }
func (m *HelloRequest) String() string { return proto.CompactTextString(m) }
func (*HelloRequest) ProtoMessage()    {}
func (*HelloRequest) Descriptor() ([]byte, []int) {
    return fileDescriptor_17b8c58d586b62f2, []int{0}
}

func (m *HelloRequest) XXX_Unmarshal(b []byte) error {
    return xxx_messageInfo_HelloRequest.Unmarshal(m, b)
}
func (m *HelloRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
    return xxx_messageInfo_HelloRequest.Marshal(b, m, deterministic)
}
func (m *HelloRequest) XXX_Merge(src proto.Message) {
    xxx_messageInfo_HelloRequest.Merge(m, src)
}
func (m *HelloRequest) XXX_Size() int {
    return xxx_messageInfo_HelloRequest.Size(m)
}
func (m *HelloRequest) XXX_DiscardUnknown() {
    xxx_messageInfo_HelloRequest.DiscardUnknown(m)
}

var xxx_messageInfo_HelloRequest proto.InternalMessageInfo

func (m *HelloRequest) GetName() string {
    if m != nil {
        return m.Name
    }
    return ""
}

// The response message containing the greetings
type HelloReply struct {
    Message              string   `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

func (m *HelloReply) Reset()         { *m = HelloReply{} }
func (m *HelloReply) String() string { return proto.CompactTextString(m) }
func (*HelloReply) ProtoMessage()    {}
func (*HelloReply) Descriptor() ([]byte, []int) {
    return fileDescriptor_17b8c58d586b62f2, []int{1}
}

func (m *HelloReply) XXX_Unmarshal(b []byte) error {
    return xxx_messageInfo_HelloReply.Unmarshal(m, b)
}
func (m *HelloReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
    return xxx_messageInfo_HelloReply.Marshal(b, m, deterministic)
}
func (m *HelloReply) XXX_Merge(src proto.Message) {
    xxx_messageInfo_HelloReply.Merge(m, src)
}
func (m *HelloReply) XXX_Size() int {
    return xxx_messageInfo_HelloReply.Size(m)
}
func (m *HelloReply) XXX_DiscardUnknown() {
    xxx_messageInfo_HelloReply.DiscardUnknown(m)
}

var xxx_messageInfo_HelloReply proto.InternalMessageInfo

func (m *HelloReply) GetMessage() string {
    if m != nil {
        return m.Message
    }
    return ""
}

func init() {
    proto.RegisterType((*HelloRequest)(nil), "helloworld.HelloRequest")
    proto.RegisterType((*HelloReply)(nil), "helloworld.HelloReply")
}

func init() { proto.RegisterFile("helloworld.proto", fileDescriptor_17b8c58d586b62f2) }

var fileDescriptor_17b8c58d586b62f2 = []byte{
    // 175 bytes of a gzipped FileDescriptorProto
    0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xc8, 0x48, 0xcd, 0xc9,
    0xc9, 0x2f, 0xcf, 0x2f, 0xca, 0x49, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x42, 0x88,
    0x28, 0x29, 0x71, 0xf1, 0x78, 0x80, 0x78, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25, 0x42, 0x42,
    0x5c, 0x2c, 0x79, 0x89, 0xb9, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x60, 0xb6, 0x92,
    0x1a, 0x17, 0x17, 0x54, 0x4d, 0x41, 0x4e, 0xa5, 0x90, 0x04, 0x17, 0x7b, 0x6e, 0x6a, 0x71, 0x71,
    0x62, 0x3a, 0x4c, 0x11, 0x8c, 0x6b, 0xe4, 0xc9, 0xc5, 0xee, 0x5e, 0x94, 0x9a, 0x5a, 0x92, 0x5a,
    0x24, 0x64, 0xc7, 0xc5, 0x11, 0x9c, 0x58, 0x09, 0xd6, 0x25, 0x24, 0xa1, 0x87, 0xe4, 0x02, 0x64,
    0xcb, 0xa4, 0xc4, 0xb0, 0xc8, 0x14, 0xe4, 0x54, 0x2a, 0x31, 0x38, 0x19, 0x70, 0x49, 0x67, 0xe6,
    0xeb, 0xa5, 0x17, 0x15, 0x24, 0xeb, 0xa5, 0x56, 0x24, 0xe6, 0x16, 0xe4, 0xa4, 0x16, 0x23, 0xa9,
    0x75, 0xe2, 0x07, 0x2b, 0x0e, 0x07, 0xb1, 0x03, 0x40, 0x5e, 0x0a, 0x60, 0x4c, 0x62, 0x03, 0xfb,
    0xcd, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xb7, 0xcd, 0xf2, 0xef, 0x00, 0x00, 0x00,
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4

// GreeterClient is the client API for Greeter service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type GreeterClient interface {
    // Sends a greeting
    SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
}

type greeterClient struct {
    cc *grpc.ClientConn
}

func NewGreeterClient(cc *grpc.ClientConn) GreeterClient {
    return &greeterClient{cc}
}

func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) {
    out := new(HelloReply)
    err := c.cc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, opts...)
    if err != nil {
        return nil, err
    }
    return out, nil
}

// GreeterServer is the server API for Greeter service.
type GreeterServer interface {
    // Sends a greeting
    SayHello(context.Context, *HelloRequest) (*HelloReply, error)
}

func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) {
    s.RegisterService(&_Greeter_serviceDesc, srv)
}

func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
    in := new(HelloRequest)
    if err := dec(in); err != nil {
        return nil, err
    }
    if interceptor == nil {
        return srv.(GreeterServer).SayHello(ctx, in)
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: "/helloworld.Greeter/SayHello",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest))
    }
    return interceptor(ctx, in, info, handler)
}

var _Greeter_serviceDesc = grpc.ServiceDesc{
    ServiceName: "helloworld.Greeter",
    HandlerType: (*GreeterServer)(nil),
    Methods: []grpc.MethodDesc{
        {
            MethodName: "SayHello",
            Handler:    _Greeter_SayHello_Handler,
        },
    },
    Streams:  []grpc.StreamDesc{},
    Metadata: "helloworld.proto",
}

生成文件包含服務端接口GreeterServer描述,客戶端greeterClient接口及實現,以及HelloRequest、HelloResponse結構體。

4、服務端

在server子目錄下創建server.go文件:

package main

import (
   "context"
   "net"

   "google.golang.org/grpc"
   pb "helloworld/proto"
   "google.golang.org/grpc/reflection"
   "google.golang.org/grpc/grpclog"
)

const (
   // Address gRPC服務地址
   port = ":50051"
)

// server is used to implement helloworld.GreeterServer.
type server struct{}

// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
   return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}

func main() {
   lis, err := net.Listen("tcp", port)
   if err != nil {
      grpclog.Fatalf("failed to listen: %v", err)
   }
   // 實例化gRPC Server
   s := grpc.NewServer()
   // 注冊服務
   pb.RegisterGreeterServer(s, &server{})
   // Register reflection service on gRPC server.
   reflection.Register(s)
   if err := s.Serve(lis); err != nil {
      grpclog.Fatalf("failed to serve: %v", err)
   }
}

服務端引入編譯后的proto包,實現約定的SayHello接口方法,接口描述可以查看helloworld.pb.go文件中的GreeterServer接口描述。實例化grpc Server并注冊GreeterService,開始提供服務。

5、客戶端

客戶端使用gRPC訪問服務端:

package main

import (
   "context"
   "os"
   "time"

   "google.golang.org/grpc"
   pb "helloworld/proto"
   "log"
)

const (
   address     = "localhost:50051"
   defaultName = "world"
)

func main() {
   // Set up a connection to the server.
   conn, err := grpc.Dial(address, grpc.WithInsecure())
   if err != nil {
      log.Fatalf("did not connect: %v", err)
   }
   defer conn.Close()
   c := pb.NewGreeterClient(conn)

   // Contact the server and print out its response.
   name := defaultName
   if len(os.Args) > 1 {
      name = os.Args[1]
   }
   ctx, cancel := context.WithTimeout(context.Background(), time.Second)
   defer cancel()
   r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})
   if err != nil {
      log.Fatalf("could not greet: %v", err)
   }
   log.Printf("Greeting: %s", r.Message)
}
// output:
// 2018/12/17 19:57:47 Greeting: Hello world

客戶端初始化連接后直接調用聲明的方法,即可向服務端發起請求。

6、運行測試

在server目錄下啟動Server:
go run main.go
在client目錄下啟動客戶端:
go run main.go
客戶端接收到服務端的響應:
2018/12/17 20:03:44 Greeting: Hello world

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

旌德县| 长宁区| 沽源县| 禄丰县| 密山市| 定襄县| 榆社县| 宁河县| 泽库县| 成武县| 娱乐| 华亭县| 新乡市| 阳曲县| 怀集县| 神池县| 琼海市| 旅游| 嵊泗县| 英德市| 云安县| 什邡市| 哈巴河县| 仙居县| 铜鼓县| 寻乌县| 南江县| 仁布县| 宜宾市| 洪雅县| 东台市| 兴化市| 维西| 麦盖提县| 象州县| 罗源县| 荃湾区| 永善县| 霞浦县| 准格尔旗| 平遥县|