code: func (cli *Client) handlePUBLISH(p packet.Packet) error {
  	// Get the PUBLISH Packet.
  	publish := p.(*packet.PUBLISH)
  
  	switch publish.QoS {
  	case mqtt.QoS0:
  		// Lock for reading.
  		cli.muConn.RLock()
  
  		// Unlock.
  		defer cli.muConn.RUnlock()
  
  		// Handle the Application Message.
  		cli.handleMessage(publish.TopicName, publish.Message)
  
  		return nil
  	case mqtt.QoS1:
  		// Lock for reading.
  		cli.muConn.RLock()
  
  		// Unlock.
  		defer cli.muConn.RUnlock()
  
  		// Handle the Application Message.
  		cli.handleMessage(publish.TopicName, publish.Message)
  
  		// Create a PUBACK Packet.
  		puback, err := packet.NewPUBACK(&packet.PUBACKOptions{
  			PacketID: publish.PacketID,
  		})
  		if err != nil {
  			return err
  		}
  
  		// Send the Packet to the Server.
  		cli.conn.send <- puback
  
  		return nil
  	default:
  		// Lock for update.
  		cli.muSess.Lock()
  
  		// Unlock.
  		defer cli.muSess.Unlock()
  
  		// Validate the Packet Identifier.
  		if _, exist := cli.sess.receivingPackets[publish.PacketID]; exist {
  			return packet.ErrInvalidPacketID
  		}
  
  		// Set the Packet to the Session.
  		cli.sess.receivingPackets[publish.PacketID] = p
  
  		// Create a PUBREC Packet.
  		pubrec, err := packet.NewPUBREC(&packet.PUBRECOptions{
  			PacketID: publish.PacketID,
  		})
  		if err != nil {
  			return err
  		}
  
  		// Send the Packet to the Server.
  		cli.conn.send <- pubrec
  
  		return nil
  	}
  }
docs: // handlePUBLISH handles the PUBLISH Packet.