Go语言中的RPC调用
Go语言中的RPC调用
首先,说一下目录结构:
一、HttpRPC
1、建立服务文件
/*Go RPC的函数只有符合下面的条件才能被远程访问,不然会被忽略,详细的要求如下:
函数必须是导出的(首字母大写)
必须有两个导出类型的参数,
第一个参数是接收的参数,第二个参数是返回给客户端的参数,第二个参数必须是指针类型的
函数还要有一个返回值error
举个例子,正确的RPC函数格式如下:
func (t *T) MethodName(argType T1, replyType *T2) error
*/
package common
import (
"errors"
)
type Args struct {
A, B float32
}
type Result struct {
Value float32
}
type MathService struct {
}
func (s *MathService) Add(args *Args, result *Result) error {
result.Value = args.A + args.B
return nil
}
func (s *MathService) Divide(args *Args, result *Result) error {
if args.B == 0 {
return errors.New("除数不能为零!")
}
result.Value = args.A / args.B
return nil
}
2、服务端代码:
package main
import (
"fmt"
"net/http"
"net/rpc"
"../common"
)
func main() {
var ms = new(common.MathService)
rpc.Register(ms)
rpc.HandleHTTP() //将Rpc绑定到HTTP协议上。
fmt.Println("启动服务...")
err := http.ListenAndServe(":1234", nil)
if err != nil {
fmt.Println(err.Error())
}
fmt.Println("服务已停止!")
}
3、客户端调用代码:
package main
import (
"fmt"
"net/rpc"
"../common"
)
func main() {
var args = common.Args{17, 8}
var result = common.Result{}
var client, err = rpc.DialHTTP("tcp", "127.0.0.1:1234")
if err != nil {
fmt.Println("连接RPC服务失败:", err)
}
err = client.Call("MathService.Divide", args, &result)
if err != nil {
fmt.Println("调用失败:", err)
}
fmt.Println("调用结果:", result.Value)
}
4、测试:
二、HttpRPC
1、建立服务文件
/*Go RPC的函数只有符合下面的条件才能被远程访问,不然会被忽略,详细的要求如下:
函数必须是导出的(首字母大写)
必须有两个导出类型的参数,
第一个参数是接收的参数,第二个参数是返回给客户端的参数,第二个参数必须是指针类型的
函数还要有一个返回值error
举个例子,正确的RPC函数格式如下:
func (t *T) MethodName(argType T1, replyType *T2) error
*/
package common
import (
"errors"
)
type Args struct {
A, B float32
}
type Result struct {
Value float32
}
type MathService struct {
}
func (s *MathService) Add(args *Args, result *Result) error {
result.Value = args.A + args.B
return nil
}
func (s *MathService) Divide(args *Args, result *Result) error {
if args.B == 0 {
return errors.New("除数不能为零!")
}
result.Value = args.A / args.B
return nil
}
2、服务端文件
package main
import (
"fmt"
"net"
"net/rpc"
"../common"
)
func main() {
var ms = new(common.MathService) //实例化服务对像
rpc.Register(ms) //注册这个服务
fmt.Println("启动服务...")
var address, _ = net.ResolveTCPAddr("tcp", "127.0.0.1:1234") //定义TCP的服务承载地址
listener, err := net.ListenTCP("tcp", address) //监听TCP连接
if err != nil {
fmt.Println("启动失败!", err)
}
for {
conn, err := listener.Accept() //如果接受到连接
if err != nil {
continue
}
fmt.Println("接收到一个调用请求...")
rpc.ServeConn(conn) //让此rpc绑定到该Tcp连接上。
}
//fmt.Println("服务已停止!")
}
3、客户端代码:
// main.go
package main
import (
"fmt"
"net/rpc"
"../common"
)
func main() {
var client, err = rpc.Dial("tcp", "127.0.0.1:1234")
if err != nil {
fmt.Println("连接不到服务器:", err)
}
var args = common.Args{40, 3}
var result = common.Result{}
fmt.Println("开始调用!")
err = client.Call("MathService.Add", args, &result)
if err != nil {
fmt.Println("调用失败!", err)
}
fmt.Println("调用成功!结果:", result.Value)
}
4、效果:
Go语言中的RPC调用
https://www.dearcloud.cn/2016/03/09/20200310-cnblogs-old-posts/20160309-Go语言中的RPC调用/