code: func (c *Client) Disconnect(timeout ...time.Duration) error {
  	c.mutex.Lock()
  	defer c.mutex.Unlock()
  
  	// check if connected
  	if atomic.LoadUint32(&c.state) != clientConnected {
  		return ErrClientNotConnected
  	}
  
  	// finish current packets
  	if len(timeout) > 0 {
  		c.futureStore.Await(timeout[0])
  	}
  
  	// set state
  	atomic.StoreUint32(&c.state, clientDisconnecting)
  
  	// send disconnect packet
  	err := c.send(packet.NewDisconnect(), false)
  
  	return c.end(err, true)
  }
docs: // Disconnect will send a Disconnect packet and close the connection.
  //
  // If a timeout is specified, the client will wait the specified amount of time
  // for all queued futures to complete or cancel. If no timeout is specified it
  // will not wait at all.