Class: Blather::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/blather/client/client.rb

Overview

# Blather Client

Blather’s Client class provides a set of helpers for working with common XMPP tasks such as setting up and starting the connection, settings status, registering and dispatching filters and handlers and roster management.

Client can be used separately from the DSL if you’d like to implement your own DSL Here’s the echo example using the client without the DSL:

require 'blather/client/client'
client = Client.setup '[email protected]', 'echo'

client.register_handler(:ready) do
  puts "Connected ! send messages to #{client.jid.stripped}."
end

client.register_handler :subscription, :request? do |s|
  client.write s.approve!
end

client.register_handler :message, :chat?, :body => 'exit' do |m|
  client.write Blather::Stanza::Message.new(m.from, 'Exiting...')
  client.close
end

client.register_handler :message, :chat?, :body do |m|
  client.write Blather::Stanza::Message.new(m.from, "You sent: #{m.body}")
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeClient

Returns a new instance of Client.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/blather/client/client.rb', line 52

def initialize  # @private
  @state = :initializing

  @status = Stanza::Presence::Status.new
  @handlers = {}
  @tmp_handlers = {}
  @filters = {:before => [], :after => []}
  @roster = Roster.new self
  @caps = Stanza::Capabilities.new

  @handler_queue = GirlFriday::WorkQueue.new :handle_stanza, :size => 5 do |stanza|
    handle_data stanza
  end

  setup_initial_handlers
end

Instance Attribute Details

#capsObject (readonly)

Returns the value of attribute caps.



35
36
37
# File 'lib/blather/client/client.rb', line 35

def caps
  @caps
end

#jidObject (readonly)

Returns the value of attribute jid.



35
36
37
# File 'lib/blather/client/client.rb', line 35

def jid
  @jid
end

#rosterObject (readonly)

Returns the value of attribute roster.



35
36
37
# File 'lib/blather/client/client.rb', line 35

def roster
  @roster
end

Class Method Details

.setup(jid, password, host = nil, port = nil, certs = nil, connect_timeout = nil) ⇒ Blather::Client

Create a new client and set it up

domain

