golang——grpc和rpc的模板
- grpc
项目路径
1. 在proto文件中创建需要远程调用的函数
//先从server中开始,创建greeter.proto文件
syntax="proto3";
option go_package="./greeter";//编译后文件生成的地方
service Greeter{ //定义需要传递的接口
rpc SayHello(HelloReq) returns (HelloRes);//定义接口方法名
}
message HelloReq{
string Name = 1;//定义的参数一定要首字母大写,不然不能共有使用
}
message HelloRes{
string message = 1;
}
2. 编译文件
protoc --go_out=. --go_opt=paths=source_relative
--go-grpc_out=. --go-grpc_opt=paths=source_relative
./greeter.proto
3.编写服务器端
package main
//定义一个结构体实现接口中的方法
type Hello struct {
*greeter.UnimplementedGreeterServer
//看生成的grpc代码可以发现多了这个方法,这是为了向前版本兼容
//提高容错性设置的,在结构体里实现就好
}
func (this Hello) SayHello(c context.Context, req *greeter.HelloReq) (*greeter.HelloRes, error) {
fmt.Println(req)
return &greeter.HelloRes{
Message: "你好" + req.Name,
}, nil
}
//进行服务端创建
func main(){
//初始化一个grpc对象
grpcServer := grpc.NewServer()
//注册服务
greeter.RegisterGreeterServer(grpcServer,&Hello{})
//监听端口
listen,err := net.Listen("tcp","127.0.0.1:8888")
if err!=nil{
log.Fatal("err=", err)
return
}
//启动服务
grpcServer.Serve(listen)
}
4.编写客户端
//配置连接级别的安全凭证TLS SSL,返回一个DialOption用于连接服务器
grpcClient, err := grpc.Dial("127.0.0.1:8888", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatal("err=", err)
}
//注册客服端
client := greeter.NewGreeterClient(grpcClient)
//调用服务器端方法,Background表示一个空的context
res, _ := client.SayHello(context.Background(), &greeter.HelloReq{
Name: "dcd",
})
fmt.Println(res)
}
- rpc
服务器端
package main
import (
"fmt"
"log"
"net"
"net/rpc"
)
//定义一个远程调用的方法
type Hello struct{}
//两个参数,返回数据必须为指针类型,并且必须可以序列化,channel complex func这些不能序列化的数据
//返回结果为error,并且为公开的方法
func (h Hello) SayHello(req string, res *string) error {
fmt.Println(req)
*res = "hello" + req
return nil
}
func main() {
//注册rpc服务
err := rpc.RegisterName("hello", new(Hello))
if err != nil {
log.Fatal("err=", err.Error())
return
}
//设置监听
listen, err := net.Listen("tcp", "127.0.0.1:8888")
if err != nil {
log.Fatal("err=", err.Error())
return
}
defer listen.Close()
fmt.Println("server开始监听")
for {
//接收连接
conn, err := listen.Accept()
if err != nil {
log.Fatal("err=", err.Error())
return
}
//绑定服务
go rpc.ServeConn(conn)
}
}
客户端
package main
import (
"fmt"
"log"
"net/rpc"
)
func main() {
//使用rpc连接服务
conn, err := rpc.Dial("tcp", "127.0.0.1:8888")
if err != nil {
log.Fatal("err=", err.Error())
return
}
defer conn.Close()
//调用远程函数
var res string
err = conn.Call("hello.SayHello", "dcd", &res)
if err != nil {
log.Fatal("err=", err.Error())
return
}
fmt.Println(res)
}