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
-
#filters ⇒ Object
readonly
Internal.
-
#handlers ⇒ Object
readonly
Internal.
-
#host ⇒ Object
readonly
Public.
-
#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(host, 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(host, port = 5222) ⇒ Connection
Returns a new instance of Connection.
27 28 29 30 31 32 33 34 35 36 |
# File 'lib/jabber4r/connection.rb', line 27 def initialize(host, port = 5222) @host, @port = host, port @handlers, @filters = {}, {} @poll_counter = 10 @mutex = Mutex.new @status = DISCONNECTED end |
Instance Attribute Details
#filters ⇒ Object (readonly)
Internal
22 23 24 |
# File 'lib/jabber4r/connection.rb', line 22 def filters @filters end |
#handlers ⇒ Object (readonly)
Internal
22 23 24 |
# File 'lib/jabber4r/connection.rb', line 22 def handlers @handlers end |
#host ⇒ Object (readonly)
Public
16 17 18 |
# File 'lib/jabber4r/connection.rb', line 16 def host @host end |
#input ⇒ Object (readonly)
Public
16 17 18 |
# File 'lib/jabber4r/connection.rb', line 16 def input @input end |
#output ⇒ Object (readonly)
Public
16 17 18 |
# File 'lib/jabber4r/connection.rb', line 16 def output @output end |
#parser ⇒ Object (readonly)
Internal
25 26 27 |
# File 'lib/jabber4r/connection.rb', line 25 def parser @parser end |
#parser_thread ⇒ Object (readonly)
Internal
19 20 21 |
# File 'lib/jabber4r/connection.rb', line 19 def parser_thread @parser_thread end |
#poll_thread ⇒ Object (readonly)
Internal
19 20 21 |
# File 'lib/jabber4r/connection.rb', line 19 def poll_thread @poll_thread end |
#port ⇒ Object (readonly)
Public
16 17 18 |
# File 'lib/jabber4r/connection.rb', line 16 def port @port end |
#socket ⇒ Object (readonly)
Internal
25 26 27 |
# File 'lib/jabber4r/connection.rb', line 25 def socket @socket end |
#status ⇒ Object (readonly)
Public
16 17 18 |
# File 'lib/jabber4r/connection.rb', line 16 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
98 99 100 101 102 |
# File 'lib/jabber4r/connection.rb', line 98 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
69 70 71 72 73 74 75 |
# File 'lib/jabber4r/connection.rb', line 69 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
42 43 44 45 46 47 48 49 50 |
# File 'lib/jabber4r/connection.rb', line 42 def connect @socket = TCPSocket.new(@host, @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
81 82 83 |
# File 'lib/jabber4r/connection.rb', line 81 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
199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/jabber4r/connection.rb', line 199 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
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/jabber4r/connection.rb', line 174 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
88 89 90 |
# File 'lib/jabber4r/connection.rb', line 88 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.
226 227 228 |
# File 'lib/jabber4r/connection.rb', line 226 def on_connection_exception(&block) @exception_block = block end |
#parse_failure(exception = nil) ⇒ Object
230 231 232 |
# File 'lib/jabber4r/connection.rb', line 230 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.
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/jabber4r/connection.rb', line 242 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
161 162 163 164 165 166 167 |
# File 'lib/jabber4r/connection.rb', line 161 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
131 132 133 |
# File 'lib/jabber4r/connection.rb', line 131 def receive(xml) @mutex.synchronize { process_xml_from_socket(xml) } end |
#register_parsing_thread ⇒ Object
Internal: Register new parser thread
Returns nothing
55 56 57 |
# File 'lib/jabber4r/connection.rb', line 55 def register_parsing_thread @parser_thread = Thread.new { parser.parse } end |
#register_polling_thread ⇒ Object
Internal: Register new polling thread
Returns nothing
62 63 64 |
# File 'lib/jabber4r/connection.rb', line 62 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
109 110 111 |
# File 'lib/jabber4r/connection.rb', line 109 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
121 122 123 |
# File 'lib/jabber4r/connection.rb', line 121 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
217 218 219 |
# File 'lib/jabber4r/connection.rb', line 217 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
144 145 146 147 148 149 150 151 152 153 |
# File 'lib/jabber4r/connection.rb', line 144 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 |