日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

程序员如何用gRPC谈一场恋爱

發布時間:2024/2/28 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 程序员如何用gRPC谈一场恋爱 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.




導語: 本文以幽默詼諧的方式,介紹gRPC的4種client-server服務模式的開發實踐及應用場景


前言:為什么要寫這篇文章?
  • The best way to learn is to teach. gRPC的examples里的例子是一個簡易的router,瑣碎的業務代碼很多,看起來比較繞。于是就自己寫一個例子,看看自己是否都將這些知識點掌握了。

  • 談戀愛的過程,其實跟client-server服務模式非常像。單獨講這4種模式有些無聊,所以就嘗試用一種盡量有趣的方式去介紹,順便也可以作為某些男生的一份簡單的戀愛指南。


gRPC client-server服務模式

這里先將重要的結論寫出來,方便以后查閱,具體介紹見下文。找不到準確的中文來翻譯這幾種模式,就保留了英文。


  • ?0x1: A simple RPC?

    最簡單的一發一收的client-server模型。這就是我們用得最多的模式



  • ?0x2:?A client-to-server streaming RPC

    client先建立長連接,然后發送多個request給server,server最后統一回一個rsp

?????應用場景:

  • agent上報CPU,內存等數據到server

  • 客戶端心跳

  • 客戶端并發調用細小粒度的接口。比如有5個后臺接口A B C D E,客戶端在不同頁面,可以調用不同的接口組合。比如在個人頁,就調用ABC;在動態頁面,就調用CDE,后臺都只會有一個rsp。這種模式的好處就是讓后臺可以將接口的粒度細化,客戶端調用靈活,減少重復代碼,提高復用率


    • 0x3: A server-to-client streaming RPC?

      client先發一個請求到server,然后server不停的回包

    ? ? ? 應用場景:

  • 股票app??蛻舳讼蚍斩税l送一個股票代碼,服務端就把該股票的實時數據源源不斷的返回給客戶端

  • app的在線push。client先發請求到server注冊,然后server就可以發在線push了



    • 0x4: A Bidirectional streaming RPC?

      建立一個長連接,然后client和server可以隨意收發數據

    ? ? ? 應用場景:

  • 聊天機器人

  • 有狀態的游戲服務器進行數據交換。比如LOL,王者榮耀等競技游戲,client和server之間需要非常頻繁地交換數據


    • 總結:除了一發一收的模式,client-to-server與server-to-client這兩種模式,其實用雙向RPC都可以做到。但是雙向RPC的編碼難度更高(后面例子中可以看到),異常處理也需要更仔細,所以具體使用哪種模式需要根據具體需求來分析

    接下來就讓我用一個男女生之間的交往故事來說明這4種服務模式。內容純屬虛構,并故意寫得比較搞笑。如果有不恰當的描述,請告訴我。


    男女生交往之gRPC的4種模式

    一些說明

    • Selina:女生名字,client

    • John:男生名字,server

    • 等等,女生是client,男生是server。那么,女生給男生提要求,是不是就是client向server請求數據一樣自然!!!!噢噢噢,這應該是我學編程以來,領悟到的最重要的道理吧!!!


    基礎代碼說明

    • client

    // 建立跟server的連接 conn, err := grpc.Dial(love_const.Address, grpc.WithInsecure())

    (左滑可查看完整代碼,下同)


    • server

    //?設置監聽協議與端口 lis, err := net.Listen("tcp", love_const.Address) //?初始化gRPC?server實例 grpcServer := grpc.NewServer() //?注冊命令字與處理函數 love_proto.RegisterBehaviorServer(grpcServer,?newServer()) //?啟動服務 grpcServer.Serve(lis)



    0x1: A simple RPC


    • Selina職場工作不順,剛被leader說了一頓,又恰好來大姨媽了,心情十分不好,問John:在哪

    • John正在打游戲,非常忙,未察覺出Selina的語氣有異樣,說:剛起床,在打游戲呢

    Selina: "在哪" Jhon: "剛起床,在打游戲呢"

    這種模式就是我們用得最多的模式,一發一收


    • client代碼

    response, err := client.WhereAreYou(ctx, message)


    • server代碼

    func (s *loveServer) WhereAreYou(ctx context.Context, message *love_proto.Message) (*love_proto.Response, error) { rsp := new(love_proto.Response) rsp.Words = "剛起床,在打游戲呢" return rsp, nil }



    0x2:?A client-to-server streaming RPC


    • Selina開始向John訴苦,說了很多話

    • John忙著打游戲,只看清“我來大姨媽了”,就只回了一句:哦,多喝熱水

    Selina: "你在干嘛" Selina: "我不開心" Selina: "我要和你說話" Selina: "你怎么還不打電話過來" Selina: "我來大姨媽了" Jhon: "哦,多喝熱水"


    這種模式是client先建立長連接,然后發送多個request給server,server最后統一回一個rsp。


    應用場景

  • agent收集CPU,內存等數據到server

  • 客戶端心跳

  • 客戶端并發調用細小粒度的接口。比如有5個后臺接口A B C D E,客戶端在不同頁面,可以調用不同的接口組合,比如在個人頁,就調用ABC;在動態頁面,就調用CDE,后臺都只會有一個rsp。這種模式的好處就是讓后臺可以將接口的粒度細化,客戶端調用靈活,減少重復代碼,提高復用率

    • client代碼

    // 獲取一個stream對象 stream, err := client.ContinuousCall(ctx) if?err?!=?nil?{ log.Fatalf("%v.ContinuousCall(_) = _, %v", client, err) } // 通過stream來發送多個message for _, message := range messages { fmt.Printf("message words: %s\n", message.Words) if err := stream.Send(message); err != nil { log.Fatalf("%v.Send(%v) = %v", stream, message, err) } } // 發送EOF給server,然后收取server的回包 reply, err := stream.CloseAndRecv() if err != nil { log.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil) }


    • server代碼

    for { //?不斷收取client的發包 message, err := stream.Recv() // 當客戶端發送EOF時說明要給回包了 if err == io.EOF { rsp := new(love_proto.Response) rsp.Words = "哦,多喝熱水" return stream.SendAndClose(rsp) } if err != nil { return err } printGirlWords(message.Words) }



    0x3: A server-to-client streaming RPC


    • Selina生氣了

    • John先一直想解決方案,然后發現沒有回應,就要買禮物,安慰等措施:包治百病

    Selina: "這么久不給我打電話,你是不是不愛我了?" Jhon: "啊,寶貝你怎么了?" Jhon: "我剛剛在玩游戲,那一局剛開,我走不開啊" Jhon: "你不能不講道理啊" Jhon: "你都20分鐘不回我了" Jhon: "好了,寶貝,我錯了,都是我的錯" Jhon: "你在家等我,我過去接你,帶你去買包包"


    這種模式是client先發一個請求到server,然后server不停的回包

    應用場景

  • 股票app。客戶端向服務端發送一個股票代碼,服務端就把該股票的實時數據源源不斷的返回給客戶端

  • app的在線push。client先發請求到server注冊,然后server就可以發在線push了

    • client代碼

    // 獲取stream對象,并發送一個消息 stream, err := client.LoveOrNot(ctx, message) if err != nil { log.Fatalf("%v.LoveOrNot(_) = _, %v", client, err) } for { // 不斷收取server回包 response,?err?:=?stream.Recv() // EOF表示server發包結束 if err == io.EOF { break } if err != nil { log.Fatalf("%v.LoveOrNot(_) = _, %v", client, err) } log.Printf("rsp: %s", response.Words) }


    • server代碼

    for _, response := range responses { // 不停向client發消息 if err := stream.Send(response); err != nil { return err } }



    0x4: A Bidirectional streaming RPC


    • John道歉,買禮物,Selina不再生氣,于是開始聊天

    Selina: "好呀好呀" Jhon: "寶貝我很快就到啦" Selina: "等我化妝" Jhon: "寶貝我很快就到啦" Selina: "親愛的你最好啦" Jhon: "寶貝我很快就到啦" Selina: "么么噠" Jhon: "寶貝我很快就到啦"


    這種模式就是建立一個長連接,然后client和server可以隨意收發數據

    應用場景

  • 聊天機器人

  • 有狀態的游戲服務器進行數據交換。比如LOL,王者榮耀等競技游戲,client和server之間需要非常頻繁地交換數據


    • client代碼

    // 獲取stream對象 stream, err := client.LoveChat(ctx) if err != nil { log.Fatalf("%v.LoveChat(_) = _, %v", client, err) } // 這個管道沒有太多實際意義,只是為了讓client將rsp都收完整 waitc := make(chan struct{}) go func() { for { // 不停地收server的包 response, err := stream.Recv() // server回包EOF,然后關閉管道 if err == io.EOF { // read done. close(waitc) log.Printf("EOF return") return } if err != nil { log.Fatalf("Failed to receive a note : %v", err) } log.Printf("rsp: %s", response.Words) } }() // 每隔一秒向server發一個消息,模擬聊天場景 for _, message := range messages { time.Sleep(1 * time.Second) if err := stream.Send(message); err != nil { log.Fatalf("Failed to send a message: %v", err) } } // 這里告訴server: client已經將數據發完了(其實就是給server發一個EOF),server會返回一個io.EOF stream.CloseSend() <-waitc


    • server代碼

    for { // 不斷收取client發包 message, err := stream.Recv() if err == io.EOF { return nil } if err != nil { return err } for _, response := range responses { // 給client發包 if err := stream.Send(response); err != nil { return err } } }

    男生們看過來,看過來


    • 既然標題寫了“用gRPC教程序員談戀愛”,那么肯定就得給點干貨。女生可能天生比男生更感性一些,所以當女生在傾訴問題的時候,千萬不要只去想解決方案,而是要盡快地安慰女生,傾聽她的吐槽,順著她的思路去稍微吐槽下。可以換位思考,如果你自己心情不好的時候,肯定也想有人來安慰,而不是想聽到”你要看開一點,這樣工作效率才會高”之類的解決方案的話

    • 在傾聽和安慰之后,然后把問題解決,或者幫助女生把問題解決。做和說同樣重要。



    總結

    以上是生活随笔為你收集整理的程序员如何用gRPC谈一场恋爱的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。