真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

gRPC快速入門(mén)(四)——gRPC快速入門(mén)-創(chuàng)新互聯(lián)

gRPC快速入門(mén)(四)——gRPC快速入門(mén)

一、gRPC簡(jiǎn)介

1、gRPC簡(jiǎn)介

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

創(chuàng)新互聯(lián)公司專(zhuān)業(yè)為企業(yè)提供饒平網(wǎng)站建設(shè)、饒平做網(wǎng)站、饒平網(wǎng)站設(shè)計(jì)、饒平網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、饒平企業(yè)網(wǎng)站模板建站服務(wù),十余年饒平做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

2、gRPC的優(yōu)點(diǎn)

gRPC優(yōu)點(diǎn)如下:
(1)平臺(tái)無(wú)關(guān),語(yǔ)言無(wú)關(guān),可擴(kuò)展;
(2)提供了友好的動(dòng)態(tài)庫(kù),使用簡(jiǎn)單;
(3)解析速度快,比對(duì)應(yīng)的XML快約20-100倍;
(4)序列化數(shù)據(jù)非常簡(jiǎn)潔、緊湊,與XML相比,其序列化之后的數(shù)據(jù)量約為1/3到1/10。

3、gRPC安裝

官方推薦安裝命令:
go get google.golang.org/grpc
國(guó)內(nèi)網(wǎng)絡(luò)環(huán)境由于GFW原因,不能直接訪問(wèn)google服務(wù)器,報(bào)錯(cuò)如下:
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)
因此,在國(guó)內(nèi)網(wǎng)絡(luò)環(huán)境下推薦直接從GitHub下載相應(yīng)依賴(lài)進(jìn)行安裝。

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)編寫(xiě).proto描述文件。
(2)編譯生成.pb.go文件。
(3)服務(wù)端實(shí)現(xiàn)約定的接口并提供服務(wù)。
(4)客戶端按照約定調(diào)用方法請(qǐng)求服務(wù)。

2、proto service定義

一個(gè)RPC service是一個(gè)能夠通過(guò)參數(shù)和返回值進(jìn)行遠(yuǎn)程調(diào)用的方法。由于gRPC通過(guò)將數(shù)據(jù)編碼成Protocal Buffer來(lái)實(shí)現(xiàn)傳輸,因此,使用者可以通過(guò)Protocal Buffers interface definitioin language(IDL)來(lái)定義service method,同時(shí)將參數(shù)和返回值也定義成Protocal Buffer message類(lèi)型。gRPC源碼目錄提供了多個(gè)使用示例,本文使用helloworld示例作為模板,helloworld示例目錄位于google.golang.org/grpc/examples/helloworld。
在$GOPATH/src目錄下創(chuàng)建helloworld目錄,包含proto、server、client子目錄。proto目錄下創(chuàng)建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文件中定義了一個(gè)Greeter Service,服務(wù)包含一個(gè)SayHello方法,同時(shí)聲明了HelloRequest和HelloReply消息結(jié)構(gòu)用于請(qǐng)求和響應(yīng)??蛻舳耸褂肏elloRequest參數(shù)調(diào)用SayHello方法請(qǐng)求服務(wù)端,服務(wù)端響應(yīng)HelloReply消息。

3、生成Go代碼

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

// 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",
}

生成文件包含服務(wù)端接口GreeterServer描述,客戶端greeterClient接口及實(shí)現(xiàn),以及HelloRequest、HelloResponse結(jié)構(gòu)體。

4、服務(wù)端

在server子目錄下創(chuàng)建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服務(wù)地址
   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)
   }
   // 實(shí)例化gRPC Server
   s := grpc.NewServer()
   // 注冊(cè)服務(wù)
   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)
   }
}

服務(wù)端引入編譯后的proto包,實(shí)現(xiàn)約定的SayHello接口方法,接口描述可以查看helloworld.pb.go文件中的GreeterServer接口描述。實(shí)例化grpc Server并注冊(cè)GreeterService,開(kāi)始提供服務(wù)。

5、客戶端

客戶端使用gRPC訪問(wèn)服務(wù)端:

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

客戶端初始化連接后直接調(diào)用聲明的方法,即可向服務(wù)端發(fā)起請(qǐng)求。

6、運(yùn)行測(cè)試

在server目錄下啟動(dòng)Server:
go run main.go
在client目錄下啟動(dòng)客戶端:
go run main.go
客戶端接收到服務(wù)端的響應(yīng):
2018/12/17 20:03:44 Greeting: Hello world

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性?xún)r(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。


當(dāng)前名稱(chēng):gRPC快速入門(mén)(四)——gRPC快速入門(mén)-創(chuàng)新互聯(lián)
文章位置:http://weahome.cn/article/dshgdo.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部