// Serve accepts incoming connections on the listener lis, creating a new // ServerTransport and service goroutine for each. The service goroutines // read gRPC request and then call the registered handlers to reply to them. // Service returns when lis.Accept fails. func (s *Server) Serve(lis net.Listener) error { s.mu.Lock() if s.lis == nil { s.mu.Unlock() return ErrServerStopped } s.lis[lis] = true s.mu.Unlock() defer func() { lis.Close() s.mu.Lock() delete(s.lis, lis) s.mu.Unlock() }() for { c, err := lis.Accept() if err != nil { return err } if creds, ok := s.opts.creds.(credentials.TransportAuthenticator); ok { c, err = creds.ServerHandshake(c) if err != nil { grpclog.Println("grpc: Server.Serve failed to complete security handshake.") continue } } s.mu.Lock() if s.conns == nil { s.mu.Unlock() c.Close() return nil } st, err := transport.NewServerTransport("http2", c, s.opts.maxConcurrentStreams) if err != nil { s.mu.Unlock() c.Close() grpclog.Println("grpc: Server.Serve failed to create ServerTransport: ", err) continue } s.conns[st] = true s.mu.Unlock() go func() { st.HandleStreams(func(stream *transport.Stream) { s.handleStream(st, stream) }) s.mu.Lock() delete(s.conns, st) s.mu.Unlock() }() } }
// serveNewHTTP2Transport sets up a new http/2 transport (using the // gRPC http2 server transport in transport/http2_server.go) and // serves streams on it. // This is run in its own goroutine (it does network I/O in // transport.NewServerTransport). func (s *Server) serveNewHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) { st, err := transport.NewServerTransport("http2", c, s.opts.maxConcurrentStreams, authInfo) if err != nil { s.mu.Lock() s.errorf("NewServerTransport(%q) failed: %v", c.RemoteAddr(), err) s.mu.Unlock() c.Close() grpclog.Println("grpc: Server.Serve failed to create ServerTransport: ", err) return } if !s.addConn(st) { st.Close() return } s.serveStreams(st) }
// start starts server. Other goroutines should block on s.readyChan for futher operations. func (s *server) start(t *testing.T, port int, maxStreams uint32) { var err error if port == 0 { s.lis, err = net.Listen("tcp", ":0") } else { s.lis, err = net.Listen("tcp", ":"+strconv.Itoa(port)) } if err != nil { t.Fatalf("failed to listen: %v", err) } _, p, err := net.SplitHostPort(s.lis.Addr().String()) if err != nil { t.Fatalf("failed to parse listener address: %v", err) } s.port = p s.conns = make(map[transport.ServerTransport]bool) if s.readyChan != nil { close(s.readyChan) } for { conn, err := s.lis.Accept() if err != nil { return } st, err := transport.NewServerTransport("http2", conn, maxStreams, nil) if err != nil { return } s.mu.Lock() if s.conns == nil { s.mu.Unlock() st.Close() return } s.conns[st] = true s.mu.Unlock() h := &testStreamHandler{st} go st.HandleStreams(func(s *transport.Stream) { go h.handleStream(t, s) }) } }
// Serve accepts incoming connections on the listener lis, creating a new // ServerTransport and service goroutine for each. The service goroutines // read gRPC request and then call the registered handlers to reply to them. // Service returns when lis.Accept fails. func (s *Server) Serve(lis net.Listener) error { s.mu.Lock() s.printf("serving") if s.lis == nil { s.mu.Unlock() return ErrServerStopped } s.lis[lis] = true s.mu.Unlock() defer func() { lis.Close() s.mu.Lock() delete(s.lis, lis) s.mu.Unlock() }() for { c, err := lis.Accept() if err != nil { s.mu.Lock() s.printf("done serving; Accept = %v", err) s.mu.Unlock() return err } var authInfo credentials.AuthInfo if creds, ok := s.opts.creds.(credentials.TransportAuthenticator); ok { var conn net.Conn conn, authInfo, err = creds.ServerHandshake(c) if err != nil { s.mu.Lock() s.errorf("ServerHandshake(%q) failed: %v", c.RemoteAddr(), err) s.mu.Unlock() grpclog.Println("grpc: Server.Serve failed to complete security handshake.") continue } c = conn } s.mu.Lock() if s.conns == nil { s.mu.Unlock() c.Close() return nil } st, err := transport.NewServerTransport("http2", c, s.opts.maxConcurrentStreams, authInfo) if err != nil { s.errorf("NewServerTransport(%q) failed: %v", c.RemoteAddr(), err) s.mu.Unlock() c.Close() grpclog.Println("grpc: Server.Serve failed to create ServerTransport: ", err) continue } s.conns[st] = true s.mu.Unlock() go func() { var wg sync.WaitGroup st.HandleStreams(func(stream *transport.Stream) { var trInfo *traceInfo if EnableTracing { trInfo = &traceInfo{ tr: trace.New("grpc.Recv."+methodFamily(stream.Method()), stream.Method()), } trInfo.firstLine.client = false trInfo.firstLine.remoteAddr = st.RemoteAddr() stream.TraceContext(trInfo.tr) if dl, ok := stream.Context().Deadline(); ok { trInfo.firstLine.deadline = dl.Sub(time.Now()) } } wg.Add(1) go func() { s.handleStream(st, stream, trInfo) wg.Done() }() }) wg.Wait() s.mu.Lock() delete(s.conns, st) s.mu.Unlock() }() } }