亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

gRPC 可能出現零服務器消息嗎?

gRPC 可能出現零服務器消息嗎?

Go
白豬掌柜的 2023-06-19 14:12:02
在下面的gRPC客戶端代碼中,第二個是if必要的嗎?status, err := cli.GetStatus(ctx, &empty.Empty{})if err != nil {    return err}if status == nil {    // this should NEVER happen - right?    return fmt.Errorf("nil Status result returned") }go 直覺上,為了以防萬一,應該總是檢查 nil 。但是,有一個運行時檢查來捕獲任何客戶端到服務器的nil使用,例如status, err := cli.GetStatus(ctx, nil) // <- runtime errorif err != nil {    // "rpc error: code = Internal desc = grpc: error while marshaling: proto: Marshal called with nil"    return err}那么是否有類似的服務器到客戶端運行時保證,從而消除檢查的需要status == nil?
查看完整描述

2 回答

?
ITMISS

TA貢獻1871條經驗 獲得超8個贊

使用人為的服務器示例進一步調查:


func (s *mygRPC) GetStatus(context.Context, *empty.Empty) (*pb.Status, error) {

? ? log.Println("cli: GetStatus()")


? ? //return &pb.Status{}, nil

? ? return nil, nil // <- can server return a nil status message (with nil error)

}

并測試客戶端/服務器的反應:


客戶:


ERROR: rpc error: code = Internal desc = grpc: error while marshaling: proto: Marshal called with nil

服務器:


2019/05/14 16:09:50 cli: GetStatus()

ERROR: 2019/05/14 16:09:50 grpc: server failed to encode response:? rpc error: code = Internal desc = grpc: error while marshaling: proto: Marshal called with nil

因此,即使想要合法地返回一個 nil 值,gRPC傳輸也不會允許。


注意:服務器端代碼仍在執行 - 正如預期的那樣 - 但就客戶端而言,調用gRPC失敗了。


結論:有效的 ( err==nil) 服務器響應將始終返回有效的 ( 非nil) 消息。


編輯:


檢查源代碼可以揭示捕獲消息的gRPC位置:nil


服務器.go

func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, cp Compressor, opts *transport.Options, comp encoding.Compressor) error {

? ? data, err := encode(s.getCodec(stream.ContentSubtype()), msg)

? ? if err != nil {

? ? ? ? grpclog.Errorln("grpc: server failed to encode response: ", err)

? ? ? ? return err

? ? }

? ? // ...

}

rpc_util.go

func encode(c baseCodec, msg interface{}) ([]byte, error) {

? ? if msg == nil { // NOTE: typed nils will not be caught by this check

? ? ? ? return nil, nil

? ? }

? ? b, err := c.Marshal(msg)

? ? if err != nil {

? ? ? ? return nil, status.Errorf(codes.Internal, "grpc: error while marshaling: %v", err.Error())

? ? }

? ? // ...

}

這一行的評論是關鍵:


if msg == nil { // NOTE: typed nils will not be caught by this check }

因此,如果要對我們的 typed-nil 使用 reflect,reflect.ValueOf(msg).IsNil()將返回true. 以下c.Marshal(msg)錯誤 - 調用無法向客戶端發送消息響應。


查看完整回答
反對 回復 2023-06-19
?
小唯快跑啊

TA貢獻1863條經驗 獲得超2個贊

是的,這永遠不應該發生。GRPC 對此負責。



查看完整回答
反對 回復 2023-06-19
  • 2 回答
  • 0 關注
  • 153 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號