Rpc 标准库的几种实现方式
server
server.go
package main
import (
"errors"
"fmt"
"net"
"net/http"
"net/rpc"
)
type Args struct {
A, B int
}
type Quotient struct {
Quo, Rem int
}
type Arith int
func (t *Arith) Multiply(args *Args, reply *int) error {
*reply = args.A * args.B
return nil
}
func (t *Arith) Divide(args *Args, quo *Quotient) error {
if args.B == 0 {
return errors.New("divide by zero")
}
quo.Quo = args.A / args.B
quo.Rem = args.A % args.B
return nil
}
func main() {
arith := new(Arith)
rpc.Register(arith)
rpc.HandleHTTP() // http 实现
err := http.ListenAndServe(":1234", nil) // http rpc 监听
if err != nil {
fmt.Println(err.Error())
}
}
// TCP 实现
//func main() {
// arith := new(Arith)
// rpc.Register(arith)
// tcpAddr, err := net.ResolveTCPAddr("tcp", ":1234")
// checkError(err)
// listener, err := net.ListenTCP("tcp", tcpAddr)
// checkError(err)
// for {
// conn, err := listener.Accept()
// if err != nil {
// continue
// }
// rpc.ServeConn(conn)
// }
//}
//func checkError(err error) {
// if err != nil {
// fmt.Println("Fatal error ", err.Error())
// os.Exit(1)
// }
//}
client
client.go
package main
import (
"fmt"
"log"
"net/rpc"
"net/rpc/jsonrpc"
"os"
//"os"
)
type Args struct {
A, B int
}
type Quotient struct {
Quo, Rem int
}
func main() {
//if len(os.Args) != 2 {
// fmt.Println("Usage: ", os.Args[0], "server")
// os.Exit(1)
//}
//serverAddress := os.Args[1]
serverAddress := "localhost"
client, err := rpc.DialHTTP("tcp", serverAddress+":1234")
if err != nil {
log.Fatal("dialing:", err)
}
// Synchronous call
args := Args{17, 8}
var reply int
// 核心: 调用 Arith.Multiply 方法,传参
err = client.Call("Arith.Multiply", args, &reply)
if err != nil {
log.Fatal("arith error:", err)
}
fmt.Printf("Arith: %d*%d=%d\n", args.A, args.B, reply)
var quot Quotient
// 核心: 调用 Arith.Multiply 方法,传参
err = client.Call("Arith.Divide", args, ")
if err != nil {
log.Fatal("arith error:", err)
}
fmt.Printf("Arith: %d/%d=%d remainder %d\n", args.A, args.B, quot.Quo, quot.Rem)
}
// json-rpc 实现
//func main() {
// //if len(os.Args) != 2 {
// //fmt.Println("Usage: ", os.Args[0], "server:port")
// //log.Fatal(1)
// //}
// //service := os.Args[1]
// service := ":1212"
//TCP 实现
//client, err := rpc.Dial("tcp", service)
//if err != nil {
//log.Fatal("dialing:", err)
//}
// client, err := jsonrpc.Dial("tcp", service)
// if err != nil {
// log.Fatal("dialing:", err)
// }
//
// // Synchronous call
// args := Args{17, 8}
// var reply int
// err = client.Call("Arith.Multiply", args, &reply)
// if err != nil {
// log.Fatal("arith error:", err)
// }
// fmt.Printf("Arith: %d*%d=%d\n", args.A, args.B, reply)
// var quot Quotient
// err = client.Call("Arith.Divide", args, ")
// if err != nil {
// log.Fatal("arith error:", err)
// }
// fmt.Printf("Arith: %d/%d=%d remainder %d\n", args.A, args.B, quot.Quo, quot.Rem)
//}
- 原文作者:战神西红柿
- 原文链接:https://tomatoares.github.io/posts/network/rpc-%E6%A0%87%E5%87%86%E5%BA%93%E7%9A%84%E5%87%A0%E7%A7%8D%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。