使用框架
- 客户端使用iris
- 数据库使用mysql
- 服务注册使用zookeeper
- 使用rpc :“github.com/smallnest/rpcx/client”
客户端编写代码
这里只粘贴了api接口的handler,负责接收请求,这里调用zookeeper注册的服务。
var (
zkAddr = flag.String("zkAddr", "192.168.20.190:2181", "zookeeper address")
basePath = flag.String("base", "/home/companyIntro", "prefix path")
xclient client.XClient
)
func GetI(ctx iris.Context) {
flag.Parse()
d := client.NewZookeeperDiscovery(*basePath, "GetI", []string{*zkAddr}, nil)
xclient = client.NewXClient("GetI", client.Failtry, client.RandomSelect, d, client.DefaultOption)
args := &example.RequestGetI{}
reply := &example.ResponseGetI{}
err := xclient.Call(context.Background(), "GetI", args, reply)
if err != nil{
log.Println("failed to call: %v",err)
xclient.Close()
}
defer xclient.Close()
log.Println(reply.String())
marshal, err := json.Marshal(reply.String())
//log.Println(reply.CompanyIntro,marshal)
log.Println(marshal)
ctx.JSON(reply.String())
}
func GetAll(ctx iris.Context) {
flag.Parse()
d := client.NewZookeeperDiscovery(*basePath, "GetAll", []string{*zkAddr}, nil)
xclient = client.NewXClient("GetAll", client.Failtry, client.RandomSelect, d, client.DefaultOption)
args := &example.RequestGetAll{
Status: 1,
Page: &example.Page{
PageNum: 1,
PageSize: 20,
},
}
reply := &example.ResponseGetAll{}
err := xclient.Call(context.Background(), "GetAll", args, reply)
if err != nil{
log.Println("failed to call: %v",err)
xclient.Close()
}
defer xclient.Close()
log.Println(reply.String())
var rest map[string]interface{}
if err := json.Unmarshal([]byte(reply.String()), &rest);err != nil{
return
}
//log.Println(reply.CompanyIntro,marshal)
log.Println(rest)
ctx.JSON(reply.String())
}
服务: 我这里是以数据库中的表,拆开的服务
服务端的主要代码
var Intro *CompanyIntroRepo
/*type GetI int
type GetAll int*/
func GetI(ctx context.Context, args *example.RequestGetI, reply *example.ResponseGetI) error {
all, err := Intro.SelectIAll()
if err != nil {
log.Fatal(err)
}
reply.CompanyIntro = all
fmt.Printf("call: request - %v ,\n response - %v", args, reply)
return nil
}
func GetAll(ctx context.Context, args *example.RequestGetAll, reply *example.ResponseGetAll) error {
var page model.Pagination
page.PageNum = args.Page.GetPageNum()
page.PageSize = args.Page.GetPageSize()
page.PageTotal = args.Page.GetPageTotal()
all,err := Intro.Select(&page, int(args.GetStatus()))
if err != nil{
return err
}
reply.Page = &example.Page{
PageTotal: page.PageTotal,
PageSize: page.PageSize,
PageNum: page.PageNum,
Total: page.Total,
}
for _,v := range all{
intro := example.CompanyIntro{}
intro.Status = v.Status
intro.Id = v.Id
intro.SeqNo = v.SeqNo
intro.Title =v.Title
intro.Content = v.Content
reply.CompanyIntro = append(reply.CompanyIntro, &intro)
}
return nil
}
需要注意的是:是否看着context无用,但是还是要写上,使用上下文的形式,我这里没有使用
我这里因为 中间proto 定的格式有点不对,所以这里有很多缀余代码。
proto
对于每一个远程rpc服务,都必须要定义request,response。
这样很方便后面的操作
syntax = "proto3";
package companyIntro;
//option go_package= "";
service companyIntro{
rpc GetI (RequestGetI) returns (ResponseGetI){}
rpc GetAll(RequestGetAll) returns (ResponseGetAll){}
}
// getAll 的req 和resp
message RequestGetAll{
int32 Status = 1;
Page page = 2;
}
message ResponseGetAll{
repeated CompanyIntro companyIntro = 1;
Page page = 2;
}
// 分页数据
message Page{
int32 PageNum = 1;
int32 PageSize = 2;
int32 Total = 3;
int32 PageTotal = 4;
}
// 结构体
message CompanyIntro{
int64 Id = 1;
string Title = 2;
string Content =3;
}
// GetI 的 req and resp
message RequestGetI{
}
message ResponseGetI{
repeated CompanyIntro companyIntro = 1;
Page page = 2;
}
运行截图
- 成功注册信息
- 开始调用api : http://localhost:8082/api/v1/intro,下图返回数据: