先创建一个带服务的.proto文件
syntax = "proto3"; //指定版本
package goProtocol; //指定包名
option go_package = "./;goProtocol";
// 该文件依赖于插件来生成服务代码。
option cc_generic_services = true;
option java_generic_services = true;
option py_generic_services = true;
/**
go 比较特殊
option go_package = "aaa;bbb";
aaa 表示生成的go文件的存放地址,会自动生成目录的。
bbb 表示生成的go文件所属的包名
*/
/**
服务名: Speak,
其中只有 名为“SayOk”的一个RPC服务,
输入是 Request格式的数据流, 输出是 Response 格式的数据流
*/
service Speak {
rpc SayOk(Request) returns (Response) {}
}
// 请求数据 Request格式定义
message Request {
string input = 1;
}
// 响应数据Response格式定义
message Response {
string output = 1;
}
生成对应服务和结构代码
// 生成数据结构
protoc --go_out=. *.proto
// 生成服务
protoc --go_out=plugins=grpc:. *.proto // 旧版
// 可能会报错
// --go_out: protoc-gen-go: plugins are not supported; use 'protoc --go-grpc_out=...' to generate gRPC
// See https://grpc.io/docs/languages/go/quickstart/#regenerate-grpc-code for more information.
// 因为版本更新了导致的,换
protoc --go-grpc_out=. *.proto // 新版
编写服务端代码
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"log"
"net"
"换成你自己的包名/goProtocol"
)
func main() {
StartServer()
}
func StartServer() {
log.Println("启动服务端...")
server := grpc.NewServer()
// 注册 ToolBoxServer
goProtocol.RegisterSpeakServer(server, &Speak{})
// 监听3000端口
address, err := net.Listen("tcp", ":3000")
if err != nil {
panic(err)
}
if err := server.Serve(address); err != nil {
panic(err)
}
}
// Speak 服务端
type Speak struct {
goProtocol.UnimplementedSpeakServer
}
// SayOk 实现了 SpeakServer 接口中定义的 SayOk 方法
func (*Speak) SayOk(ctx context.Context, req *goProtocol.Request) (*goProtocol.Response, error) {
fmt.Println("调用了SayOk")
return &goProtocol.Response{
Output: "调用了SayOk:" + req.Input,
}, nil
}
编写客户端代码
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"log"
"net/http"
"换成你自己的包名/goProtocol"
)
func main() {
// 编写http请求处理函数
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
res := StartClient("127.0.0.1:3000")
fmt.Println(res)
// 返回一个字符串到网页
w.Write([]byte(res))
})
err := http.ListenAndServe(":8080", nil)
if err != nil {
fmt.Println(err.Error())
return
}
}
func StartClient(target string) string {
// 创建连接
conn, err := grpc.Dial(target, grpc.WithInsecure())
if err != nil {
log.Printf("连接失败: [%v] ", err)
return ""
}
defer conn.Close()
// 声明客户端
client := goProtocol.NewSpeakClient(conn)
// 声明 context
ctx := context.Background()
// 启动一个 goroutine 接收命令行输入的指令
//var reply string // 接收返回值
res, err := client.SayOk(ctx, &goProtocol.Request{Input: "调用传递参数:aa"})
if err != nil {
fmt.Println(err)
return ""
}
fmt.Println(res)
return res.Output
}
开启服务端
go run server.go
运行客户端端
go run client.go
服务端控制台输出结果
2022/11/24 17:51:39 启动服务端...
调用了SayOk
客户端API调试工具返回结果
微服务相关文章
一个简单的微服务系统架构笔记
评论 (0)