欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang?RPC包原理和使用詳細(xì)介紹

 更新時(shí)間:2022年09月14日 09:44:25   作者:whynogome  
golang的rpc支持三個(gè)級(jí)別的RPC:TCP、HTTP、JSONRPC。但Go的RPC包是獨(dú)一無二的RPC,它和傳統(tǒng)的RPC系統(tǒng)不同,它只支持Go開發(fā)的服務(wù)器與客戶端之間的交互,因?yàn)樵趦?nèi)部,它們采用了Gob來編碼

本篇文章旨在通過學(xué)習(xí)rpc包和github上的一個(gè)rpc小項(xiàng)目,熟悉和學(xué)習(xí)golang中各個(gè)包的使用

工作流程

通過閱讀官方文檔,了解了rpc的基本工作模式

  • 第一步,建立一個(gè)用于遠(yuǎn)程調(diào)用的包,存放僅供遠(yuǎn)程調(diào)用使用的方法和類型-
  • 第二步,實(shí)例化包的對(duì)象,并在rpc中注冊(cè)該包,以便之后的調(diào)用
  • 第三步,建立一個(gè)服務(wù)端,接收客戶端的請(qǐng)求,使用編碼器解析請(qǐng)求后,根據(jù)請(qǐng)求中的方法和參數(shù),調(diào)用第二步注冊(cè)的實(shí)例的方法,然后使用編碼器把返回值加密后,返回給客戶端
  • 第四步,建立一個(gè)客戶端,連接服務(wù)端,成功后,向連接發(fā)送使用編碼器加密后的數(shù)據(jù),然后等待服務(wù)端響應(yīng)(同步或異步)。響應(yīng)成功后,使用編碼器解析服務(wù)端返回的數(shù)據(jù)

第三步第四步中,多次用到的編碼器,是rpc包的關(guān)鍵。默認(rèn)情況下,rpc包使用的是go特有的encoding/gob包進(jìn)行數(shù)據(jù)的編碼和解碼。但是當(dāng)我們服務(wù)端和客戶端使用了不同的語言時(shí),若加密方法無法兼容,就會(huì)出現(xiàn)問題,所以rpc包支持自定義編碼器。

工作模式

go的rpc除了支持常規(guī)常規(guī)的tpc+端口的遠(yuǎn)程調(diào)用方式,也支持基于http的遠(yuǎn)程調(diào)用實(shí)現(xiàn)。但是,我都用rpc了,還用個(gè)毛的http形式。不過作為一種形式,我們出于禮貌的簡(jiǎn)單了解下。

http模式

官方文檔的例子,就是使用的http形式的rpc,如下

服務(wù)端

//實(shí)例化rpc遠(yuǎn)程調(diào)用的方法所屬對(duì)象
arith := new(Arith)
//注冊(cè)對(duì)象
rpc.Register(arith)
//把rpc監(jiān)聽 對(duì)應(yīng)到http處理器。即指定http請(qǐng)求addr+port時(shí),調(diào)用的方法
rpc.HandleHTTP()
//獲取監(jiān)聽地址
l, e := net.Listen("tcp", ":1234")
if e != nil {
	log.Fatal("listen error:", e)
}
//開啟一個(gè)go程,持續(xù)處理監(jiān)聽數(shù)據(jù)
go http.Serve(l, nil)

客戶端

//連接 rpc的http服務(wù)端
client, err := rpc.DialHTTP("tcp", serverAddress + ":1234")
if err != nil {
	log.Fatal("dialing:", err)
}
//同步調(diào)用
// 實(shí)例化rpc傳入?yún)?shù)
args := &server.Args{7,8}
//聲明rpc 回復(fù)參數(shù)。傳入和回復(fù)參數(shù),必須與調(diào)用方法中的參入類型一致
var reply int
//調(diào)用rpc注冊(cè)的方法
err = client.Call("Arith.Multiply", args, &reply)
if err != nil {
	log.Fatal("arith error:", err)
}
fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply)
//或:異步調(diào)用
// Asynchronous call
quotient := new(Quotient)
divCall := client.Go("Arith.Divide", args, quotient, nil)
replyCall := <-divCall.Done	// will be equal to divCall

