greet.proto
syntax = "proto3";
package greet;
option go_package = "greetpb";
message Greeting {
string first_name = 1;
string last_name = 2;
}
message GreetRequest {
Greeting greeting = 1;
}
message GreetResponse {
string result = 1;
}
message GreetManytimesRequest {
Greeting greeting = 1;
}
message GreetManytimesResponse {
string result = 1;
}
message LongGreetRequest {
Greeting greeting = 1;
}
message LongGreetResponse {
string result = 1;
}
message GreetEveryRequest {
Greeting Greeting = 1;
}
message GreetEveryResponse {
string result = 1;
}
service GreetService{
//Unary
rpc Greet (GreetRequest) returns (GreetResponse) {};
// server stream
rpc GreetManytimes (GreetManytimesRequest) returns (stream GreetManytimesResponse) {};
//client stream
rpc LongGreet (stream LongGreetRequest) returns (LongGreetResponse) {};
// Bi-Directional Streaming
rpc GreetEvery (stream GreetEveryRequest) returns (stream GreetEveryResponse);
}
输出成golang
#!/bin/bash
protoc greet/greetpb/greet.proto --go_out=plugins=grpc:.
Service
package main
import (
"context"
"fmt"
"io"
"log"
"myproject/goGrpc_course/greet/greetpb"
"net"
"strconv"
"time"
"google.golang.org/grpc"
)
type server struct{}
// 接收客户端 cli.Greet 方法的 request
func (*server) Greet(ctx context.Context, req *greetpb.GreetRequest) (*greetpb.GreetResponse, error) {
fmt.Println("Greet function was invoked with: ", req)
firstName := req.GetGreeting().GetFirstName()
result := "Hello" + firstName
rst := &greetpb.GreetResponse{
Result: result,
}
return rst, nil
}
// 接收客户端 cli.GreetManytimes 方法的 request
func (*server) GreetManytimes(req *greetpb.GreetManytimesRequest, stream greetpb.GreetService_GreetManytimesServer) error {
fmt.Println("GreetManytimes function was invoked with:", req)
firstName := req.GetGreeting().GetFirstName()
for i := 0; i < 10; i++ {
result := "Hello" + firstName + "number" + strconv.Itoa(i)
resp := &greetpb.GreetManytimesResponse{
Result: result,
}
stream.Send(resp)
time.Sleep(1000 * time.Millisecond)
}
return nil
}
// 接收客户端 cli.LongGreet 方法的 request
func (*server) LongGreet(stream greetpb.GreetService_LongGreetServer) error {
fmt.Println("LongGreet function was invoked with:", stream)
result := ""
// 循环接收若干 stream.send() 的请求
for {
req, err := stream.Recv()
// 全部接收完毕:一次回应全部 result
if err == io.EOF {
fmt.Println("finished reading client stream")
// SendAndClose 函数 return 了 error
return stream.SendAndClose(&greetpb.LongGreetResponse{
Result: result,
})
}
if err != nil {
log.Fatalln("reading client stream error: ", err)
}
firstName := req.GetGreeting().GetFirstName()
result += "Hello " + firstName + "! "
}
}
func (*server) GreetEvery(stream greetpb.GreetService_GreetEveryServer) error {
fmt.Println("GreetEvery function was invoked with streaming request:")
for {
req, err := stream.Recv()
if err == io.EOF {
return nil
}
if err != nil {
log.Fatalln("Error while reading client stream")
return err
}
firstName := req.GetGreeting().GetFirstName()
result := "Hello " + firstName + "! "
// 发送应答
if err := stream.Send(&greetpb.GreetEveryResponse{
Result: result,
}); err != nil {
log.Fatalf("Error while sending datea to client: %v", err)
return err
}
}
}
func main() {
fmt.Println("Hello I'm servers!")
// 50051 是 gRPC 的默认端口
lst, err := net.Listen("tcp", "0.0.0.0:50051")
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
//创建 server 并注册
s := grpc.NewServer()
greetpb.RegisterGreetServiceServer(s, &server{})
// 启动server
if err := s.Serve(lst); err != nil {
log.Fatalln("failed to serve: ", err)
}
}
client
package main
import (
"context"
"fmt"
"io"
"log"
"myproject/goGrpc_course/greet/greetpb"
"time"
"google.golang.org/grpc"
)
func main() {
fmt.Println("Hello, I'm a client")
//创建客户端拨号连接
cc, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
log.Fatalln("could not connect: ", err)
}
defer cc.Close()
//创建 client API 实例
cli := greetpb.NewGreetServiceClient(cc)
// doUnary(cli)
// doServerStream(cli)
// doClientStream(cli)
doBiDiStream(cli)
}
func doUnary(cli greetpb.GreetServiceClient) {
fmt.Println("starting do Unary RPC...")
// request 内容(填写结构体)
req := &greetpb.GreetRequest{
Greeting: &greetpb.Greeting{
FirstName: "Squall",
LastName: "Dong",
},
}
//向服务器端的 Greet 方法传递数据
resp, err := cli.Greet(context.Background(), req)
if err != nil {
log.Fatalln("Greet is failed", err)
}
log.Printf("Response form Greet:", resp.Result)
}
func doServerStream(cli greetpb.GreetServiceClient) {
fmt.Println("starting doServerStream RPC...")
rst := &greetpb.GreetManytimesRequest{
Greeting: &greetpb.Greeting{
FirstName: "Squall",
LastName: "dong",
},
}
// 向服务器端的 GreetManytimes 方法传递数据
respStream, err := cli.GreetManytimes(context.Background(), rst)
if err != nil {
log.Fatalln("Failed with calling GreetManytimes RPC: ", err)
}
for {
msg, err := respStream.Recv()
if err == io.EOF {
fmt.Println("reached the end of the stream !")
break
}
if err != nil {
log.Fatalln("failed while recv message: ", err)
}
fmt.Println("Response from GreetManytimes: ", msg.GetResult())
}
}
func doClientStream(cli greetpb.GreetServiceClient) {
fmt.Println("starting doClientStream RPC...")
// 向服务器端的 LongGreet 方法传递数据
stream, err := cli.LongGreet(context.Background())
if err != nil {
log.Fatalln("send client stream failed : ", err)
}
// 创建需要发送的 stream 列表
requests := []*greetpb.LongGreetRequest{
&greetpb.LongGreetRequest{
Greeting: &greetpb.Greeting{
FirstName: "Squall",
},
},
&greetpb.LongGreetRequest{
Greeting: &greetpb.Greeting{
FirstName: "Evin",
},
},
&greetpb.LongGreetRequest{
Greeting: &greetpb.Greeting{
FirstName: "Emily",
},
},
&greetpb.LongGreetRequest{
Greeting: &greetpb.Greeting{
FirstName: "Kimbarly",
},
},
&greetpb.LongGreetRequest{
Greeting: &greetpb.Greeting{
FirstName: "Fanny",
},
},
}
// 循环发送
for _, req := range requests {
fmt.Printf("sending request: %v\n", req)
stream.Send(req)
time.Sleep(1000 * time.Millisecond)
}
// 发送完毕,关闭steam并接收相应
resp, err := stream.CloseAndRecv()
if err != nil {
log.Fatalln("error while receiving response form LongGreet: ", err)
}
// 查看服务器的相应
fmt.Println("LogGreeting response:", resp.GetResult())
// resp.GetResult()
}
func doBiDiStream(cli greetpb.GreetServiceClient) {
fmt.Println("starting doBiDiStream RPC")
// create a stream by invoking the client
stream, err := cli.GreetEvery(context.Background())
if err != nil {
log.Fatalln("Error while send client stream ", err)
}
// request := []*greetpb.GreetEveryRequest{
// &greetpb.GreetEveryRequest{
// Greeting: greetpb.Greeting{
// FirstName: "Squall",
// }
// }
// }
// stream.Send(&greetpb.GreetEveryRequest)
requests := []*greetpb.GreetEveryRequest{
&greetpb.GreetEveryRequest{
Greeting: &greetpb.Greeting{
FirstName: "Squall",
},
},
&greetpb.GreetEveryRequest{
Greeting: &greetpb.Greeting{
FirstName: "Kevin",
},
},
&greetpb.GreetEveryRequest{
Greeting: &greetpb.Greeting{
FirstName: "Emily",
},
},
&greetpb.GreetEveryRequest{
Greeting: &greetpb.Greeting{
FirstName: "Kimbarly",
},
},
&greetpb.GreetEveryRequest{
Greeting: &greetpb.Greeting{
FirstName: "Fanny",
},
},
}
waitc := make(chan struct{})
// send a bunch of message to the client(go routine)
go func() {
for _, req := range requests {
fmt.Printf("sending message: %v\n", req)
stream.Send(req)
time.Sleep(1000 * time.Millisecond)
}
stream.CloseSend()
}()
// receive a bunch of message from the client (go routine)
go func() {
for {
res, err := stream.Recv()
if err == io.EOF {
break
}
if err != nil {
log.Fatalln("Error while recving: ", err)
break
}
fmt.Printf("Received: %v\n", res.GetResult())
}
close(waitc)
}()
// block until everything is done
<-waitc
}
有疑问加站长微信联系(非本文作者)