這篇文章主要介紹“Golang RPC的使用方法”,在日常操作中,相信很多人在Golang RPC的使用方法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Golang RPC的使用方法”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
專注于為中小企業(yè)提供成都網(wǎng)站建設(shè)、成都做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)坡頭免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了數(shù)千家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
RPC (Remote Rrocedure Call)遠(yuǎn)程過程調(diào)用,可以理解為客戶端請求服務(wù)端,客戶端將要執(zhí)行的函數(shù)請求發(fā)送到服務(wù)端,服務(wù)端通過計(jì)算返回結(jié)果。
通過TCP協(xié)議傳輸,默認(rèn)使用GOB編碼解碼, GOB不支持其他語言,所以只能Golang使用
package main import ( "fmt" "net" "net/rpc" ) type HelloService struct { } func (s *HelloService) Hello(request string, reply *string) error { *reply = fmt.Sprintf("Hello %s", request) return nil } func main() { listener, err := net.Listen("tcp", ":1234") if err != nil { fmt.Println(err) return } err = rpc.RegisterName("HelloService", &HelloService{}) if err != nil { fmt.Println(err) } conn, err := listener.Accept() if err != nil { fmt.Println(err) } rpc.ServeConn(conn) }
package main import ( "fmt" "net/rpc" ) func main() { client, err := rpc.Dial("tcp", "localhost:1234") if err != nil { fmt.Println(err) } var body string err = client.Call("HelloService.Hello", "World", &body) if err != nil { fmt.Println(err) } fmt.Println(body) }
由于GOB解碼編碼不支持其他所以可以改成JSON編碼解碼 服務(wù)端使用rpc.ServerCodec(jsonrpc.NewServerCodec(conn))
改變編碼解碼為JSON
需要修改的代碼rpc.ServeConn(conn)
改為rpc.ServerCodec(jsonrpc.NewServerCodec(conn))
.... conn, _ := listener.Accept() rpc.ServerCodec(jsonrpc.NewServerCodec(conn)) ....
主要代碼實(shí)現(xiàn)rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))
package main import ( "fmt" "net" "net/rpc" "net/rpc/jsonrpc" ) func main() { conn, err :=net.Dial("tcp", "localhost:1234") if err != nil { fmt.Println(err) return } var reply string client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn)) err = client.Call("HelloService.Hello", "body", &reply) if err != nil { fmt.Println(err) } fmt.Println(reply) }
上面實(shí)例都是基于TCP協(xié)議傳輸,RPC也可以使用HTTP協(xié)議進(jìn)行傳輸
package main import ( "fmt" "io" "net/http" "net/rpc" "net/rpc/jsonrpc" ) type HelloServer struct {} func (h *HelloServer) Hello(request string, reply *string) error { *reply = fmt.Sprintf("Hello %s", request) return nil } func main() { err := rpc.RegisterName("HelloService", &HelloServer{}) if err != nil { fmt.Println(err) } http.HandleFunc("/jsonrpc", func(writer http.ResponseWriter, request *http.Request) { var conn io.ReadWriteCloser = struct { io.Writer io.ReadCloser }{ ReadCloser: request.Body, Writer: writer, } err = rpc.ServeRequest(jsonrpc.NewServerCodec(conn)) if err != nil { fmt.Println(err) } }) http.ListenAndServe(":1234", nil) }
package main import ( "bytes" "encoding/json" "fmt" "io" "io/ioutil" "net/http" ) func main() { d := map[string]interface{}{ "id": 0, "params": []string{"body"}, "method": "HelloService.Hello", } b, err := json.Marshal(d) if err != nil { fmt.Println(err) } resp, err := http.Post("http://localhost:1234/jsonrpc", "", bytes.NewBuffer(b)) if err != nil { fmt.Println(err) } defer func(Body io.ReadCloser) { err := Body.Close() if err != nil { fmt.Println(err) } }(resp.Body) bData, _ := ioutil.ReadAll(resp.Body) fmt.Println(string(bData)) }
到此,關(guān)于“Golang RPC的使用方法”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!