class LIFX::LAN::Transport::UDP

@api private @private

Public Class Methods

new(*args) click to toggle source
Calls superclass method LIFX::LAN::Transport::new
# File lib/lifx/lan/transport/udp.rb, line 8
def initialize(*args)
  super
  @socket = create_socket
end

Public Instance Methods

close() click to toggle source
Calls superclass method LIFX::LAN::Transport#close
# File lib/lifx/lan/transport/udp.rb, line 67
def close
  super
  return if !@socket
  @socket.close
  @socket = nil
  if @listener
    @listener.abort
  end
end
connected?() click to toggle source
# File lib/lifx/lan/transport/udp.rb, line 13
def connected?
  !!@socket
end
listen(ip: self.host, port: self.port) click to toggle source
# File lib/lifx/lan/transport/udp.rb, line 41
def listen(ip: self.host, port: self.port)
  if @listener
    raise "Socket already being listened to"
  end

  @listener = Thread.start do
    reader = UDPSocket.new
    reader.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
    reader.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEPORT, true) if Socket.const_defined?('SO_REUSEPORT')
    reader.bind(ip, port)
    loop do
      begin
        bytes, (_, _, ip, _) = reader.recvfrom(128)
        logger.debug("<- #{bytes.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join}")
        message = Message.unpack(bytes)
        logger.debug("<- Incoming message: #{message}")
        notify_observers(:message_received, {message: message, ip: ip, transport: self})
      rescue Message::UnpackError
        if Config.log_invalid_messages
          logger.warn("#{self}: Unrecognised bytes: #{bytes.bytes.map { |b| '%02x ' % b }.join}")
        end
      end
    end
  end
end
write(message) click to toggle source
# File lib/lifx/lan/transport/udp.rb, line 28
def write(message)
  logger.debug("-> Broadcast UDP message: #{message}")
  logger.debug("-> #{message.to_hex}")
  data = message.pack
  @socket.send(data, 0, host, port)
  true
rescue => ex
  logger.warn("#{self}: Error on #write: #{ex}")
  logger.debug("#{self}: Backtrace: #{ex.backtrace.join("\n")}")
  close
  false
end
write_raw(data) click to toggle source
# File lib/lifx/lan/transport/udp.rb, line 17
def write_raw(data)
  logger.debug("-> #{data}")
  @socket.send(data.scan(/../).map { |x| x.hex.chr }.join, 0, host, port)
  true
rescue => ex
  logger.warn("#{self}: Error on #write: #{ex}")
  logger.debug("#{self}: Backtrace: #{ex.backtrace.join("\n")}")
  close
  false
end

Protected Instance Methods

create_socket() click to toggle source
# File lib/lifx/lan/transport/udp.rb, line 79
def create_socket
  UDPSocket.new.tap do |socket|
    socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
  end
end