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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

iframe的src怎么携带参数_三种传递gRPC动态参数方式的使用体验

發(fā)布時間:2023/12/19 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iframe的src怎么携带参数_三种传递gRPC动态参数方式的使用体验 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

gRPC是一個遠程調用框架,使用Protobuf做為信息的載體來完成客戶端和服務端的數(shù)據(jù)傳輸。關于怎么定義Protobuf消息、搭建gRPC服務在之前的系列文章中都有提及,今天來說一下在使用gRPC和Protobuf的過程中怎么傳遞動態(tài)參數(shù)。

首先說明一下,這里所說的動態(tài)參數(shù)指的是在定義Protobuf消息時還不能確定其具體內容的復合類型字段,簡單的說就是消息里的這個字段我們想傳一個類似JSON對象、Map字典、結構體等等這樣的組合值,但是JSON里有哪些字段、每個字段值是什么類型或者Map字典鍵值的類型我們在定義消息時還無法確定(能確定就可以定義子消息嵌套進來了,不在本文的討論范圍內),把這樣的Protobuf消息字段叫做動態(tài)參數(shù)。

針對通過Protobuf傳遞動態(tài)參數(shù)的需求,官方文檔里并沒有給出標準的解決方案,目前我所知道的能夠通過bytes、Map以及proto.Struct這三種Protobuf消息字段的類型實現(xiàn),每種方式也都有自己的優(yōu)勢和劣處,如果你碰巧知道更好的實現(xiàn)方案,歡迎在評論里留言討論。

下面我們就來看一下使用這三種消息字段的類型如何實現(xiàn)動態(tài)參數(shù)的傳遞。

使用bytes傳遞JSON對象參數(shù)

Protobuf里的bytes類型的字段編碼成Go代碼后對應的是Go里的字節(jié)切片[]byte類型。所以我們可以把動態(tài)參數(shù)的字段類型定義成bytes類型,這樣客戶端把JSON對象傳遞到服務端后,服務端能直接對動態(tài)參數(shù)里包含的JSON對象做解碼操作,省去了一次從string到[]byte的類型轉換。

舉個例子來說,在下面的Protobuf消息定義里info字段的類型是bytes

rpc?UpdateRecord?(UpdateRecordRequest)?returns?(UpdateRecordReply)?{
}
????
message?UpdateRecordRequest?{
????int64?id?=?1;
????bytes?info?=?2;
}

那么在使用對于這個gRPC方法,客戶端在使用的時候,直接把info數(shù)據(jù)通過json.Marshal編碼后傳遞給服務端即可。

info?:=?struct?{
??name?string
??age??int
}?{
???name:?"James",
???age:?20,
}
jsonInfo,?_?:=?json.Marshal(info)
_?:=?AppService.UpdateRecord(&AppService.UpdateRecordRequest{id:?2,?info:?jsonInfo})

在服務端可以加一個參數(shù)驗證,保證傳遞過來的是一個正確的JSON對象。

func?IsJSON(in?[]byte)?bool?{
?var?js?map[string]interface{}
?return?json.Unmarshal(in,?&js)?==?nil

}

驗證完后就可以根據(jù)實際的使用需求解碼動態(tài)參數(shù)里的JSON對象解析到具體的結構體變量。

type?Info?struct?{
?name?string?`json:"name"`
?age?int?`json:"id"`
}

func?(s?server)?UpdateRecord(ctx?context.Context,?reqeust?*AppService.UpdateRecordRequest)?(reply?*AppService.UpdateRecordReply,?err?error)?{
??if?!isJson(req.Info)?{
????//?錯誤處理
????...
??}
??v?:=?Info{}
??json.Unmarshal(req.Info,?$v)
}

我一般是這種方法,感覺比較方便,唯一算是麻煩的地方就是每個使用動態(tài)參數(shù)的地方要自己定義解析JSON對象對應的結構體類型。

使用Map類型傳遞動態(tài)參數(shù)

如果你不想通過JSON對象來傳遞參數(shù),另一種經(jīng)常能想到的方案是把參數(shù)的字段類型定義成字典,具體每次調用時可以根據(jù)需要設置不同的Key-Value對。Protobuf恰好也有Map類型。

