补充RPC

This commit is contained in:
yumaojun03 2025-08-24 10:05:50 +08:00
parent 56caa73209
commit 3e17213c8c
4 changed files with 123 additions and 0 deletions

View File

@ -0,0 +1,47 @@
package main
import (
"log"
"net"
"net/rpc"
)
func main() {
// 把我们的对象注册成一个rpc的 receiver
// 其中rpc.Register函数调用会将对象类型中所有满足RPC规则的对象方法注册为RPC函数
// 所有注册的方法会放在“HelloService”服务空间之下
// err := HelloService.FnName(req, resp)
rpc.RegisterName("HelloService", new(HelloService))
// RPC服务器还没启动起来
// 然后我们建立一个唯一的TCP链接
listener, err := net.Listen("tcp", ":1234")
if err != nil {
log.Fatal("ListenTCP error:", err)
}
// 通过rpc.ServeConn函数在该TCP链接上为对方提供RPC服务。
// 没Accept一个请求就创建一个goroutie进行处理
for {
conn, err := listener.Accept()
if err != nil {
log.Fatal("Accept error:", err)
}
// 前面都是tcp的知识, 到这个RPC就接管了
// 因此 你可以认为 rpc 帮我们封装消息到函数调用的这个逻辑,
// 提升了工作效率, 逻辑比较简洁,可以看看他代码
go rpc.ServeConn(conn)
}
}
// 要通过 net/rpc 把一个对象的方法 暴露为rpc需要符合 net/rpc的方法签名: Hello(request string, reply *string) error
// FnName(req any, resp *any) error
type HelloService struct{}
// HTTP Framwork Handler Hello(request string, reply *string) error
func (h *HelloService) Hello(request string, reply *string) error {
*reply = "hello " + request
return nil
}

View File

@ -0,0 +1,23 @@
package main
import (
"context"
"fmt"
"log"
"122.51.31.227/go-course/go18/skills/rpc/hello_world/service"
)
func main() {
client, err := service.NewHelloServiceClient("localhost:1234")
if err != nil {
log.Fatal("dialing:", err)
}
// SDK 提供的方法调用
reply, err := client.Hello(context.Background(), "bob")
if err != nil {
log.Fatal(err)
}
fmt.Println(reply)
}

View File

@ -0,0 +1,45 @@
package service
import (
"context"
"net/rpc"
)
// 首先是通过rpc.Dial拨号RPC服务, 建立连接
// client, err := rpc.Dial("tcp", "localhost:1234")
// if err != nil {
// log.Fatal("dialing:", err)
// }
// // 然后通过client.Call调用具体的RPC方法
// // 在调用client.Call时:
// // 第一个参数是用点号链接的RPC服务名字和方法名字
// // 第二个参数是 请求参数
// // 第三个是请求响应, 必须是一个指针, 有底层rpc服务帮你赋值
// var reply string
// // HelloServiceClient.Hello(ctx, req) (resp, error)
// err = client.Call("HelloService.Hello", "bob", &reply)
// if err != nil {
// log.Fatal(err)
// }
func NewHelloServiceClient(address string) (HelloService, error) {
client, err := rpc.Dial("tcp", address)
if err != nil {
return nil, err
}
return &HelloServiceClient{client: client}, nil
}
type HelloServiceClient struct {
client *rpc.Client
}
func (h *HelloServiceClient) Hello(ctx context.Context, request string) (string, error) {
var reply string
err := h.client.Call("HelloService.Hello", request, &reply)
if err != nil {
return "", err
}
return reply, nil
}

View File

@ -0,0 +1,8 @@
package service
import "context"
// RPC 协议,约束服务端的实现,约束 客户端的调用
type HelloService interface {
Hello(ctx context.Context, request string) (string, error)
}