Parameters:

  • jid (Blather::JID, #to_s)

    the JID to authorize with

  • password (String)

    the password to authorize with

  • host (String) (defaults to: nil)

    if this isn’t set it’ll be resolved off the JID’s

  • port (Fixnum, String) (defaults to: nil)

    the port to connect to.

Returns:



48
49
50
# File 'lib/blather/client/client.rb', line 48

def self.setup(jid, password, host = nil, port = nil, certs = nil, connect_timeout = nil)
  self.new.setup(jid, password, host, port, certs, connect_timeout)
end

Instance Method Details

#clear_handlers(type, *guards) ⇒ Object

Clear handlers with given guards

Parameters:

  • type (Symbol, nil)

    remove filters for a specific handler

  • guards (guards)

    take a look at the guards documentation



130
131
132
# File 'lib/blather/client/client.rb', line 130

def clear_handlers(type, *guards)
  @handlers[type].delete_if { |g, _| g == guards }
end

#closeObject

Close the connection



170
171
172
# File 'lib/blather/client/client.rb', line 170

def close
  self.stream.close_connection_after_writing
end

#connected?Boolean

Check whether the client is currently connected.

Returns:

  • (Boolean)


70
71
72
# File 'lib/blather/client/client.rb', line 70

def connected?
  setup? && !@stream.nil? && !@stream.stopped?
end

#handle_data(stanza) ⇒ Object



191
192
193
194
195
196
197
# File 'lib/blather/client/client.rb', line 191

def handle_data(stanza)
  catch(:halt) do
    run_filters :before, stanza
    handle_stanza stanza
    run_filters :after, stanza
  end
end

#post_init(stream, jid = nil) ⇒ Object



175
176
177
178
179
# File 'lib/blather/client/client.rb', line 175

def post_init(stream, jid = nil)
  @stream = stream
  @jid = JID.new(jid) if jid
  self.jid.node ? client_post_init : ready!
end

#receive_data(stanza) ⇒ Object



187
188
189
# File 'lib/blather/client/client.rb', line 187

def receive_data(stanza)
  @handler_queue << stanza
end

#register_filter(type, handler = nil, *guards) {|Blather::Stanza| ... } ⇒ Object

Register a filter to be run before or after the handler chain is run.

Parameters:

  • type (<:before, :after>)

    the filter type

  • handler (Symbol, nil) (defaults to: nil)

    set the filter on a specific handler

  • guards (guards)

    take a look at the guards documentation

Yields:



110
111
112
113
114
115
# File 'lib/blather/client/client.rb', line 110

def register_filter(type, handler = nil, *guards, &filter)
  unless [:before, :after].include?(type)
    raise "Invalid filter: #{type}. Must be :before or :after"
  end
  @filters[type] << [guards, handler, filter]
end

#register_handler(type, *guards) {|Blather::Stanza| ... } ⇒ Object

Register a handler

Parameters:

  • type (Symbol, nil)

    set the filter on a specific handler

  • guards (guards)

    take a look at the guards documentation

Yields:



139
140
141
142
143
# File 'lib/blather/client/client.rb', line 139

def register_handler(type, *guards, &handler)
  check_handler type, guards
  @handlers[type] ||= []
  @handlers[type] << [guards, handler]
end

#register_tmp_handler(id) {|Blather::Stanza| ... } ⇒ Object

Register a temporary handler. Temporary handlers are based on the ID of the JID and live only until a stanza with said ID is received.

Parameters:

  • id (#to_s)

    the ID of the stanza that should be handled

Yields:



122
123
124
# File 'lib/blather/client/client.rb', line 122

def register_tmp_handler(id, &handler)
  @tmp_handlers[id.to_s] = handler
end

#runObject Also known as: connect

Start the connection.

The stream type used is based on the JID. If a node exists it uses Blather::Stream::Client otherwise Blather::Stream::Component



97
98
99
100
101
# File 'lib/blather/client/client.rb', line 97

def run
  raise 'not setup!' unless setup?
  klass = @setup[0].node ? Blather::Stream::Client : Blather::Stream::Component
  klass.start self, *@setup
end

#setup(jid, password, host = nil, port = nil, certs = nil, connect_timeout = nil) ⇒ Object



205
206
207
208
209
210
211
212
213
# File 'lib/blather/client/client.rb', line 205

def setup(jid, password, host = nil, port = nil, certs = nil, connect_timeout = nil)
  @jid = JID.new(jid)
  @setup = [@jid, password]
  @setup << host
  @setup << port
  @setup << certs
  @setup << connect_timeout
  self
end

#setup?Boolean

Returns:

  • (Boolean)


200
201
202
# File 'lib/blather/client/client.rb', line 200

def setup?
  @setup.is_a? Array
end

#statusObject

Get the current status. Taken from the ‘state` attribute of Status



75
76
77
# File 'lib/blather/client/client.rb', line 75

def status
  @status.state
end

#status=(state) ⇒ Object

Set the status. Status can be set with either a single value or an array containing

[state, message, to].



83
84
85
86
87
88
89
90
91
# File 'lib/blather/client/client.rb', line 83

def status=(state)
  state, msg, to = state

  status = Stanza::Presence::Status.new state, msg
  status.to = to
  @status = status unless to

  write status
end

#unbindObject



182
183
184
# File 'lib/blather/client/client.rb', line 182

def unbind
  call_handler_for(:disconnected, nil) || (EM.reactor_running? && EM.stop)
end

#write(stanza) ⇒ Object

Write data to the stream

Parameters:

  • stanza (#to_xml, #to_s)

    the content to send down the wire



148
149
150
# File 'lib/blather/client/client.rb', line 148

def write(stanza)
  self.stream.send(stanza)
end

#write_with_handler(stanza) {|Blather::Stanza| ... } ⇒ Object

Helper that will create a temporary handler for the stanza being sent before writing it to the stream.

client.write_with_handler(stanza) { |s| "handle stanza here" }

is equivalent to:

client.register_tmp_handler(stanza.id) { |s| "handle stanza here" }
client.write stanza

Parameters:

Yields:



164
165
166
167
# File 'lib/blather/client/client.rb', line 164

def write_with_handler(stanza, &handler)
  register_tmp_handler stanza.id, &handler
  write stanza
end