// NewConn creates a Conn. func NewConn(cc *ClientConn) (*Conn, error) { if cc.target == "" { return nil, ErrUnspecTarget } c := &Conn{ target: cc.target, dopts: cc.dopts, resetChan: make(chan int, 1), shutdownChan: make(chan struct{}), } if EnableTracing { c.events = trace.NewEventLog("grpc.ClientConn", c.target) } if !c.dopts.insecure { var ok bool for _, cd := range c.dopts.copts.AuthOptions { if _, ok := cd.(credentials.TransportAuthenticator); !ok { continue } ok = true } if !ok { return nil, ErrNoTransportSecurity } } else { for _, cd := range c.dopts.copts.AuthOptions { if cd.RequireTransportSecurity() { return nil, ErrCredentialsMisuse } } } c.stateCV = sync.NewCond(&c.mu) if c.dopts.block { if err := c.resetTransport(false); err != nil { c.Close() return nil, err } // Start to monitor the error status of transport. go c.transportMonitor() } else { // Start a goroutine connecting to the server asynchronously. go func() { if err := c.resetTransport(false); err != nil { grpclog.Printf("Failed to dial %s: %v; please retry.", c.target, err) c.Close() return } c.transportMonitor() }() } return c, nil }
// NewServer creates a gRPC server which has no service registered and has not // started to accept requests yet. func NewServer(opt ...ServerOption) *Server { var opts options for _, o := range opt { o(&opts) } if opts.codec == nil { // Set the default codec. opts.codec = protoCodec{} } s := &Server{ lis: make(map[net.Listener]bool), opts: opts, conns: make(map[transport.ServerTransport]bool), m: make(map[string]*service), } if EnableTracing { _, file, line, _ := runtime.Caller(1) s.events = trace.NewEventLog("grpc.Server", fmt.Sprintf("%s:%d", file, line)) } return s }