golang使用net/rpc庫實現(xiàn)rpc
項目左側(cè)包結(jié)構(gòu)
rpc服務(wù)端實現(xiàn)
使用golang官方的net/rpc庫實現(xiàn)RPC方法,使用http作為RPC的載體,通過http/net包監(jiān)聽客戶端連接請求。
rpc服務(wù)端實現(xiàn)代碼serverrpc.go如下
package main import ( "errors" "fmt" "log" "net" "net/http" "net/rpc" "os" ) // 運算結(jié)構(gòu)體 type Arith struct { } // 運算請求結(jié)構(gòu)體 type ArithRequest struct { A int B int } // 運算響應結(jié)構(gòu)體 type ArithResponse struct { Pro int //product 表示乘積 Quo int //quotient 表示商 Rem int //remaind 表示余數(shù) } /* 運算結(jié)構(gòu)體的乘法運算方法 第一個參數(shù)只需要拿到其里面的值只需要傳一個結(jié)構(gòu)體即可, 第二個參數(shù)需要將運算結(jié)果存到其里面所以需要傳地址 */ func (this *Arith) Multiply(req ArithRequest, res *ArithResponse) error { res.Pro = req.A * req.B return nil } /* 運算結(jié)構(gòu)體的除法運算方法 第一個參數(shù)只需要拿到其里面的值只需要傳一個結(jié)構(gòu)體即可, 第二個參數(shù)需要將運算結(jié)果存到其里面所以需要傳地址 */ func (this *Arith) Divide(req ArithRequest, res *ArithResponse) error { if req.B == 0 { //除法為0,運算不合法 return errors.New("divide by zero") } res.Quo = req.A / req.B res.Rem = req.A % req.B return nil } func main() { rpc.Register(new(Arith)) //注冊rpc服務(wù) rpc.HandleHTTP() //采用http作為rpc的載體 lis, err := net.Listen("tcp", "127.0.0.1:8090") //Listen是block(阻塞的) if err != nil { log.Fatalln("fatal error:", err) } fmt.Fprintf(os.Stdout, "%s", "start connection") http.Serve(lis, nil) //net.Listen是阻塞的,需要通過這里進行啟動 }
rpc客戶端實現(xiàn)
上述服務(wù)端程序運行之后,將會監(jiān)聽本地的8090端口,我們可以實現(xiàn)一個客戶端程序,連接服務(wù)端并且實現(xiàn)RPC方法調(diào)用。
rpc客戶端實現(xiàn)代碼clientrpc.go如下
package main import ( "fmt" "log" "net/rpc" ) // 算數(shù)運算請求結(jié)構(gòu)體 type ArithRequest struct { A int B int } // 算數(shù)運算響應結(jié)構(gòu)體 type ArithResponse struct { Pro int //product 乘積 Quo int //quotient 商 Rem int //remain 余數(shù) } func main() { //通過網(wǎng)絡(luò)實現(xiàn)rpc遠程進程調(diào)用 conn, err := rpc.DialHTTP("tcp", "127.0.0.1:8090") if err != nil { log.Fatalln("dailing error", err) } req := ArithRequest{9, 2} //請求結(jié)構(gòu)體 var res ArithResponse //響應結(jié)構(gòu)體,用于存儲運算結(jié)果 //實現(xiàn)rpc之后,通過Call方法在客戶端調(diào)用服務(wù)端里面算數(shù)運算結(jié)構(gòu)體的乘法運算方法 err = conn.Call("Arith.Multiply", req, &res) if err != nil { log.Fatalln("arith error", err) } fmt.Printf("%d * %d = %d\n", req.A, req.B, res.Pro) //實現(xiàn)rpc之后,通過Call方法在客戶端調(diào)用服務(wù)端里面算數(shù)運算結(jié)構(gòu)體的除法運算方法 err = conn.Call("Arith.Divide", req, &res) if err != nil { log.Fatalln("arith error", err) } fmt.Printf("%d / %d, quo is %d, rem is %d\n", req.A, req.B, res.Quo, res.Rem) }
詳細實現(xiàn)步驟
1.首先初始化項目
go mod init pro01 //pro01表示項目名稱
2.在當前項目下新建包server,并且在該包下面新建serverrpc.go實現(xiàn)rpc服務(wù)端
3.在當前項目下新建包client,并且在該包下面新建clientrpc.go實現(xiàn)rpc客戶端
4.運行rpc服務(wù)端程序 ,首先進入server包,然后運行serverrpc.go
cd server
go run serverrpc.go
5.運行rpc客戶端程序,首先進入client包,然后運行clientrpc.go
cd client
go run clientrpc.go
6.查看輸出結(jié)果是否正確,輸出結(jié)果如下表示程序運行結(jié)果正確,當然我這里的結(jié)果是根據(jù)我在請求結(jié)構(gòu)體里面給出的倆個數(shù)值進行計算的,具體結(jié)果是否正確根據(jù)自己的具體程序判斷。
總結(jié)
通過官方庫net/rpc實現(xiàn)rpc遠程進程調(diào)用非常方便,并且實現(xiàn)還是比較簡單的,但是有一個缺點就是不能跨平臺。
到此這篇關(guān)于golang使用net/rpc庫實現(xiàn)rpc的文章就介紹到這了,更多相關(guān)go rpc內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Sublime Text3安裝Go語言相關(guān)插件gosublime時搜不到gosublime的解決方法
本文主要介紹了Sublime Text3安裝Go語言相關(guān)插件gosublime時搜不到gosublime的解決方法,具有一定的參考價值,感興趣的可以了解一下2022-01-01Go?json自定義Unmarshal避免判斷nil示例詳解
這篇文章主要為大家介紹了Go?json自定義Unmarshal避免判斷nil示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06