code: func (c *client) Publish(topic string, qos byte, retained bool, payload interface{}) Token {
  	token := newToken(packets.Publish).(*PublishToken)
  	DEBUG.Println(CLI, "enter Publish")
  	switch {
  	case !c.IsConnected():
  		token.setError(ErrNotConnected)
  		return token
  	case c.connectionStatus() == reconnecting && qos == 0:
  		token.flowComplete()
  		return token
  	}
  	pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
  	pub.Qos = qos
  	pub.TopicName = topic
  	pub.Retain = retained
  	switch payload.(type) {
  	case string:
  		pub.Payload = []byte(payload.(string))
  	case []byte:
  		pub.Payload = payload.([]byte)
  	default:
  		token.setError(fmt.Errorf("Unknown payload type"))
  		return token
  	}
  
  	if pub.Qos != 0 && pub.MessageID == 0 {
  		pub.MessageID = c.getID(token)
  		token.messageID = pub.MessageID
  	}
  	persistOutbound(c.persist, pub)
  	if c.connectionStatus() == reconnecting {
  		DEBUG.Println(CLI, "storing publish message (reconnecting), topic:", topic)
  	} else {
  		DEBUG.Println(CLI, "sending publish message, topic:", topic)
  		c.obound <- &PacketAndToken{p: pub, t: token}
  	}
  	return token
  }
docs: // Publish will publish a message with the specified QoS and content
  // to the specified topic.
  // Returns a token to track delivery of the message to the broker