RPC(Remote Procedure Call)筆記

RPC設(shè)計的目的:
隱藏客戶端服務(wù)器通信細(xì)節(jié)
客戶端調(diào)用更加像傳統(tǒng)的過程調(diào)用
服務(wù)器處理更加像傳統(tǒng)的過程調(diào)用

RPC理想是把網(wǎng)絡(luò)通信做的跟函數(shù)調(diào)用一樣。

  • Client

      z = fn(x, y)
    
  • Server

      fn(x, y) {
          compute
          return z
      }
    

*** RPC設(shè)計的目標(biāo)是這種程度的透明度。 ***

服務(wù)器端

import "net/rpc"

創(chuàng)建遠(yuǎn)程調(diào)用對象

服務(wù)端(Register)注冊一個對象,使它作為一個服務(wù)被暴露,服務(wù)的名字是該對象的類型名。注冊之后,對象的導(dǎo)出方法就可以被遠(yuǎn)程訪問。服務(wù)端可以注冊多個不同類型的對象(服務(wù)),但注冊具有相同類型的多個對象是錯誤的。

只有滿足如下標(biāo)準(zhǔn)的方法才能用于遠(yuǎn)程訪問,其余方法會被忽略:

  • 方法是導(dǎo)出的
  • 方法有兩個參數(shù),都是導(dǎo)出類型或內(nèi)建類型
  • 方法的第二個參數(shù)是指針
  • 方法只有一個error接口類型的返回值

事實上,方法必須看起來像這樣:

func (t *T) MethodName(argType T1, replyType *T2) error

比如:

type Args struct {
    A, B int
}

type Arith int

func (t *Arith) Multiply(args *Args, reply *int) error {
    *reply = args.A * args.B
    return nil
}
注冊對象
arith := new(Arith)
rpc.Register(arith)
創(chuàng)建監(jiān)聽,接收并處理請求
rpc.HandleHTTP()

// 監(jiān)聽端口 1234
l, e := net.Listen("tcp", ":1234")
if e != nil {
    log.Fatal("listen error: ", e)
}
http.Serve(l, nil)
客戶端
和服務(wù)器端建立連接
client, err := rpc.DialHTTP("tcp", "127.0.0.1:1234")
if err != nil {
    log.Fatal("dialing: ", err)
}
執(zhí)行遠(yuǎn)程調(diào)用

執(zhí)行遠(yuǎn)程調(diào)用,有兩種方式:同步和異步。

// 同步調(diào)用,Call會等待遠(yuǎn)端調(diào)用完成
args := &Args{7, 8}
var reply int
err = client.Call("Arith.Multiply", args, &reply)

fmt.Printf("Arith: %d*%d=%d\n", args.A, args.B, reply)
// 異步調(diào)用,Go方法異步地發(fā)送調(diào)用請求,并使用返回的Call結(jié)構(gòu)體類型的Done通道字段傳遞完成信號
quotient := new(Quotient)
divCall := client.Go("Arith.Divide", args, quotient, nil)
<-divCall.Done

fmt.Printf("Arith: %d/%d=%d...%d\n", args.A, args.B, quotient.Quo, quotient.Rem)

--End
Mason

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容