proto/hello.proto
// protoc --go_out=plugins=grpc:. hello.proto
syntax = "proto3";
package proto;
message String {
string value = 1;
}
service HelloService {
rpc Hello (String) returns (String);
rpc Channel (stream String) returns (stream String);
}
server/server.go
package main
import (
context "context"
"fmt"
"io"
"log"
"net"
"../proto"
"google.golang.org/grpc"
)
type HelloServiceImpl struct{}
func (p *HelloServiceImpl) Hello(ctx context.Context, args *proto.String) (*proto.String, error) {
reply := &proto.String{Value: "hello: " + args.GetValue()}
return reply, nil
}
func (p *HelloServiceImpl) Channel(stream proto.HelloService_ChannelServer) error {
for {
args, err := stream.Recv()
if nil != err {
if io.EOF == err {
fmt.Println("io.EOF")
return nil
}
return err
}
reply := &proto.String{Value: "server:" + args.GetValue()}
err = stream.Send(reply)
if nil != err {
return err
}
}
}
func main() {
grpcServer := grpc.NewServer()
proto.RegisterHelloServiceServer(grpcServer, new(HelloServiceImpl))
lis, err := net.Listen("tcp4", ":1234")
if nil != err {
log.Fatal(err)
}
grpcServer.Serve(lis)
}
client/client.go
package main
import (
"context"
"fmt"
"io"
"log"
"time"
"../proto"
"google.golang.org/grpc"
)
func main() {
conn, err := grpc.Dial("localhost:1234", grpc.WithInsecure())
if nil != err {
log.Fatal(err)
}
defer conn.Close()
client := proto.NewHelloServiceClient(conn)
reply, err := client.Hello(context.Background(), &proto.String{Value: "hello client"})
if nil != err {
log.Fatal(err)
}
fmt.Println(reply.GetValue())
fmt.Println("-----------")
stream, err := client.Channel(context.Background())
if nil != err {
log.Fatal(err)
}
go func() {
for i := 0; i < 100; i++ {
if err := stream.Send(&proto.String{Value: "hi"}); nil != err {
log.Fatal(err)
}
time.Sleep(time.Second)
}
stream.CloseSend()
}()
for {
reply, err := stream.Recv()
if nil != err {
if io.EOF == err {
break
}
log.Fatal(err)
}
fmt.Println(reply.GetValue())
}
}