class SSDP::Producer
Attributes
services[RW]
uuid[RW]
Public Class Methods
new(options={})
click to toggle source
# File lib/ssdp/producer.rb, line 10 def initialize(options={}) @uuid = SecureRandom.uuid @services = {} @listener = { :socket => nil, :thread => nil } @notifier = { :thread => nil } @options = SSDP::DEFAULTS.merge options end
Public Instance Methods
add_service(type, location_or_param_hash)
click to toggle source
# File lib/ssdp/producer.rb, line 42 def add_service(type, location_or_param_hash) params = {} if location_or_param_hash.is_a? Hash params = location_or_param_hash else params['AL'] = location_or_param_hash params['LOCATION'] = location_or_param_hash end @services[type] = params send_notification type, params if @options[:notifier] && running? end
remove_service(type)
click to toggle source
# File lib/ssdp/producer.rb, line 55 def remove_service(type) @services.delete type end
running?()
click to toggle source
# File lib/ssdp/producer.rb, line 18 def running? @listener[:thread] != nil end
start()
click to toggle source
# File lib/ssdp/producer.rb, line 22 def start start_notifier if @notifier[:thread].nil? && @options[:notifier] start_listener if @listener[:thread].nil? end
stop(bye_bye=true)
click to toggle source
# File lib/ssdp/producer.rb, line 27 def stop(bye_bye=true) was_running = running? if @listener[:thread] @listener[:thread].exit @listener[:thread] = nil end if @notifier[:thread] @notifier[:thread].exit @notifier[:thread] = nil end @services.each { |type, params| send_bye_bye type, params } if bye_bye && @options[:notifier] && was_running end
Private Instance Methods
process_ssdp(message, consumer)
click to toggle source
# File lib/ssdp/producer.rb, line 61 def process_ssdp(message, consumer) ssdp = SSDP.parse_ssdp message return unless ssdp[:status].start_with? 'M-SEARCH * HTTP' return if ssdp[:params]['ST'].nil? if @options[:respond_to_all] && ssdp[:params]['ST'].downcase == 'ssdp:all' @services.each { |service, _| send_response service, consumer } return end return if @services[ssdp[:params]['ST']].nil? send_response ssdp[:params]['ST'], consumer end
send_broadcast_packet(body)
click to toggle source
# File lib/ssdp/producer.rb, line 116 def send_broadcast_packet(body) broadcaster = SSDP.create_broadcaster broadcaster.send body, 0, @options[:broadcast], @options[:port] broadcaster.close end
send_bye_bye(type, params)
click to toggle source
# File lib/ssdp/producer.rb, line 98 def send_bye_bye(type, params) bye_bye_body = "NOTIFY * HTTP/1.1\r\n" \ "HOST: #{@options[:broadcast]}:#{@options[:port]}\r\n" \ "NTS: ssdp:byebye\r\n" \ "NT: #{type}\r\n" \ "USN: uuid:#{@uuid}\r\n" + params.map { |k, v| "#{k}: #{v}" }.join("\r\n") + "\r\n\r\n" send_broadcast_packet bye_bye_body end
send_direct_packet(body, endpoint)
click to toggle source
# File lib/ssdp/producer.rb, line 110 def send_direct_packet(body, endpoint) udp_socket = UDPSocket.new udp_socket.send body, 0, endpoint[:address], endpoint[:port] udp_socket.close end
send_notification(type, params)
click to toggle source
# File lib/ssdp/producer.rb, line 86 def send_notification(type, params) notify_body = "NOTIFY * HTTP/1.1\r\n" \ "HOST: #{@options[:broadcast]}:#{@options[:port]}\r\n" \ "NTS: ssdp:alive\r\n" \ "NT: #{type}\r\n" \ "USN: uuid:#{@uuid}\r\n" + params.map { |k, v| "#{k}: #{v}" }.join("\r\n") + "\r\n\r\n" send_broadcast_packet notify_body end
send_response(type, consumer)
click to toggle source
# File lib/ssdp/producer.rb, line 76 def send_response(type, consumer) params = @services[type] response_body = "HTTP/1.1 200 OK\r\n" \ "ST: #{type}\r\n" \ "USN: uuid:#{@uuid}\r\n" + params.map { |k, v| "#{k}: #{v}" }.join("\r\n") + "\r\n\r\n" send_direct_packet response_body, consumer end
start_listener()
click to toggle source
# File lib/ssdp/producer.rb, line 122 def start_listener @listener[:socket] = SSDP.create_listener @options @listener[:thread] = Thread.new do begin loop do message, consumer = @listener[:socket].recvfrom @options[:maxpack] process_ssdp message, { :address => consumer[3], :port => consumer[1] } unless @services.count == 0 end ensure @listener[:socket].close end end end
start_notifier()
click to toggle source
# File lib/ssdp/producer.rb, line 136 def start_notifier @notifier[:thread] = Thread.new do loop do sleep @options[:interval] @services.each { |type, params| send_notification type, params } end end end