def publish(topic, payload = '', retain = false, qos = 0)
      raise ArgumentError, 'Topic name cannot be nil' if topic.nil?
      raise ArgumentError, 'Topic name cannot be empty' if topic.empty?

      packet = MQTT::Packet::Publish.new(
        :id => next_packet_id,
        :qos => qos,
        :retain => retain,
        :topic => topic,
        :payload => payload
      )

      # Send the packet
      res = send_packet(packet)

      return if qos.zero?

      Timeout.timeout(@ack_timeout) do
        while connected?
          @pubacks_semaphore.synchronize do
            return res if @pubacks.delete(packet.id)
          end
          # FIXME: make threads communicate with each other, instead of polling
          # (using a pipe and select ?)
          sleep 0.01
        end
      end

      -1
    end
def publish(topic, payload = '', retain = false, qos = 0)
      raise ArgumentError, 'Topic name cannot be nil' if topic.nil?
      raise ArgumentError, 'Topic name cannot be empty' if topic.empty?

      packet = MQTT::Packet::Publish.new(
        :id => next_packet_id,
        :qos => qos,
        :retain => retain,
        :topic => topic,
        :payload => payload
      )

      # Send the packet
      res = send_packet(packet)

      return if qos.zero?

      Timeout.timeout(@ack_timeout) do
        while connected?
          @pubacks_semaphore.synchronize do
            return res if @pubacks.delete(packet.id)
          end
          # FIXME: make threads communicate with each other, instead of polling
          # (using a pipe and select ?)
          sleep 0.01
        end
      end

      -1
    end
Publish a message on a particular topic to the MQTT server.