client.go
func (c *Client) Start() (
	<-chan irc.Message,
	chan<- irc.Message,
	<-chan error,
	error,
) {
	if err := c.connect(); err != nil {
		return nil, nil, nil, fmt.Errorf("error connecting: %s", err)
	}

	if err := c.writeMessage(irc.Message{
		Command: "NICK",
		Params:  []string{c.nick},
	}); err != nil {
		_ = c.conn.Close()
		return nil, nil, nil, err
	}

	if err := c.writeMessage(irc.Message{
		Command: "USER",
		Params:  []string{c.nick, "0", "*", c.nick},
	}); err != nil {
		_ = c.conn.Close()
		return nil, nil, nil, err
	}

	c.recvChan = make(chan irc.Message, 512)
	c.sendChan = make(chan irc.Message, 512)
	c.errChan = make(chan error, 512)
	c.doneChan = make(chan struct{})

	c.wg = &sync.WaitGroup{}

	c.wg.Add(1)
	go c.reader(c.recvChan)

	c.wg.Add(1)
	go c.writer(c.sendChan)

	return c.recvChan, c.sendChan, c.errChan, nil
}
func (c *Client) Start() (
	<-chan irc.Message,
	chan<- irc.Message,
	<-chan error,
	error,
) {
	if err := c.connect(); err != nil {
		return nil, nil, nil, fmt.Errorf("error connecting: %s", err)
	}

	if err := c.writeMessage(irc.Message{
		Command: "NICK",
		Params:  []string{c.nick},
	}); err != nil {
		_ = c.conn.Close()
		return nil, nil, nil, err
	}

	if err := c.writeMessage(irc.Message{
		Command: "USER",
		Params:  []string{c.nick, "0", "*", c.nick},
	}); err != nil {
		_ = c.conn.Close()
		return nil, nil, nil, err
	}

	c.recvChan = make(chan irc.Message, 512)
	c.sendChan = make(chan irc.Message, 512)
	c.errChan = make(chan error, 512)
	c.doneChan = make(chan struct{})

	c.wg = &sync.WaitGroup{}

	c.wg.Add(1)
	go c.reader(c.recvChan)

	c.wg.Add(1)
	go c.writer(c.sendChan)

	return c.recvChan, c.sendChan, c.errChan, nil
}
// Start starts a client's connection and registers.
//
// The client responds to PING commands.
//
// All messages received from the server will be sent on the receive channel.
//
// Messages you send to the send channel will be sent to the server.
//
// If an error occurs, we send a message on the error channel. If you receive a
// message on that channel, you must stop the client.
//
// The caller must call Stop() to clean up the client.