從上面的代碼可以看到,請(qǐng)求服務(wù)端時(shí),需要客戶端在服務(wù)器發(fā)起http請(qǐng)求,如果直接在瀏覽器或者其他工具發(fā)起http請(qǐng)求則報(bào)錯(cuò),因?yàn)榇藭r(shí)rpc.HandleHTTP方法指定的默認(rèn)方法,使用的是默認(rèn)gob編碼器,且只接收connect類型的請(qǐng)求。查看源代碼,如下

直接發(fā)起的http請(qǐng)求,無法使用go獨(dú)有的gob包編碼,rpc服務(wù)端也就無法使用默認(rèn)gob包解碼。

所以我們要寫一個(gè)新的方法代替rpc.HandleHTTp,把http請(qǐng)求綁定到一個(gè)使用其他解碼器的方法上,如下

//注冊(cè)路由和對(duì)應(yīng)的handler
http.HandleFunc("/json", func(rw http.ResponseWriter, r *http.Request) {
//聲明一個(gè)客戶端連接對(duì)象   
var conn io.ReadWriteCloser = struct {
      io.Writer
      io.ReadCloser
   }{
      ReadCloser: r.Body,
      Writer:     rw,
   }
//也可以使用如下方法獲取接管客戶端連接,http處理器不在管理該鏈接,使用完畢后需要自行關(guān)閉鏈接
// conn, _, err := rw.(http.Hijacker).Hijack()
  // if err != nil {
   //   log.Print("rpc hijacking fail: ", err.Error())
    //  return
   // }
   io.WriteString(conn, "HTTP/1.0 rpc-ok\n\n")
   //server.ServeConn(conn)
 //rpc.ServeRequest,指定編碼器,以同步的方式處理請(qǐng)求一次,編碼器內(nèi)不關(guān)閉鏈接,由http服務(wù)處理。適用于http形式的請(qǐng)求,因?yàn)閔ttp是無狀態(tài)的,每次請(qǐng)求都是一個(gè)新的鏈接
//rpc.ServeCodec,指定編碼器,for循環(huán)接收客戶端鏈接的消息,每次消息處理開啟一個(gè)go程,相當(dāng)于異步處理,直到客戶端關(guān)閉或解碼錯(cuò)誤,跳出循環(huán),關(guān)閉連接。適用客戶端,一次連接多次發(fā)送數(shù)據(jù)
   rpc.ServeRequest(jsonrpc.NewServerCodec(conn))})
//監(jiān)聽http請(qǐng)求
http.ListenAndServe("127.0.0.1:1234", nil)

上面代碼中的==jsonrpc.NewServerCodec(conn)==是一個(gè)官方定義好的json格式的編碼器。我們?cè)趆ttp中發(fā)送數(shù)據(jù)時(shí),只要使用json格式,就能被服務(wù)端解析

執(zhí)行g(shù)o文件,在post模擬url請(qǐng)求,如下

服務(wù)器模式

服務(wù)端

//聲明和注冊(cè)rpc方法對(duì)象
//獲取監(jiān)聽信息
lis, err := net.Listen("tcp", ":8082")
	if err != nil {
		log.Fatal(err)
}
//循環(huán)讀取監(jiān)聽到的數(shù)據(jù)
for {
	//獲取一個(gè)客戶端連接
   conn, err := lis.Accept()
   if err != nil {
      continue
   }
   //開啟一個(gè)go程序,使用自定義編碼器處理當(dāng)前獲取連接
   go s.Server.ServeCodec(jsonrpc.NewServerCodec(conn))
}

客戶端

