简介
RPC: 远程过程调用(Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。 该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。 如果涉及的软件采用面向对象编程,那么远程过程调用亦可称作远程调用或远程方法调用。
用通俗易懂的语言描述就是:RPC允许跨机器、跨语言调用计算机程序方法。打个比方,我用go语言写了个获取用户信息的方法getUserInfo,并把go程序部署在阿里云服务器上面,现在我有一个部署在腾讯云上面的php项目,需要调用golang的getUserInfo方法获取用户信息,php跨机器调用go方法的过程就是RPC调用。
代码
server.go
package main
import (
"fmt"
"net"
"net/http"
"net/rpc"
"time"
)
type Server struct {
}
type Req struct {
NumOne int
NumTwo int
}
type Res struct {
Num int
}
func (s *Server) Add(req Req,res *Res) error {
time.Sleep(5*time.Second)
res.Num = req.NumOne + req.NumTwo
return nil
}
func main() {
rpc.Register(new(Server))
rpc.HandleHTTP()
l,e := net.Listen("tcp",":8888")
if e != nil {
fmt.Println("错了")
}
http.Serve(l,nil)
}
client.go
package main
import (
"fmt"
"log"
"net/rpc"
"time"
)
type Req struct {
NumOne int
NumTwo int
}
type Res struct {
Num int
}
func main() {
req := Req{NumOne: 1,NumTwo: 2}
var res Res
client, err := rpc.DialHTTP("tcp","localhost:8888")
if err != nil {
log.Fatal("dialing:",err)
}
//client调用call是同步,调用Go是异步
//一、call调用
//client.Call("Server.Add",req,&res)
//fmt.Println(res)
//二、Go调用
ca := client.Go("Server.Add", req, &res, nil)
//以下是等待的过程中做的事情
//方式一
for {
select {
case <-ca.Done:
fmt.Println(res)
return
default:
time.Sleep(time.Second)
fmt.Println("我等着")
}
}
//方式二
//fmt.Println("我可以做好多事情!")
//<-ca.Done
//fmt.Println(res)
}