《GO语言高级编程》设计中案例,仅作为笔记进行收藏。通常的RPC是基于C/S结构,RPC的服务端对应⽹络的服务器,RPC的客户端也对应⽹络客户端。但是对于⼀些特殊场景,⽐如在公司内⽹提供⼀个RPC服务,但是在外⽹⽆法链接到内⽹的服务器。这种时候我们可以参考类似反向代理的技术,⾸先从内⽹主动链接到外⽹的TCP服务器,然后基于TCP链接向外⽹提供RPC服务。
1.Server/main.go
package main
import (
"net"
"net/rpc"
"time"
)
type HelloService struct{}
func (p *HelloService) Hello(request string, reply *string) error {
*reply = "hello:" + request
return nil
}
func main() {
rpc.Register(new(HelloService))
for {
conn, _ := net.Dial("tcp", "localhost:1234")
if conn == nil {
time.Sleep(time.Second)
continue
}
rpc.ServeConn(conn)
conn.Close()
}
}
2.Client/main.go
package main
import (
"fmt"
"log"
"net"
"net/rpc"
)
func main() {
listener, err := net.Listen("tcp", ":1234")
if err != nil {
log.Fatal("ListenTCP error:", err)
}
clientChan := make(chan *rpc.Client)
go func() {
for {
conn, err := listener.Accept()
if err != nil {
log.Fatal("Accept error:", err)
}
clientChan <- rpc.NewClient(conn)
}
}()
client := <-clientChan
defer client.Close()
var reply string
err = client.Call("HelloService.Hello", "hello", &reply)
if err != nil {
log.Fatal(err)
}
fmt.Println(reply)
}