//連接服務(wù)端
conn, err := net.Dial("tcp", ":8082")if err != nil {
	log.Fatal(err)
}
defer conn.Close()
//使用json編碼器新建客戶端
client := &Client{rpc.NewClientWithCodec(jsonrpc.NewServerCodec(conn))}
//聲明rpc方法中傳入和輸出的參數(shù)
resq := message.ArithRequest{A: 20, B: 5}
resp := message.ArithResponse{}
//調(diào)用rpc方法
err = client.Call("ArithService.Add", &resq, &resp)
log.Printf("Arith.Add(%v, %v): %v ,Error: %v", resq.A, resq.B, resp.C, err)

到此這篇關(guān)于golang RPC包原理和使用詳細(xì)介紹的文章就介紹到這了,更多相關(guān)golang RPC包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang之?dāng)?shù)據(jù)驗(yàn)證validator的實(shí)現(xiàn)

    golang之?dāng)?shù)據(jù)驗(yàn)證validator的實(shí)現(xiàn)

    這篇文章主要介紹了golang之?dāng)?shù)據(jù)驗(yàn)證validator的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • go語言context包功能及操作使用詳解

    go語言context包功能及操作使用詳解

    這篇文章主要為大家介紹了go語言context包功能及操作使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • go使用consul實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)及配置共享實(shí)現(xiàn)詳解

    go使用consul實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)及配置共享實(shí)現(xiàn)詳解

    這篇文章主要為大家介紹了go使用consul實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)及配置共享實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Golang中的關(guān)鍵字(defer、:=、go?func())詳細(xì)解讀

    Golang中的關(guān)鍵字(defer、:=、go?func())詳細(xì)解讀

    這篇文章主要介紹了Golang中的關(guān)鍵字(defer、:=、go?func())詳細(xì)解讀,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • golang如何設(shè)置Header Content-type

    golang如何設(shè)置Header Content-type

    這篇文章主要介紹了golang如何設(shè)置Header Content-type問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 詳解Go語言中如何創(chuàng)建Cron定時(shí)任務(wù)

    詳解Go語言中如何創(chuàng)建Cron定時(shí)任務(wù)

    Cron是一個(gè)強(qiáng)大的定時(shí)任務(wù)調(diào)度庫,它允許開發(fā)者在Go應(yīng)用中方便地設(shè)置和管理定時(shí)任務(wù),本文將結(jié)合具體案例,詳細(xì)介紹Cron在Go語言中的用法,需要的可以參考下
    2024-10-10
  • Go語言安裝和GoLand2021最全超詳細(xì)安裝教程

    Go語言安裝和GoLand2021最全超詳細(xì)安裝教程

    Go語言和GoLand的關(guān)系好比于java和idea、python和pycharm,因此我們需要先安裝好Go語言后才能安裝GoLand。它的安裝和java,python的安裝大同小異,好了,下面給大家?guī)砹薌oLand2021安裝教程,需要的朋友參考下吧
    2021-08-08
  • golang原生http包實(shí)現(xiàn)各種情況的get請(qǐng)求方式

    golang原生http包實(shí)現(xiàn)各種情況的get請(qǐng)求方式

    這篇文章主要介紹了golang原生http包實(shí)現(xiàn)各種情況的get請(qǐng)求方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Go語言區(qū)別于其他語言的特性

    Go語言區(qū)別于其他語言的特性

    在本文中,今天這篇文章將給大家介紹一下 Go 與其他語言不同的 9 個(gè)特性,需要的朋友可以參考下面文章的具體內(nèi)容
    2021-10-10
  • 詳解Golang如何動(dòng)態(tài)獲取配置文件

    詳解Golang如何動(dòng)態(tài)獲取配置文件

    項(xiàng)目中經(jīng)常獲取一些常用配置文件,當(dāng)有配置文件中的參數(shù)被修改后,如何的實(shí)時(shí)獲取配置文件就很關(guān)鍵了,下面小編就來講講如何利用viper實(shí)時(shí)獲取配置文件吧
    2023-08-08

最新評(píng)論