(Linux)前提
- 需要安装protobuf
sudo apt install golang-goprotobuf-dev
sudo apt-get install protobuf-compiler
- 安装protoc-gen-go
sudo apt install protoc-gen-go
目录结构
我这边是编写了一个登录的服务,目录结构如下图所示,使用go mod来管理依赖,go mod开启的话需要设置环境变量go env GO111MODULE=on
,然后输入go mod init package_name
(package_name为你自定义的)
编写步骤
编写proto文件
编写login.proto
syntax = "proto3";
package login ;
enum Cmd {
CMD_AUTH = 0;
CMD_LIST = 1;
CMD_QUERY = 2;
}
enum Code{
CODE_SUCCESS = 0;
CODE_BAD_REQUEST = 400;
CODE_BAD_AUTH = 401;
CODE_INTERL_ERROR = 500;
}
message Request{
string name = 1;
string passwd = 2;
Cmd cmd = 3;
string token = 4;
}
message Response{
Code code = 1;
string msg = 2;
}
message ResponseStream{
Code code = 1;
string info = 2;
}
// Interface exported by the server.
service LoginService {
rpc LoginAuth(Request) returns(Response){}
}
然后在login目录下执行
protoc --go_out=plugins=grpc:. login.proto
就会生成login.pb.gp文件
编写服务器
服务器代码server.go
package main
import (
"fmt"
login "go-learn/login"
"net"
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
type loginServer struct {
}
//简单RPC,文本对象返回
func (s *loginServer) LoginAuth(ctx context.Context, req *login.Request) (*login.Response, error) {
fmt.Printf("req name:%s, passwd:%s, cmd:%d\n", req.Name, req.Passwd, int(req.Cmd))
if 0 == len(req.Name) || 0 == len(req.Passwd) {
return &login.Response{
Code: login.Code_CODE_BAD_REQUEST,
Msg: "name or passwd is null",
}, nil
} else {
return &login.Response{
Code: login.Code_CODE_SUCCESS,
Msg: "login success",
}, nil
}
}
func main() {
listen, err := net.Listen("tcp", "127.0.0.1:8033")
if err != nil {
fmt.Printf("listen failed, %v\n", err)
return
}
fmt.Printf("listen success !\n")
grpcServer := grpc.NewServer()
loginSrv := loginServer{}
login.RegisterLoginServiceServer(grpcServer, &loginSrv)
grpcServer.Serve(listen)
}
编写客户端
编写客户端代码client.go
package main
import (
"context"
"flag"
"fmt"
"go-learn/login"
"time"
"google.golang.org/grpc"
)
var (
dest = flag.String("dest", "localhost:10000", "The server address in the format of host:port")
name = flag.String("name", "xiaowang", "The name is login account name")
passwd = flag.String("passwd", "123456", "The passwd is the login account password to login")
cmd = flag.Int("cmd", int(login.Cmd_CMD_AUTH), "The cmd is the login cmd")
)
func printLogin(client login.LoginServiceClient, req *login.Request) {
fmt.Printf("Client: Request cmd:%d, name:%s, passwd:%s\n", req.Cmd, req.Name, req.Passwd)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
response, err := client.LoginAuth(ctx, req)
if err != nil {
fmt.Printf("%v\n", err)
return
}
fmt.Println(response)
}
func main() {
flag.Parse()
conn, err := grpc.Dial(*dest, grpc.WithInsecure())
if err != nil {
fmt.Printf("failed to Dial")
}
defer conn.Close()
client := login.NewLoginServiceClient(conn)
printLogin(client, &login.Request{
Name: *name,
Passwd: *passwd,
Cmd: login.Cmd(*cmd),
Token: "PFSD31234124SDJA3242",
})
}
运行测试
在server路径下执行
go build server.go
./server
在client路径下执行
go build client.go
./client -dest 127.0.0.1:8033
- server 运行结果
- client 运行结果