go windows + grpc 以及grpc流模式使用
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了go windows + grpc 以及grpc流模式使用,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4827字,纯文字阅读大概需要7分钟。
内容图文
![go windows + grpc 以及grpc流模式使用](/upload/InfoBanner/zyjiaocheng/924/f50cfa0a5d42437d99e857dba5f9e89f.jpg)
国内网络问题,windows使用grpc过程
安装protoc
将写好的proto文件,生成pb.go文件,下载地址https://github.com/protocolbuffers/protobuf/releases,下载下来的是一个zip文件,将文件解压找到/bin/protoc.exe,将其配置到环境变量。在控制台中输入protoc --version,打印出下载protoc版本说明安装正确。
安装grpc
这里因为网络问题,需要从github上拉源码安装,
git clone https://github.com/golang/net.git %GOPATH%/src/golang.org/x/net
git clone https://github.com/golang/text.git %GOPATH%/src/golang.org/x/text
git clone https://github.com/grpc/grpc-go.git %GOPATH%/src/google.golang.org/grpc
git clone https://github.com/protocolbuffers/protobuf-go.git %GOPATH%/src/google.golang.org/protobuf
git clone https://github.com/google/go-genproto.git %GOPATH%/src/google.golang.org/genproto
这里是grpc依赖的,已经编译时依赖的全部资源
安装protoc-gen-go
go get github.com/golang/protobuf/protoc-gen-go
我这里使用的是protoc-gen-gofast(有大佬做过测试,go-fast要快4-7倍,https://studygolang.com/articles/22824)
使用源码安装
git clone https://github.com/gogo/protobuf.git
go install protoc-gen-gofast
至此准备工作已经完成,接下来进行简单的测试
Grpc测试
grpc基于http2.0,再次同时记录一下grpc流模式的使用(http2.0 :1. 多路复用 2.TCP连接 3.二进制代替文本 4.标题压缩 5.服务器推送,grpc也同样具有这些功能)
proto文件
syntax = "proto3";
package proto;
option go_package = "proto";
message HelloReq {
string name = 1;
string content = 2;
}
message HelloResp{
string content = 1;
}
message HelloListResp{
repeated string content = 1;
}
service HelloService {
// 普通调用
rpc Hello(HelloReq) returns (HelloResp){}
// 客户端流模式
rpc HelloClientStream(stream HelloReq) returns (HelloListResp){}
// 服务端流模式
rpc HelloServerStream(HelloReq) returns (stream HelloResp){}
// 双向流模式
rpc HelloStream(stream HelloReq) returns (stream HelloResp){}
}
在proto文件的目录下执行 protoc --gofast_out=plugins=grpc:. *.proto 生成 hello.pb.go 文件。
服务端代码:
package main
import (
"context"
"demo/proto"
"fmt"
"google.golang.org/grpc"
"io"
"net"
)
type HelloServer struct {
}
func (*HelloServer) Hello(ctx context.Context, in *proto.HelloReq) (*proto.HelloResp, error) {
return &proto.HelloResp{
Content: fmt.Sprintf("%v : %v", in.GetName(), in.GetContent()),
}, nil
}
func (*HelloServer) HelloClientStream(stream proto.HelloService_HelloClientStreamServer) error {
var users []string
for {
recv, err := stream.Recv()
//接收完了返回结果并关闭
if err == io.EOF {
return stream.SendAndClose(&proto.HelloListResp{
Content: users,
})
}
if err != nil {
return err
}
users = append(users, fmt.Sprintf(recv.GetName()+" : "+recv.GetContent()))
}
}
func (*HelloServer) HelloServerStream(in *proto.HelloReq, stream proto.HelloService_HelloServerStreamServer) error {
for i := 0; i < 10; i++ {
stream.Send(&proto.HelloResp{
Content: fmt.Sprintf("%v - %v : %v", i, in.GetName(), in.GetContent()),
})
}
return nil
}
func (*HelloServer) HelloStream(stream proto.HelloService_HelloStreamServer) error {
for {
recv, err := stream.Recv()
//接收完了返回
if err == io.EOF {
return nil
}
if err != nil {
return err
}
err = stream.Send(&proto.HelloResp{
Content: fmt.Sprintf("%v : %v", recv.GetName(), recv.GetContent()),
})
if err != nil {
return err
}
}
}
func main() {
listen, err := net.Listen("tcp", ":8001")
if err != nil {
panic(err)
}
s := grpc.NewServer()
proto.RegisterHelloServiceServer(s, &HelloServer{})
err = s.Serve(listen)
if err != nil {
panic(err)
}
}
客户端实现:
package main
import (
"context"
"demo/proto"
"fmt"
"google.golang.org/grpc"
"io"
"strconv"
"time"
)
func main() {
conn, err := grpc.Dial("localhost:8001", grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
panic(err)
}
defer conn.Close()
cli := proto.NewHelloServiceClient(conn)
// 普通调用
hello, err := cli.Hello(context.Background(), &proto.HelloReq{
Name: "demo",
Content: "Hello World",
})
if err != nil {
panic(err)
}
fmt.Println(hello.GetContent())
// 客户端流模式测试
client, err := cli.HelloClientStream(context.Background())
if err != nil {
panic(err)
}
for i := 0; i < 5; i++ {
client.Send(&proto.HelloReq{
Name: "world" + strconv.Itoa(i),
Content: "hello",
})
}
client.CloseSend()
recv, err := client.CloseAndRecv()
if err != nil {
panic(err)
}
for i := range recv.Content {
fmt.Println(recv.GetContent()[i])
}
// 服务端流模式测试
stream, err := cli.HelloServerStream(context.Background(), &proto.HelloReq{
Name: "hello",
Content: "world",
})
for {
resp, err := stream.Recv()
if err != nil {
if err == io.EOF {
break
} else {
panic(err)
}
}
fmt.Println(resp.Content)
}
// 双向流模式测试
helloStream, err := cli.HelloStream(context.Background())
if err != nil {
panic(err)
}
go func() {
for {
resp, err := helloStream.Recv()
if err != nil {
if err == io.EOF {
break
} else {
panic(err)
}
}
fmt.Println(resp.Content)
}
}()
for i := 0; i < 5; i++ {
time.Sleep(time.Second)
fmt.Println("send", i)
helloStream.Send(&proto.HelloReq{
Name: "hello" + strconv.Itoa(i),
Content: "world",
})
}
helloStream.CloseSend()
time.Sleep(time.Second)
}
目录结构如下:
内容总结
以上是互联网集市为您收集整理的go windows + grpc 以及grpc流模式使用全部内容,希望文章能够帮你解决go windows + grpc 以及grpc流模式使用所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。