go语言标准库实现rpc
基于HTTP协议的rpc实现
1. 服务端代码
`
点击查看代码
package main
import (
"fmt"
"log"
"net"
"net/http"
"net/rpc"
)
type Args struct {
A, B int
}
// ServiceA 自定义一个结构体
type ServiceA struct{}
// Add 为ServiceA类型增加一个可导出的Sum方法
func (s *ServiceA) Sum(args *Args, reply *int) error {
*reply = args.A + args.B
return nil
}
func main() {
service := new(ServiceA)
rpc.Register(service) // 注册rpc服务
rpc.HandleHTTP() // 基于http协议
l, e := net.Listen("tcp", ":9000")
if e != nil {
log.Fatal("listen error:", e)
}
http.Serve(l, nil)
fmt.Println("rpc server listening at 9000")
}
2. 客户端代码
`
点击查看代码
package main
type Args struct {
A, B int
}
//func main() {
// 建立连接
client, err := rpc.DialHTTP("tcp", "127.0.0.1:9000")
if err != nil {
log.Fatal("dialing:", err)
}
// 同步调用
args := &Args{A: 10, B: 20}
var reply int
err = client.Call("ServiceA.Sum", args, &reply)
if err != nil {
log.Fatal("arith error:", err)
}
fmt.Printf("ServiceA.Sum: %d+%d=%d\n", args.A, args.B, reply)
// 异步调用
var reply2 int
// 方法名 传递的结构体实例,包含服务调用需要的参数;存放结果的变量,通道
divCall := client.Go("ServiceA.Sum", args, &reply2, nil)
reply2call := <-divCall.Done
fmt.Println(reply2call.Error)
fmt.Println(reply2)
}
点击查看代码
package main
import (
"fmt"
"log"
"net"
"net/http"
"net/rpc"
)
type Args struct {
A, B int
}
// ServiceA 自定义一个结构体
type ServiceA struct{}
// Add 为ServiceA类型增加一个可导出的Sum方法
func (s *ServiceA) Sum(args *Args, reply *int) error {
*reply = args.A + args.B
return nil
}
func main() {
service := new(ServiceA)
rpc.Register(service) // 注册RPC服务
listener, err := net.Listen("tcp", ":9001")
if err != nil {
log.Fatal("listen error:", err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Fatal("accept error:", err)
}
rpc.ServeConn(conn)
}
}
4. 服务端代码
`
点击查看代码
package main
type Args struct {
A, B int
}
func main() {
// 建立连接
client, err := rpc.Dial("tcp", "127.0.0.1:9001")
if err != nil {
log.Fatal("dialing:", err)
}
//同步调用
args := &Args{55, 120}
var reply int
err = client.Call("ServiceA.Sum", args, &reply)
if err != nil {
log.Fatal("ServiceA.Sum error", err)
}
fmt.Printf("ServiceA.Add: %d+%d=%d\n", args.A, args.B, reply)
// 一部调用
var asyncReply int
divCall := client.Go("ServiceA.Sum", args, &asyncReply, nil)
replyCall := <-divCall.Done // 接收调用结果
fmt.Println(replyCall.Error)
fmt.Println(replyCall.ServiceMethod)
fmt.Println(asyncReply)
}

浙公网安备 33010602011771号