lib/milight/v6/socket.rb in milight-v6-0.1.1 vs lib/milight/v6/socket.rb in milight-v6-0.2.0
- old
+ new
@@ -3,44 +3,68 @@
require "logger"
require "socket"
module Milight
module V6
+ # Send and receive UDP packets.
class Socket
READ_TIMEOUT = 5
- def initialize(host, port)
- @socket = UDPSocket.new
- @socket.connect(host, port)
+ attr_reader :host, :port
- @logger = Logger.new(STDOUT)
- @logger.level = Logger::INFO if ENV["MILIGHT_DEBUG"] != "1"
+ def initialize(host, port)
+ @host = host
+ @port = port
end
def send_bytes(bytes)
- @logger.debug("Sending: #{format_bytes_as_hex(bytes)}")
+ logger.debug("Sending: #{format_bytes_as_hex(bytes)}")
- @socket.send(bytes.pack('C*'), 0)
+ socket.send(bytes.pack('C*'), 0, @host, @port)
end
def receive_bytes
- response = @socket.recvfrom_nonblock(128).first
+ response, address = socket.recvfrom_nonblock(128)
bytes = response.unpack('C*')
- @logger.debug("Received: #{format_bytes_as_hex(bytes)}")
+ logger.debug("Received: #{format_bytes_as_hex(bytes)}")
- bytes
+ [bytes, address.last]
rescue IO::WaitReadable
- ready = IO.select([@socket], nil, nil, READ_TIMEOUT)
+ ready = IO.select([socket], nil, nil, READ_TIMEOUT)
retry if ready
- return false
+ return nil
end
+ def close
+ socket.close
+ end
+
private
+ def socket
+ @socket ||= begin
+ socket = UDPSocket.new
+
+ if @host == "<broadcast>" || @host == "255.255.255.255"
+ socket.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_BROADCAST, true)
+ end
+
+ socket
+ end
+ end
+
+ def logger
+ @logger ||= begin
+ logger = Logger.new(STDOUT)
+ logger.level = Logger::INFO if ENV["MILIGHT_DEBUG"] != "1"
+ logger
+ end
+ end
+
def format_bytes_as_hex(bytes)
- bytes.map { |s| format("0x%02X", s) }
+ bytes.map { |s| format("0x%02X", s) }.join(", ")
end
end
end
end