code: func ClientFromConfig(c *Config) (*RPCClient, error) {
  	// Setup the defaults
  	if c.Timeout == 0 {
  		c.Timeout = DefaultTimeout
  	}
  
  	// Try to dial to serf
  	conn, err := net.DialTimeout("tcp", c.Addr, c.Timeout)
  	if err != nil {
  		return nil, err
  	}
  
  	// Create the client
  	client := &RPCClient{
  		seq:        0,
  		timeout:    c.Timeout,
  		conn:       conn.(*net.TCPConn),
  		reader:     bufio.NewReader(conn),
  		writer:     bufio.NewWriter(conn),
  		dispatch:   make(map[uint64]seqHandler),
  		shutdownCh: make(chan struct{}),
  	}
  	client.dec = codec.NewDecoder(client.reader,
  		&codec.MsgpackHandle{RawToString: true, WriteExt: true})
  	client.enc = codec.NewEncoder(client.writer,
  		&codec.MsgpackHandle{RawToString: true, WriteExt: true})
  	go client.listen()
  
  	// Do the initial handshake
  	if err := client.handshake(); err != nil {
  		client.Close()
  		return nil, err
  	}
  
  	// Do the initial authentication if needed
  	if c.AuthKey != "" {
  		if err := client.auth(c.AuthKey); err != nil {
  			client.Close()
  			return nil, err
  		}
  	}
  
  	return client, err
  }
docs: // ClientFromConfig is used to create a new RPC client given the
  // configuration object. This will return a client, or an error if
  // the connection could not be established.