1. 首頁 > 汽車知識網 > 汽車知識

    go語言中文社區,谷歌放棄golang了

    gRPC簡介

    gRPC () 是一個由Google開發的高性能、開源、跨多種編程語言和通用的遠程過程調用協議(RPC) 框架,用于客戶端和服務器端之間的通信,使用HTTP/2協議并將 ProtoBuf ()作為序列化工具。

    gRPC模式

    gRPC主要有4種請求/響應模式,分別是:

    (1) 簡單模式(Simple RPC)

    (2) 服務端數據流模式(Server-side streaming RPC)

    這種模式是客戶端發起一次請求,服務端返回一段連續的數據流。典型的例子是客戶端向服務端發送一個股票代碼,服務端就把該股票的實時數據源源不斷的返回給客戶端。

    (3) 客戶端數據流模式(Client-side streaming RPC)

    (4) 雙向數據流模式(Bidirectional streaming RPC)

    顧名思義,這是客戶端和服務端都可以向對方發送數據流,這個時候雙方的數據可以同時互相發送,也就是可以實現實時交互。典型的例子是聊天機器人。

    雙向數據流實戰

    1、proto定義

    2// 包名: chat

    3package chat;

    4/*

    5 服務名: Chat。

    6 其中只有 名為“BidStream”的一個RPC服務。

    7 輸入是 Request格式的數據流, 輸出是 Response 格式的數據流

    8*

    9service Chat {

    10 rpc BidStream(stream Request) returns (stream Response) {}

    11}

    12// 請求數據 Request格式定義

    13message Request {

    14 string input = 1;

    15}

    16// 響應數據Response格式定義

    17message Response {

    18 string output = 1;

    19}

    服務端程序 server.go

    2import (

    3 "io"

    4 "log"

    5 "net"

    6 "strconv"

    7 "google.golang.org/grpc"

    8 proto "chat" // 自動生成的 proto代碼

    9)

    go語言中文社區

    10// Streamer 服務端

    11type Streamer struct{}

    12// BidStream 實現了 ChatServer 接口中定義的 BidStream 方法

    13func (s *Streamer) BidStream(stream proto.Chat_BidStreamServer) error {

    14 ctx := stream.Context()

    15 for {

    16 select {

    17 case <-ctx.Done():

    18 log.Println("收到客戶端通過context發出的終止信號")

    19 return ctx.Err()

    20 default:

    21 // 接收從客戶端發來的消息

    22 輸入,err := stream.Recv()

    23 if err == io.EOF {

    24 log.Println("客戶端發送的數據流結束")

    25 return nil

    26 }

    27 if err != nil {

    28 log.Println("接收數據出錯:",err)

    29 return err

    30 }

    31 // 如果接收正常,則根據接收到的 字符串 執行相應的指令

    32 switch 輸入.Input {

    33 case "結束對話 ":

    這個項目可以理解為針對互聯網IT人打造的中文版awesome-go。已有的awesome-go項目, 匯總了很多go開源項目, 但存在的問題是收集太全了, 而且每個項目沒有詳細描述。本項目作為awesome-go的一個擴展,根據go語言中文社區提供的。

    34 log.Println("收到'結束對話'指令")

    36 return err

    37 }

    38 // 收到結束指令時,通過 return nil 終止雙向數據流

    39 return nil

    40 case "返回數據流 ":

    41 log.Println("收到'返回數據流'指令")

    42 // 收到 收到'返回數據流'指令, 連續返回 10 條數據

    43 for i := 0; i < 10; i++ {

    44 if err := stream.Send(&proto.Response{Output: "數據流 #" + strconv.Itoa(i)}); err != nil {

    45 return err

    46 }

    47 }

    社區活躍度更高,更強調社區的作用,有[RFC](GitHub - rust-lang/rfcs: RFCs for changes to Rust)。[中文社區](Rust China)也有了 Rust的劣勢是:語言特性復雜,對新手就不會那么友好 穩定性不夠,語言的進化較激進 。

    48 default:

    49 // 缺省情況下, 返回 '服務端返回: ' + 輸入信息

    50 log.Printf("[收到消息]: %s",輸入.Input)

    51 if err := stream.Send(&proto.Response{Output: "服務端返回: " + 輸入.Input}); err != nil {

    52 return err

    53 }

    54 }

    55 }

    56 }

    57}

    58func main() {

    59 log.Println("啟動服務端...")

    60 server := grpc.NewServer()

    61 // 注冊 ChatServer

    62 proto.RegisterChatServer(server,&Streamer{})

    63 address,err := net.Listen("tcp",":3000")

    64 if err != nil {

    65 panic(err)

    66 }

    67 if err := server.Serve(address); err != nil {

    68 panic(err)

    69 }

    70}

    客戶端程序 client.go

    2import (

    3 "bufio"

    4 "context"

    5 "io"

    6 "log"

    7 "os"

    8 "google.golang.org/grpc"

    9 proto "chat" // 根據proto文件自動生成的代碼

    10)

    11func main() {

    12 // 創建連接

    14 if err != nil {

    15 log.Printf("連接失敗: [%v] ",err)

    16 return

    17 }

    18 defer conn.Close()

    19 //

    20 client := proto.NewChatClient(conn)

    21 //

    22 ctx := context.Background()

    23 // 創建雙向數據流

    24 stream,err := client.BidStream(ctx)

    25 if err != nil {

    26 log.Printf("創建數據流失敗: [%v] ",err)

    27 }

    28 // 啟動一個 goroutine 接收命令行輸入的指令

    29 go func() {

    30 log.Println("請輸入消息...")

    31 輸入 := bufio.NewReader(os.Stdin)

    32 for {

    33 // 獲取 命令行輸入的字符串, 以回車 作為結束標志

    34 命令行輸入的字符串,_ := 輸入.ReadString(' ')

    35 // 向服務端發送 指令

    36 if err := stream.Send(&proto.Request{Input: 命令行輸入的字符串}); err != nil {

    37 return

    38 }

    39 }

    40 }()

    41 for {

    42 // 接收從 服務端返回的數據流

    43 響應,err := stream.Recv()

    Go 由于不支持泛型而臭名昭著,但最近,泛型已接近成為現實。Go 團隊實施了一個看起來比較穩定的設計草案,并且正以源到源翻譯器原型的形式獲得關注。本文講述的是泛型的最新設計,以及如何自己嘗試泛型。例子FIFO Stack 假設。

    44 if err == io.EOF {

    45 log.Println("?? 收到服務端的結束信號")

    46 break //如果收到結束信號,則退出“接收循環”,結束客戶端程序

    47 }

    48 if err != nil {

    49 // TODO: 處理接收錯誤

    50 log.Println("接收數據出錯:",err)

    51 }

    52 // 沒有錯誤的情況下,打印來自服務端的消息

    53 log.Printf("[客戶端收到]: %s",響應.Output)

    54 }

    55}

    運行效果

    先啟動服務端程序 server.go

    再啟動客戶端程序 client.go

    輸入消息,結果類似下圖:

    總結

    gRPC是個很強大的RPC框架,而且支持多語言編程,上面的服務端、客戶端程序我們完全可以用不同的語言實現,比如服務端用JAVA,客戶端用Python...

    gRPC的四種交互模式也給我們提供了很大的發揮空間,最近Nginx宣布支持gRPC,這可能也預示著某種趨勢...

    異步社區是一個有料、有貨,又專業的IT專業圖書社區,在這里可以讀到最新、最熱的IT類圖書!

    我想要社區的《Git高手之路》這本書,這本書是網絡編程的經典圖書,請大家幫我點贊!

    本文摘自異步社區,作者:阿貍不歌 作品:《gRPC雙向數據流的交互控制(go語言實現)》

    版權聲明:本站文章均來源于網絡,如有侵權請聯系刪除!

    聯系我們

    在線咨詢:點擊這里給我發消息

    QQ:

    工作日:9:30-18:30,節假日休息

    老婆的视频完整版在线观看