补充RPC
This commit is contained in:
parent
56caa73209
commit
3e17213c8c
47
skills/rpc/hello_world/server_a/main.go
Normal file
47
skills/rpc/hello_world/server_a/main.go
Normal 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
|
||||||
|
}
|
23
skills/rpc/hello_world/server_b/main.go
Normal file
23
skills/rpc/hello_world/server_b/main.go
Normal 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)
|
||||||
|
}
|
45
skills/rpc/hello_world/service/client.go
Normal file
45
skills/rpc/hello_world/service/client.go
Normal 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
|
||||||
|
}
|
8
skills/rpc/hello_world/service/interface.go
Normal file
8
skills/rpc/hello_world/service/interface.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
// RPC 协议,约束服务端的实现,约束 客户端的调用
|
||||||
|
type HelloService interface {
|
||||||
|
Hello(ctx context.Context, request string) (string, error)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user