Class: XwotDiscovery::XwotProtocol

Inherits:
Protocol
  • Object
show all
Defined in:
lib/xwot_discovery/protocol.rb

Overview

Prototype: The Xwot Protocol Discovery implements the protocol interface.

Constant Summary collapse

TTL =

time-to-live

1
MULTICAST_ADDR =

multicast group

"224.0.0.15"
BIND_ADDR =
"0.0.0.0"
PORT =
2015
NAME =
"XWOT-DISCOVERY"
VERSION =
"1.0"
CRLN =
"\r\n"
FLAGS =
0
RECEIVE_MAX_BYTES =
256

Instance Method Summary collapse

Constructor Details

#initializeXwotProtocol

Returns a new instance of XwotProtocol.



47
48
49
50
# File 'lib/xwot_discovery/protocol.rb', line 47

def initialize
  @socket = nil
  @observer = nil
end

Instance Method Details

#closeObject



97
98
99
# File 'lib/xwot_discovery/protocol.rb', line 97

def close
  @socket.close if !@socket.nil?
end

#listenObject



52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/xwot_discovery/protocol.rb', line 52

def listen
  init
  Thread.new do
    loop do
      Thread.start(receive) do |data|
        lines = data.split(CRLN)
        msg_hash = parse(lines)
        message = Message.new(msg_hash)
        #puts "#{Thread.current} - #{msg_hash}\n"
        @observer.dispatch(message)
      end
    end
  end
end

#notify_me(subject) ⇒ Object



133
134
135
# File 'lib/xwot_discovery/protocol.rb', line 133

def notify_me(subject)
  @observer = subject
end

#parse(lines) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/xwot_discovery/protocol.rb', line 67

def parse(lines)
  msg_hash = {
    method: '',
    protocol: '',
    urn: '*',
    payload: []
  }

  payload = false
  lines.each_with_index do |line, index|
    if index == 0
      method, urn, protocol = line.split(' ')
      msg_hash[:method] = method
      msg_hash[:protocol] = protocol
      msg_hash[:urn] = urn
    elsif payload
      msg_hash[:payload] ||= []
      msg_hash[:payload] << line
    elsif !line.empty?
      header_field, header_value = line.split(' ')
      header_field = header_field[0...-1].downcase.tr('-','_').to_sym
      msg_hash[header_field] = header_value
    elsif line.empty?
      payload = true
    end
  end
  msg_hash[:payload] = msg_hash[:payload].join('')
  msg_hash
end

#receiveObject



128
129
130
131
# File 'lib/xwot_discovery/protocol.rb', line 128

def receive
  data, _ = @socket.recvfrom(RECEIVE_MAX_BYTES)
  data
end

#send(message) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/xwot_discovery/protocol.rb', line 101

def send(message)
  client_socket = UDPSocket.open
  client_socket.setsockopt(:IPPROTO_IP, :IP_MULTICAST_TTL, TTL)

  urn = if message.urn.nil?
    '*'
  else
    message.urn
  end

  msg = ""
  msg += "#{message.method} #{urn} #{NAME}/#{VERSION}#{CRLN}"
  msg += "HOST: #{MULTICAST_ADDR}:#{PORT}#{CRLN}"
  msg += "HOSTNAME: #{Socket.gethostname}#{CRLN}"

  if ['alive', 'bye', 'update'].include?(message.method)
    msg += "LOCATION: #{message.location}#{CRLN}"
    msg += "CONTENT-TYPE: #{message.content_type}#{CRLN}"
    msg += "#{CRLN}"
    msg += "#{message.payload}#{CRLN}"
  end

  msg += "#{CRLN}"
  client_socket.send(msg, FLAGS, MULTICAST_ADDR, PORT)
  client_socket.close
end