Class: Jabber::Connection
- Inherits:
-
Object
- Object
- Jabber::Connection
- Defined in:
- lib/jabber4r/connection.rb
Overview
The connection class encapsulates the connection to the Jabber service including managing the socket and controlling the parsing of the Jabber XML stream.
Constant Summary collapse
- DISCONNECTED =
1
- CONNECTED =
2
Instance Attribute Summary collapse
-
#domain ⇒ Object
readonly
Public.
-
#filters ⇒ Object
readonly
Internal.
-
#handlers ⇒ Object
readonly
Internal.
-
#input ⇒ Object
readonly
Public.
-
#output ⇒ Object
readonly
Public.
-
#parser ⇒ Object
readonly
Internal.
-
#parser_thread ⇒ Object
readonly
Internal.
-
#poll_thread ⇒ Object
readonly
Internal.
-
#port ⇒ Object
readonly
Public.
-
#socket ⇒ Object
readonly
Internal.
-
#status ⇒ Object
readonly
Public.
Instance Method Summary collapse
-
#add_filter(name, &block) ⇒ Object
Public: Adds a filter block to process received XML messages.
-
#close ⇒ Object
(also: #disconnect)
Public: Closes the connection to the Jabber service.
-
#connect ⇒ Object
Public: Connects to the Jabber server through a TCP Socket and starts the Jabber parser.
-
#connected? ⇒ Boolean
Public: Returns if this connection is connected to a Jabber service.
-
#consume_xml_by_filters(xml) ⇒ Object
Internal: Processes a received ParsedXMLElement by filters.
-
#consume_xml_by_handlers(xml) ⇒ Object
Internal: Processes a received ParsedXMLElement by handlers.
-
#disconnected? ⇒ Boolean
Public: Returns if this connection is NOT connected to a Jabber service.
-
#initialize(domain, port = 5222) ⇒ Connection
constructor
A new instance of Connection.
-
#on_connection_exception(&block) ⇒ Object
Mounts a block to handle exceptions if they occur during the poll send.
- #parse_failure(exception = nil) ⇒ Object
-
#poll ⇒ Object
Starts a polling thread to send “keep alive” data to prevent the Jabber connection from closing for inactivity.
-
#process_xml_from_socket(xml) ⇒ Object
Internal: Processes a received ParsedXMLElement and executes registered handlers and filters against it.
-
#receive(xml) ⇒ Object
Public: Receiving xml element, and processing it NOTE: Synchonized by Mutex.
-
#register_parsing_thread ⇒ Object
Internal: Register new parser thread.
-
#register_polling_thread ⇒ Object
Internal: Register new polling thread.
-
#remove_filter(name) ⇒ Object
Public: Removes a filter block.
-
#send(xml, proc_object = nil, &block) ⇒ Object
Public: Receiving xml element, and processing it NOTE: Synchonized by Mutex.
-
#wait_for_consume? ⇒ Boolean
Internal: Should we wait for next part of socket data.
-
#write_to_socket(xml, handler = nil, &block) ⇒ Object
Internal: Sends XML data to the socket and (optionally) waits to process received data.
Constructor Details
#initialize(domain, port = 5222) ⇒ Connection
Returns a new instance of Connection.
28 29 30 31 32 33 34 35 36 37 |
# File 'lib/jabber4r/connection.rb', line 28 def initialize(domain, port = 5222) @domain, @port = domain, port @handlers, @filters = {}, {} @poll_counter = 10 @mutex = Mutex.new @status = DISCONNECTED end |
Instance Attribute Details
#domain ⇒ Object (readonly)
Public
17 18 19 |
# File 'lib/jabber4r/connection.rb', line 17 def domain @domain end |
#filters ⇒ Object (readonly)
Internal
23 24 25 |
# File 'lib/jabber4r/connection.rb', line 23 def filters @filters end |
#handlers ⇒ Object (readonly)
Internal
23 24 25 |
# File 'lib/jabber4r/connection.rb', line 23 def handlers @handlers end |
#input ⇒ Object (readonly)
Public
17 18 19 |
# File 'lib/jabber4r/connection.rb', line 17 def input @input end |
#output ⇒ Object (readonly)
Public
17 18 19 |
# File 'lib/jabber4r/connection.rb', line 17 def output @output end |
#parser ⇒ Object (readonly)
Internal
26 27 28 |
# File 'lib/jabber4r/connection.rb', line 26 def parser @parser end |
#parser_thread ⇒ Object (readonly)
Internal
20 21 22 |
# File 'lib/jabber4r/connection.rb', line 20 def parser_thread @parser_thread end |
#poll_thread ⇒ Object (readonly)
Internal
20 21 22 |
# File 'lib/jabber4r/connection.rb', line 20 def poll_thread @poll_thread end |
#port ⇒ Object (readonly)
Public
17 18 19 |
# File 'lib/jabber4r/connection.rb', line 17 def port @port end |
#socket ⇒ Object (readonly)
Internal
26 27 28 |
# File 'lib/jabber4r/connection.rb', line 26 def socket @socket end |
#status ⇒ Object (readonly)
Public
17 18 19 |
# File 'lib/jabber4r/connection.rb', line 17 def status @status end |
Instance Method Details
#add_filter(name, &block) ⇒ Object
Public: Adds a filter block to process received XML messages
name - String the name of filter block - Block of code
Returns nothing
99 100 101 102 103 |
# File 'lib/jabber4r/connection.rb', line 99 def add_filter(name, &block) raise ArgumentError, "Expected block to be given" if block.nil? @filters[name] = block end |
#close ⇒ Object Also known as: disconnect
Public: Closes the connection to the Jabber service
Returns nothing
70 71 72 73 74 75 76 |
# File 'lib/jabber4r/connection.rb', line 70 def close parser_thread.kill if parser_thread # why if? poll_thread.kill socket.close if socket @status = DISCONNECTED end |
#connect ⇒ Object
Public: Connects to the Jabber server through a TCP Socket and starts the Jabber parser.
Returns nothing
43 44 45 46 47 48 49 50 51 |
# File 'lib/jabber4r/connection.rb', line 43 def connect @socket = TCPSocket.new(@domain, @port) @parser = Jabber::Protocol.Parser.new(socket, self) register_parsing_thread register_polling_thread @status = CONNECTED end |
#connected? ⇒ Boolean
Public: Returns if this connection is connected to a Jabber service
Returns boolean
82 83 84 |
# File 'lib/jabber4r/connection.rb', line 82 def connected? status == CONNECTED end |
#consume_xml_by_filters(xml) ⇒ Object
Internal: Processes a received ParsedXMLElement by filters
xml - ParsedXMLElement The received element
Returns boolean
200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/jabber4r/connection.rb', line 200 def consume_xml_by_filters(xml) filters.each_value do |block| begin block.call(xml) return true if xml.element_consumed? rescue Exception => error puts error.to_s puts error.backtrace.join("\n") end end false end |
#consume_xml_by_handlers(xml) ⇒ Object
Internal: Processes a received ParsedXMLElement by handlers
xml - ParsedXMLElement The received element
Returns boolean
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/jabber4r/connection.rb', line 175 def consume_xml_by_handlers(xml) handlers.each do |thread, block| begin block.call(xml) if xml.element_consumed? handlers.delete(thread) thread.wakeup if thread.alive? return true end rescue Exception => error puts error.to_s puts error.backtrace.join("\n") end end false end |
#disconnected? ⇒ Boolean
Public: Returns if this connection is NOT connected to a Jabber service
Returns boolean
89 90 91 |
# File 'lib/jabber4r/connection.rb', line 89 def disconnected? status == DISCONNECTED end |
#on_connection_exception(&block) ⇒ Object
Mounts a block to handle exceptions if they occur during the poll send. This will likely be the first indication that the socket dropped in a Jabber Session.
227 228 229 |
# File 'lib/jabber4r/connection.rb', line 227 def on_connection_exception(&block) @exception_block = block end |
#parse_failure(exception = nil) ⇒ Object
231 232 233 |
# File 'lib/jabber4r/connection.rb', line 231 def parse_failure(exception = nil) Thread.new { @exception_block.call(exception) if @exception_block } end |
#poll ⇒ Object
Starts a polling thread to send “keep alive” data to prevent the Jabber connection from closing for inactivity.
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/jabber4r/connection.rb', line 243 def poll sleep 10 while true sleep 2 @poll_counter = @poll_counter - 1 if @poll_counter < 0 begin send(" \t ") rescue Thread.new {@exception_block.call if @exception_block} break end end end end |
#process_xml_from_socket(xml) ⇒ Object
Internal: Processes a received ParsedXMLElement and executes registered handlers and filters against it
xml - ParsedXMLElement The received element
Returns nothing
162 163 164 165 166 167 168 |
# File 'lib/jabber4r/connection.rb', line 162 def process_xml_from_socket(xml) sleep 0.1 while wait_for_consume? Jabber.debug("RECEIVED:\n#{xml}") consume_xml_by_handlers(xml) || consume_xml_by_filters(xml) end |
#receive(xml) ⇒ Object
Public: Receiving xml element, and processing it NOTE: Synchonized by Mutex
xml_element - ParsedXMLElement the received from socket xml element
Returns nothing
132 133 134 |
# File 'lib/jabber4r/connection.rb', line 132 def receive(xml) @mutex.synchronize { process_xml_from_socket(xml) } end |
#register_parsing_thread ⇒ Object
Internal: Register new parser thread
Returns nothing
56 57 58 |
# File 'lib/jabber4r/connection.rb', line 56 def register_parsing_thread @parser_thread = Thread.new { parser.parse } end |
#register_polling_thread ⇒ Object
Internal: Register new polling thread
Returns nothing
63 64 65 |
# File 'lib/jabber4r/connection.rb', line 63 def register_polling_thread @poll_thread = Thread.new { poll } end |
#remove_filter(name) ⇒ Object
Public: Removes a filter block
name - String the name of filter
Returns Block of code
110 111 112 |
# File 'lib/jabber4r/connection.rb', line 110 def remove_filter(name) filters.delete(name) end |
#send(xml, proc_object = nil, &block) ⇒ Object
Public: Receiving xml element, and processing it NOTE: Synchonized by Mutex
xml - String the string containing xml proc_object - Proc the proc object to call (default: nil) block - Block of ruby code
Returns nothing
122 123 124 |
# File 'lib/jabber4r/connection.rb', line 122 def send(xml, proc_object = nil, &block) @mutex.synchronize { write_to_socket(xml, proc_object, &block) } end |
#wait_for_consume? ⇒ Boolean
Internal: Should we wait for next part of socket data
Returns boolean
218 219 220 |
# File 'lib/jabber4r/connection.rb', line 218 def wait_for_consume? handlers.size.zero? && filters.size.zero? end |
#write_to_socket(xml, handler = nil, &block) ⇒ Object
Internal: Sends XML data to the socket and (optionally) waits to process received data. NOTE: If both habdler and block are given, handler has higher proirity
xml - String the xml data to send handler - [Proc|Lambda|#call] the proc object or labda to handle response data (optional) block - Block the block of ruby code (optional)
Returns nothing
145 146 147 148 149 150 151 152 153 154 |
# File 'lib/jabber4r/connection.rb', line 145 def write_to_socket(xml, handler = nil, &block) Jabber.debug("SENDING:\n#{xml}") handler = block if handler.nil? handlers[Thread.current] = handler unless handler.nil? socket.write(xml) @poll_counter = 10 end |