自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

gRPC入門指南之 雙向流式RPC

網(wǎng)絡(luò) 通信技術(shù)
與服務(wù)端流式 RPC類似,都只支持單項(xiàng)連續(xù)發(fā)送數(shù)據(jù),今天我們要來(lái)學(xué)習(xí)雙向流式 RPC 支持通信雙方同時(shí)多次發(fā)送或接收數(shù)據(jù)。

[[408239]]

本文轉(zhuǎn)載自微信公眾號(hào)「Golang來(lái)啦」,作者Seekload。轉(zhuǎn)載本文請(qǐng)聯(lián)系Golang來(lái)啦公眾號(hào)。

你好,我是 Seekload!

前言

前一篇文章我們學(xué)習(xí)了客戶端流式 RPC,客戶端多次向服務(wù)端發(fā)送數(shù)據(jù),發(fā)送結(jié)束之后,由服務(wù)端返回一個(gè)響應(yīng)。與服務(wù)端流式 RPC類似,都只支持單項(xiàng)連續(xù)發(fā)送數(shù)據(jù),今天我們要來(lái)學(xué)習(xí)雙向流式 RPC 支持通信雙方同時(shí)多次發(fā)送或接收數(shù)據(jù)。如下如所示:

新建并編譯proto文件

新建 bidirectional_stream.proto 文件:

  1. syntax = "proto3"
  2.  
  3. package proto; 
  4.  
  5. // 定義流式請(qǐng)求信息 
  6. message StreamRequest{ 
  7.   // 參數(shù)類型 參數(shù)名稱 標(biāo)識(shí)號(hào) 
  8.   string data = 1; 
  9.  
  10. // 定義流響應(yīng)信息 
  11. message StreamResponse{ 
  12.   int32 code = 1; 
  13.   string value = 2; 
  14.  
  15. // 定義我們的服務(wù)(可以定義多個(gè)服務(wù),每個(gè)服務(wù)可以定義多個(gè)接口) 
  16. service StreamService{ 
  17.   // 雙向流RPC,需要在請(qǐng)求、響應(yīng)數(shù)據(jù)前加stream 
  18.   rpc Record(stream StreamRequest) returns (stream StreamResponse){}; 

雙向流式 RPC,定義方法時(shí)需要在請(qǐng)求值和返回值之前加上 stream。

進(jìn)入 bidirectional_stream.proto 所在的目錄,使用如下命令編譯文件

  1. protoc --go_out=plugins=grpc:. bidirectional_stream.proto 

執(zhí)行完成之后會(huì)生成 bidirectional_stream.pb.go 文件。

創(chuàng)建server端

  1. package main 
  2.  
  3. import ( 
  4.  pb "go-grpc-example/4-bidirectional_stream_rpc/proto" 
  5.  "google.golang.org/grpc" 
  6.  "io" 
  7.  "log" 
  8.  "net" 
  9.  "strconv" 
  10.  "time" 
  11.  
  12. const ( 
  13.  Address string = ":8000" 
  14.  Network string = "tcp" 
  15.  
  16. // 定義我們的服務(wù) 
  17. type StreamService struct{} 
  18.  
  19. // 實(shí)現(xiàn) Record() 方法 
  20. func (s *StreamService) Record(srv pb.StreamService_RecordServer) error { 
  21.  n := 1 
  22.  for { 
  23.   // 接收數(shù)據(jù) 
  24.   req, err := srv.Recv() 
  25.   if err == io.EOF { 
  26.    return nil 
  27.   } 
  28.   if err != nil { 
  29.    log.Fatalf("stream get from client err: %v", err) 
  30.    return err 
  31.   } 
  32.   // 發(fā)送數(shù)據(jù) 
  33.   err = srv.Send(&pb.StreamResponse{ 
  34.    Code:  int32(n), 
  35.    Value: "This is the " + strconv.Itoa(n) + " message"
  36.   }) 
  37.   if err != nil { 
  38.    log.Fatalf("stream send to client err: %v", err) 
  39.    return err 
  40.   } 
  41.   n++ 
  42.   log.Println("stream get from client: ", req.Data) 
  43.   time.Sleep(1 * time.Second
  44.  } 
  45.  return nil 
  46.  
  47. func main() { 
  48.  // 1.監(jiān)聽端口 
  49.  listener, err := net.Listen(Network, Address) 
  50.  if err != nil { 
  51.   log.Fatalf("listener err: %v", err) 
  52.  } 
  53.  log.Println(Address + " net.Listing..."
  54.  
  55.  // 2.實(shí)例化gRPC實(shí)例 
  56.  grpcServer := grpc.NewServer() 
  57.  
  58.  // 3.注冊(cè)我們的服務(wù) 
  59.  pb.RegisterStreamServiceServer(grpcServer, &StreamService{}) 
  60.  
  61.  // 4.啟動(dòng)gRPC服務(wù)端 
  62.  err = grpcServer.Serve(listener) 
  63.  if err != nil { 
  64.   log.Fatalf("grpc server err: %v", err) 
  65.  } 

在實(shí)現(xiàn)的 Record() 方法中,for() 循環(huán)里面讀取客戶端發(fā)送的消息并返回一個(gè)響應(yīng)數(shù)據(jù)。

運(yùn)行服務(wù)端:

  1. go run server.go 
  2.  
  3. 輸出: 
  4. :8000  net listening... 

創(chuàng)建client端

  1. package main 
  2.  
  3. import ( 
  4.  "context" 
  5.  pb "go-grpc-example/4-bidirectional_stream_rpc/proto" 
  6.  "google.golang.org/grpc" 
  7.  "io" 
  8.  "log" 
  9.  "strconv" 
  10.  "time" 
  11.  
  12. const Address = ":8000" 
  13.  
  14. func main() { 
  15.  // 1.連接服務(wù)端 
  16.  conn, err := grpc.Dial(Address, grpc.WithInsecure()) 
  17.  if err != nil { 
  18.   log.Fatalf("grpc conn err: %v", err) 
  19.  } 
  20.  defer conn.Close() 
  21.  
  22.  // 2.創(chuàng)建gRPC客戶端 
  23.  grpcClient := pb.NewStreamServiceClient(conn) 
  24.  
  25.  // 3.調(diào)用 Record() 方法獲取流 
  26.  stream, err := grpcClient.Record(context.Background()) 
  27.  if err != nil { 
  28.   log.Fatalf("call record err: %v", err) 
  29.  } 
  30.  
  31.  for i := 0; i < 5; i++ { 
  32.   // 4.發(fā)送數(shù)據(jù) 
  33.   err := stream.Send(&pb.StreamRequest{ 
  34.    Data: strconv.Itoa(i), 
  35.   }) 
  36.   if err != nil { 
  37.    log.Fatalf("stream send to server err: %v", err) 
  38.   } 
  39.   // 5.接收服務(wù)端發(fā)送過(guò)來(lái)的數(shù)據(jù) 
  40.   resp, err := stream.Recv() 
  41.   if err == io.EOF { 
  42.    break 
  43.   } 
  44.   if err != nil { 
  45.    log.Fatalf("stream get from server err: %v", err) 
  46.   } 
  47.   log.Printf("stream get from server,code:%v,value:%v", resp.GetCode(), resp.Value) 
  48.   time.Sleep(1 * time.Second
  49.  } 
  50.  // 6.關(guān)閉流 
  51.  err = stream.CloseSend() 
  52.  if err != nil { 
  53.   log.Fatalf("close stream err:%v", err) 
  54.  } 

客戶端代碼,在 for() 循環(huán)里面向服務(wù)端發(fā)送了 5 次消息,并接收服務(wù)端返回的數(shù)據(jù),5次數(shù)據(jù)交互之后調(diào)用 CloseSend() 關(guān)閉流。

運(yùn)行客戶端:

  1. go run client.go 

客戶端輸出:

  1. stream get from server,code:1,value:This is the 1 message 
  2. stream get from server,code:2,value:This is the 2 message 
  3. stream get from server,code:3,value:This is the 3 message 
  4. stream get from server,code:4,value:This is the 4 message 
  5. stream get from server,code:5,value:This is the 5 message 

服務(wù)端輸出:

  1. stream get from client:  0 
  2. stream get from client:  1 
  3. stream get from client:  2 
  4. stream get from client:  3 
  5. stream get from client:  4 

觀察仔細(xì)的同學(xué)會(huì)注意到,客戶端和服務(wù)端是交替輸出的。

總結(jié)

 

這篇文章我們簡(jiǎn)單介紹了 gRPC 的雙向流式 RPC,支持通信雙方同時(shí)多次發(fā)送或接收數(shù)據(jù)。

 

責(zé)任編輯:武曉燕 來(lái)源: Golang來(lái)啦
相關(guān)推薦

2021-06-10 07:49:26

RPCgRPC模式

2021-08-30 07:49:32

NacosSync雙向復(fù)制

2011-11-29 16:38:58

Knockout

2012-02-29 01:03:10

ubuntuLinux

2011-10-18 17:05:45

分布式流式數(shù)據(jù)庫(kù)

2011-03-08 09:22:37

2024-01-02 12:17:44

Go傳統(tǒng)遠(yuǎn)程

2010-08-03 15:19:08

FlexBuilder

2011-05-18 15:15:44

MySQL

2021-03-26 10:31:19

人工智能AIOps

2011-08-03 10:01:20

IOS CoreData 雙向關(guān)系

2010-07-20 16:13:25

Perl線程

2010-12-31 13:30:12

2011-01-10 13:21:45

linuxsamba

2015-09-24 09:54:32

物聯(lián)網(wǎng)

2019-07-18 07:52:01

路由策略IP路由

2022-05-08 16:42:27

Rust編程語(yǔ)言

2024-11-19 15:07:07

2011-03-08 16:50:35

2013-01-08 13:33:07

Android開發(fā)Activity入門指南
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)