RPC(二)[RPC-Golang]

在這裏插入圖片描述
golang對prc進行了支持,使用時只需要導入net/rpc的包即可:

import "net/rpc"

rpc包提供了通過網絡或其他I/O連接對一個對象的導出方法的訪問。服務端註冊一個對象,使它作爲一個服務被暴露,服務的名字是該對象的類型名。註冊之後,對象的導出方法就可以被遠程訪問。服務端可以註冊多個不同類型的對象(服務),但註冊具有相同類型的多個對象是錯誤的。

只有滿足如下標準的方法才能用於遠程訪問,其餘方法會被忽略:

  • 方法是導出的
  • 方法有兩個參數,都是導出類型或內建類型
  • 方法的第二個參數是指針
  • 方法只有一個error接口類型的返回值
    事實上,方法必須看起來像這樣:
func (t *T) MethodName(argType T1, replyType *T2) error

其中T、T1和T2都能被encoding/gob包序列化。這些限制即使使用不同的編解碼器也適用。(未來,對定製的編解碼器可能會使用較寬鬆一點的限制)
方法的第一個參數代表 調用者提供的參數 ;第二個參數代表 返回給調用者的參數 。方法的返回值,如果非nil,將被作爲字符串回傳,在客戶端看來就和errors.New創建的一樣。如果返回了錯誤,回覆的參數將不會被髮送給客戶端。
服務端可能會單個連接上調用ServeConn管理請求。更典型地,它會創建一個網絡監聽器然後調用Accept;或者,對於HTTP監聽器,調用HandleHTTP和http.Serve。
想要使用服務的客戶端會創建一個連接,然後用該連接調用NewClient。
更方便的函數Dial(DialHTTP)會在一個原始的連接(或HTTP連接)上依次執行這兩個步驟。
生成的Client類型值有兩個方法,Call和Go,它們的參數爲要調用的服務和方法、一個包含參數的指針、一個用於接收接個的指針。
Call方法會等待遠端調用完成,而Go方法異步的發送調用請求並使用返回的Call結構體類型的Done通道字段傳遞完成信號。
除非設置了顯式的編解碼器,本包默認使用encoding/gob包來傳輸數據。

執行以下前提:安裝配置好golang開發環境

1.服務端

1.編輯服務端代碼

mkdir -p $GOPATH/src/rpctest/ && cd $_ && go mod init rpctest && mkdir -p srv && cd $_ && vim main.go

內容如下:

package main

import (
	"log"
	"net"
	"net/http"
	"net/rpc"
)

type Rpc struct {
}

/*
- 方法是導出的
- 方法有兩個參數,都是導出類型或內建類型
- 方法的第二個參數是指針
- 方法只有一個error接口類型的返回值
func (t *T) MethodName(argType T1, replyType *T2) error
*/
func (r *Rpc) GetSum(argType int, replyType *int) error {
	*replyType = argType + 100
	return nil
}
func main() {
	// 1.結構體實例化
	rp := new(Rpc)
	// 2.rpc註冊
	rpc.Register(rp)
	// 3.rpc網絡
	rpc.HandleHTTP()
	// 4.監聽網絡
	ln, err := net.Listen("tcp", "127.0.0.1:8899")
	if err != nil {
		log.Fatal(err)
	}
	// 5.等待網絡連接
	http.Serve(ln, nil)
}

2.開啓服務端

cd $GOPATH/src/rpctest/srv && go run main.go

在這裏插入圖片描述

2.客戶端

1.編輯客戶端代碼

再開一個終端執行客戶端的操作,不要關閉服務端

mkdir -p $GOPATH/src/rpctest/ && cd $_ && mkdir -p cli && cd $_ && vim main.go

內容如下:

package main

import (
	"log"
	"net/rpc"
)

func main() {
	// 1.連接服務器
	cli, err := rpc.DialHTTP("tcp", "127.0.0.1:8899")
	if err != nil {
		log.Fatal(err)
	}
	// 2.調用函數
	// serviceMethod :服務方法名,是一個 [ 結構體.方法名 ] 的字符串
	// args :需要傳入的參數
	// reply : 接收的變量參數
	//func (client *Client) Call(serviceMethod string, args interface{}, reply interface{}) error
	var reply int
	err = cli.Call("Rpc.GetSum", 99, &reply)
	if err != nil {
		log.Fatal(err)
	}
	// 3.打印結果
	log.Println(reply)
}

2.執行客戶端

前提:保證服務端已經開啓

cd $GOPATH/src/rpctest/cli && go run main.go

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章