We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Go 标准包中已经提供了对 RPC 的支持,而且支持三个级别的 RPC:TCP、HTTP、JSONRPC。
首先了解什么叫RPC,为什么要RPC,RPC是指远程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。
步骤:
使用http服务端代码实现
// server.go package main import ( "errors" "fmt" "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() err := http.ListenAndServe(":8080", nil) if err != nil { fmt.Println(err.Error()) } }
这样我们就可以使用http的方式来传递数据了。接下来是客户端代码。
// client.go package main import ( "fmt" "log" "net/rpc" "os" ) type Args struct { A, B int } type Quotient struct { Quo, Rem int } func main() { fmt.Println(os.Args) if len(os.Args) != 2 { fmt.Println("Usage: ", os.Args[0], "server") os.Exit(1) } serverAddress := os.Args[1] client, err := rpc.DialHTTP("tcp", serverAddress+":8080") 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) }
接下来让我们来运行程序首先启动服务端程序go run server.go然后开启客户端go run client.go localhost
go run server.go
go run client.go localhost
接下来我们实现基于TCP协议的RPC服务。 服务端代码如下:
// server.go package main import ( "errors" "fmt" "net" "net/rpc" "os" ) 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) tcpAddr, err := net.ResolveTCPAddr("tcp", ":8080") 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) } }
客户端代码:
package main import ( "fmt" "log" "net/rpc" "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:port") os.Exit(1) } service := os.Args[1] client, err := rpc.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) }
服务端代码:
// server.go package main import ( "errors" "fmt" "net" "net/rpc" "net/rpc/jsonrpc" "os" ) 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) tcpAddr, err := net.ResolveTCPAddr("tcp", ":8080") checkError(err) listener, err := net.ListenTCP("tcp", tcpAddr) checkError(err) for { conn, err := listener.Accept() if err != nil { continue } jsonrpc.ServeConn(conn) } } func checkError(err error) { if err != nil { fmt.Println("Fatal error ", err.Error()) os.Exit(1) } }
// server.go package main import ( "fmt" "log" "net/rpc/jsonrpc" "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:port") log.Fatal(1) } service := os.Args[1] 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) }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Go 标准包中已经提供了对 RPC 的支持,而且支持三个级别的 RPC:TCP、HTTP、JSONRPC。
概念
首先了解什么叫RPC,为什么要RPC,RPC是指远程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。
RPC 工作原理
步骤:
HTTP RPC
使用http服务端代码实现
这样我们就可以使用http的方式来传递数据了。接下来是客户端代码。
接下来让我们来运行程序首先启动服务端程序
go run server.go
然后开启客户端go run client.go localhost
TCP RPC
接下来我们实现基于TCP协议的RPC服务。
服务端代码如下:
客户端代码:
JSON RPC
服务端代码:
客户端代码:
参考资料
The text was updated successfully, but these errors were encountered: