2024-06-05|閱讀時間 ‧ 約 27 分鐘

[Go]RPC

GOB

Go官方有提供net/rpc的RPC套件。此套件提供GOB的編/解碼,且支援TCP或HTTP傳輸方式。它可以在伺服器端註冊多個不同類型物件。


遠端存取的要求條件

  • 方法的類型可輸出
  • 方法的本體可輸出
  • 方法必須要有兩個參數是輸出或內建
  • 方法的第二個參數是指標型
  • 方法的返回類型為error


伺服器端

package main

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

func main() {
algorithm := new(Algorithm)
fmt.Println("Algorithm start", algorithm)
rpc.Register(algorithm)
rpc.HandleHTTP()
err := http.ListenAndServe(":8808", nil)
if err != nil {
fmt.Println("err===", err.Error())
}
}

type Algorithm int

type Args struct {
X, Y int
}

type Response int

func (t *Algorithm) Sum(args *Args, reply *int) error {
*reply = args.X + args.Y
fmt.Println("Exec Sum ", reply)
return nil
}


用戶端

package main

import (
"fmt"
"log"
"net/rpc"
"os"
"strconv"
)

type ArgsTwo struct {
X, Y int
}

func main() {
client, err := rpc.DialHTTP("tcp", "127.0.0.1:8808")
if err != nil {
log.Fatal("ERROR:DialHTTP", err)
}
i1, _ := strconv.Atoi(os.Args[1])
i2, _ := strconv.Atoi(os.Args[2])
args := ArgsTwo{i1, i2}
var reply int
err = client.Call("Algorithm.Sum", args, &reply)
if err != nil {
log.Fatal("Call Sum algorithm error:", err)
}
fmt.Printf("Algorithm Sum: %d+%d=%d\n", args.X, args.Y, reply)
}


JSON

Go官方有提供net/rpc的RPC套件。此套件提供json-rpc的編/解碼。


伺服器端

package main

import (
"fmt"
"net"
"net/rpc"
"net/rpc/jsonrpc"
)

func init() {
fmt.Println("JSON編碼RPC,不是gob編碼,其他的和RPC概念一模一樣,")
}

type ArgsLanguage struct {
Java, Go string
}

type Programmer string

func (m *Programmer) GetSkill(al *ArgsLanguage, skill *string) error {
*skill = "Skill1:" + al.Java + ",Skill2" + al.Go
return nil
}

func main() {
str := new(Programmer)
rpc.Register(str)

tcpAddr, err := net.ResolveTCPAddr("tcp", ":8085")
if err != nil {
fmt.Println("ResolveTCPAddr err=", err)
}

listener, err := net.ListenTCP("tcp", tcpAddr)
if err != nil {
fmt.Println("tcp listen err=", err)
}

for {
conn, err := listener.Accept()
if err != nil {
continue
}
jsonrpc.ServeConn(conn)
}
}


用戶端

package main

import (
"fmt"
"log"
"net/rpc/jsonrpc"
)

func main() {
fmt.Println("client start......")
client, err := jsonrpc.Dial("tcp", "127.0.0.1:8085")
if err != nil {
log.Fatal("Dial err=", err)
}
send := Send{"Java", "Go"}
var receive string
err = client.Call("Programmer.GetSkill", send, &receive)
if err != nil {
fmt.Println("Call err=", err)
}
fmt.Println("receive", receive)

}

type Send struct {
Java, Go string
}
分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.