1/* 2 * 3 * Copyright 2018 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19// Binary server is an example server. 20package main 21 22import ( 23 "context" 24 "flag" 25 "fmt" 26 "io" 27 "log" 28 "math/rand" 29 "net" 30 "time" 31 32 "google.golang.org/grpc" 33 "google.golang.org/grpc/codes" 34 "google.golang.org/grpc/metadata" 35 "google.golang.org/grpc/status" 36 37 pb "google.golang.org/grpc/examples/features/proto/echo" 38) 39 40var port = flag.Int("port", 50051, "the port to serve on") 41 42const ( 43 timestampFormat = time.StampNano 44 streamingCount = 10 45) 46 47type server struct { 48 pb.UnimplementedEchoServer 49} 50 51func (s *server) UnaryEcho(ctx context.Context, in *pb.EchoRequest) (*pb.EchoResponse, error) { 52 fmt.Printf("--- UnaryEcho ---\n") 53 // Create trailer in defer to record function return time. 54 defer func() { 55 trailer := metadata.Pairs("timestamp", time.Now().Format(timestampFormat)) 56 grpc.SetTrailer(ctx, trailer) 57 }() 58 59 // Read metadata from client. 60 md, ok := metadata.FromIncomingContext(ctx) 61 if !ok { 62 return nil, status.Errorf(codes.DataLoss, "UnaryEcho: failed to get metadata") 63 } 64 if t, ok := md["timestamp"]; ok { 65 fmt.Printf("timestamp from metadata:\n") 66 for i, e := range t { 67 fmt.Printf(" %d. %s\n", i, e) 68 } 69 } 70 71 // Create and send header. 72 header := metadata.New(map[string]string{"location": "MTV", "timestamp": time.Now().Format(timestampFormat)}) 73 grpc.SendHeader(ctx, header) 74 75 fmt.Printf("request received: %v, sending echo\n", in) 76 77 return &pb.EchoResponse{Message: in.Message}, nil 78} 79 80func (s *server) ServerStreamingEcho(in *pb.EchoRequest, stream pb.Echo_ServerStreamingEchoServer) error { 81 fmt.Printf("--- ServerStreamingEcho ---\n") 82 // Create trailer in defer to record function return time. 83 defer func() { 84 trailer := metadata.Pairs("timestamp", time.Now().Format(timestampFormat)) 85 stream.SetTrailer(trailer) 86 }() 87 88 // Read metadata from client. 89 md, ok := metadata.FromIncomingContext(stream.Context()) 90 if !ok { 91 return status.Errorf(codes.DataLoss, "ServerStreamingEcho: failed to get metadata") 92 } 93 if t, ok := md["timestamp"]; ok { 94 fmt.Printf("timestamp from metadata:\n") 95 for i, e := range t { 96 fmt.Printf(" %d. %s\n", i, e) 97 } 98 } 99 100 // Create and send header. 101 header := metadata.New(map[string]string{"location": "MTV", "timestamp": time.Now().Format(timestampFormat)}) 102 stream.SendHeader(header) 103 104 fmt.Printf("request received: %v\n", in) 105 106 // Read requests and send responses. 107 for i := 0; i < streamingCount; i++ { 108 fmt.Printf("echo message %v\n", in.Message) 109 err := stream.Send(&pb.EchoResponse{Message: in.Message}) 110 if err != nil { 111 return err 112 } 113 } 114 return nil 115} 116 117func (s *server) ClientStreamingEcho(stream pb.Echo_ClientStreamingEchoServer) error { 118 fmt.Printf("--- ClientStreamingEcho ---\n") 119 // Create trailer in defer to record function return time. 120 defer func() { 121 trailer := metadata.Pairs("timestamp", time.Now().Format(timestampFormat)) 122 stream.SetTrailer(trailer) 123 }() 124 125 // Read metadata from client. 126 md, ok := metadata.FromIncomingContext(stream.Context()) 127 if !ok { 128 return status.Errorf(codes.DataLoss, "ClientStreamingEcho: failed to get metadata") 129 } 130 if t, ok := md["timestamp"]; ok { 131 fmt.Printf("timestamp from metadata:\n") 132 for i, e := range t { 133 fmt.Printf(" %d. %s\n", i, e) 134 } 135 } 136 137 // Create and send header. 138 header := metadata.New(map[string]string{"location": "MTV", "timestamp": time.Now().Format(timestampFormat)}) 139 stream.SendHeader(header) 140 141 // Read requests and send responses. 142 var message string 143 for { 144 in, err := stream.Recv() 145 if err == io.EOF { 146 fmt.Printf("echo last received message\n") 147 return stream.SendAndClose(&pb.EchoResponse{Message: message}) 148 } 149 message = in.Message 150 fmt.Printf("request received: %v, building echo\n", in) 151 if err != nil { 152 return err 153 } 154 } 155} 156 157func (s *server) BidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamingEchoServer) error { 158 fmt.Printf("--- BidirectionalStreamingEcho ---\n") 159 // Create trailer in defer to record function return time. 160 defer func() { 161 trailer := metadata.Pairs("timestamp", time.Now().Format(timestampFormat)) 162 stream.SetTrailer(trailer) 163 }() 164 165 // Read metadata from client. 166 md, ok := metadata.FromIncomingContext(stream.Context()) 167 if !ok { 168 return status.Errorf(codes.DataLoss, "BidirectionalStreamingEcho: failed to get metadata") 169 } 170 171 if t, ok := md["timestamp"]; ok { 172 fmt.Printf("timestamp from metadata:\n") 173 for i, e := range t { 174 fmt.Printf(" %d. %s\n", i, e) 175 } 176 } 177 178 // Create and send header. 179 header := metadata.New(map[string]string{"location": "MTV", "timestamp": time.Now().Format(timestampFormat)}) 180 stream.SendHeader(header) 181 182 // Read requests and send responses. 183 for { 184 in, err := stream.Recv() 185 if err == io.EOF { 186 return nil 187 } 188 if err != nil { 189 return err 190 } 191 fmt.Printf("request received %v, sending echo\n", in) 192 if err := stream.Send(&pb.EchoResponse{Message: in.Message}); err != nil { 193 return err 194 } 195 } 196} 197 198func main() { 199 flag.Parse() 200 rand.Seed(time.Now().UnixNano()) 201 lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port)) 202 if err != nil { 203 log.Fatalf("failed to listen: %v", err) 204 } 205 fmt.Printf("server listening at %v\n", lis.Addr()) 206 207 s := grpc.NewServer() 208 pb.RegisterEchoServer(s, &server{}) 209 s.Serve(lis) 210} 211