map?map_field?=?N;

但是有一點,在定義Map類型時,值的類型必須是固定的,并不支持像map[string]interface{}這樣的值類型。所以這種方式一般是在能確定字典參數(shù)的值類型時使用,否則如果定義成了map的話假如要傳遞整型的字段,客戶端還需要先將數(shù)據(jù)從整型轉換成字符串類型。

使用proto.Struct傳遞結構體動態(tài)參數(shù)

有些資料里提到了使用Protobuf里自帶了一個復合類型proto.Struct傳遞動態(tài)類型參數(shù),使用它的好處是它看起來是Protobuf對動態(tài)類型數(shù)據(jù)的一種原生支持,可以使用Protobuf自帶的包jsonpb 完成從JSON到proto.Struct之間的轉換。

使用proto.Struct類型需要在proto文件里先引入它的類型定義,像下面這樣。

syntax?=?"proto3";
package?messages;
import?"google/protobuf/struct.proto";

service?UserService?{
????rpc?SendJson?(SendJsonRequest)?returns?(SendJsonResponse)?{}
}

message?SendJsonRequest?{
????string?UserID?=?1;
????google.protobuf.Struct?Details?=?2;
}

message?SendJsonResponse?{
????string?Response?=?1;
}

通過proto.Struct的源碼定義能看到它底層其實是一個名叫Struct的消息,里面只包含了一個名叫fileds的Map類型字段,通過Protobuf的Oneof特性指定了Map值的類型范圍來近似完成了動態(tài)類型的支持。

message?Struct?{
??//?Unordered?map?of?dynamically?typed?values.
??map?fields?=?1;
}
message?Value?{
??//?The?kind?of?value.
??oneof?kind?{
????//?Represents?a?null?value.
????NullValue?null_value?=?1;
????//?Represents?a?double?value.
????double?number_value?=?2;
????//?Represents?a?string?value.
????string?string_value?=?3;
????//?Represents?a?boolean?value.
????bool?bool_value?=?4;
????//?Represents?a?structured?value.
????Struct?struct_value?=?5;
????//?Represents?a?repeated?`Value`.
????ListValue?list_value?=?6;
??}
}

所以在使用的時候操作proto.Struct有點像操作字典,下面是一個使用的示例。

func?sendJson(userClient?pb.UserServiceClient,?ctx?context.Context)?{
????var?item?=?&structpb.Struct{
????????Fields:?map[string]*structpb.Value{
????????????"name":?&structpb.Value{
????????????????Kind:?&structpb.Value_StringValue{
????????????????????StringValue:?"James",
????????????????},
????????????},
????????????"age":?&structpb.Value{
????????????????Kind:?&structpb.Value_NumberValue{
????????????????????NumberValue:?20,
????????????????},
????????????},
????????},
????}

????userGetRequest?:=?&pb.SendJsonRequest{
????????UserID:?"A123",
????????Details:?item,
????}

????res,?err?:=?userClient.SendJson(ctx,?userGetRequest)
}

總結

三種方法總結下來我還是覺得第一種使用起來更方便,第二種只能把值類型局限為一種,否則就需要在客戶端和服務端做類型轉換,第三種也是網(wǎng)上能找到對proto.Struct的使用的資料較少,上手難度較大,且也不如第一種靈活。另外Protobuf還有一個Any類型,讓我們使用的時候不需要定義消息,但是要攜帶一個說明數(shù)據(jù)的url使用起來感覺也不太方便。這塊如果讀者朋友們相關經(jīng)驗可以一起來探討一下。

最后做一個投票,針對gRPC動態(tài)參數(shù)這種需求大家都是怎么解決?

推薦閱讀:gRPC服務注冊發(fā)現(xiàn)及負載均衡的實現(xiàn)方案與源碼解析

- END -

關注公眾號,每周幫你學會一個進階知識

總結

以上是生活随笔為你收集整理的iframe的src怎么携带参数_三种传递gRPC动态参数方式的使用体验的全部內容,希望文章能夠幫你解決所遇到的問題。

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