Ravn::BDE::
BeaconListener
class
A simple client for beacon messages.
- address R
The multicast address
- callback R
The message callback
- port R
The port of the multicast group
- socket R
The UDP socket beacon messages will be sent to
new( address=Ravn::BDE::Beacon.multicast_address, port=Ravn::BDE::Beacon.multicast_port )
Create a new client that will listen for beacon messages.
def initialize( address=Ravn::BDE::Beacon.multicast_address, port=Ravn::BDE::Beacon.multicast_port )
@address = address
@port = port
@socket = self.create_listener_socket( address, port )
@running = false
@callback = nil
end
create_listener_socket( address, port )
Return a UDPSocket that’s set up with membership to the given multicast address.
def create_listener_socket( address, port )
self.log.info "Setting up listener on %s[%s]:%d" % [ address, Socket::INADDR_ANY, self.port ]
membership = IPAddr.new( address.to_s ).hton + IPAddr.new( '0.0.0.0' ).hton
socket = UDPSocket.new
socket.setsockopt( :IPPROTO_IP, :IP_ADD_MEMBERSHIP, membership )
socket.setsockopt( :SOL_SOCKET, :SO_REUSEPORT, 1 )
return socket
end
Register the given block
to be called on each beacon message.
def on_message( &block )
@callback = block
end
True while the listener is running
attr_predicate_accessor :running
Start listening for beacon messages.
def start
@thread = Thread.new( &self.method(:start_listening) )
end
Start listening for beacon messages and calling the on_message
handler for each one.
def start_listening
Thread.current.name = "beacon listener" unless Thread.current == Thread.main
self.socket.bind( Socket::INADDR_ANY, self.port )
self.running = true
while self.running?
begin
message, _ = self.socket.recvfrom( 1024 )
info = MessagePack.unpack( message )
self.callback&.call( info )
rescue => err
self.log.error "%p while reading from multicast: %s" % [ err.class, err.message ]
end
end
end
Stop the listener.
def stop
@running = false
end