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)
}
` **基于tcp协议的实现** **3. 服务端代码** `
点击查看代码
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)
}
`
posted @ 2025-12-09 22:20  陈绪水  阅读(0)  评论(0)    收藏  举报