Class Jabber::Client
In: lib/xmpp4r/client.rb
Parent: Connection
XMLStanza Message Presence Iq REXML::Element X IqQuery Error StreamHost IqSiFileRange IqSiFile StreamHostUsed IqSi IqFeature XRosterItem RosterItem XMUCUserItem XMUCUserInvite XDataField XDataReported XDataTitle XDataInstructions Feature Identity Item IqVcard Singleton IdGenerator Connection Client Component Comparable JID RuntimeError AuthenticationFailure ErrorException SOCKS5Error Stream SOCKS5Bytestreams SOCKS5BytestreamsTarget SOCKS5BytestreamsInitiator SOCKS5BytestreamsServerStreamHost TCPSocket SOCKS5Socket IqQuery IqQueryBytestreams IqQueryVersion IqQueryRoster IqQueryDiscoItems IqQueryDiscoInfo IBB IBBTarget IBBInitiator Responder SimpleResponder X XRoster XMUCUser XMUC XDelay XData MUCClient SimpleMUCClient Base DigestMD5 Plain FileSource StreamParser SOCKS5BytestreamsPeer SOCKS5BytestreamsServer IBBQueueItem Helper MUCBrowser Helper Helper lib/xmpp4r/authenticationfailure.rb lib/xmpp4r/idgenerator.rb lib/xmpp4r/connection.rb lib/xmpp4r/iq.rb lib/xmpp4r/jid.rb lib/xmpp4r/xmlstanza.rb lib/xmpp4r/errorexception.rb lib/xmpp4r/stream.rb lib/xmpp4r/client.rb lib/xmpp4r/x.rb lib/xmpp4r/streamparser.rb lib/xmpp4r/error.rb lib/xmpp4r/component.rb lib/xmpp4r/query.rb lib/xmpp4r/message.rb lib/xmpp4r/presence.rb lib/xmpp4r/bytestreams/helper/ibb/initiator.rb lib/xmpp4r/bytestreams/iq/si.rb lib/xmpp4r/bytestreams/iq/bytestreams.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb lib/xmpp4r/bytestreams/helper/ibb/base.rb lib/xmpp4r/bytestreams/helper/ibb/target.rb Bytestreams lib/xmpp4r/version/iq/version.rb lib/xmpp4r/version/helper/responder.rb lib/xmpp4r/version/helper/simpleresponder.rb Version lib/xmpp4r/feature_negotiation/iq/feature.rb FeatureNegotiation lib/xmpp4r/roster/helper/roster.rb lib/xmpp4r/roster/iq/roster.rb lib/xmpp4r/roster/x/roster.rb Roster lib/xmpp4r/muc/x/muc.rb lib/xmpp4r/muc/helper/mucclient.rb lib/xmpp4r/muc/x/mucuseritem.rb lib/xmpp4r/muc/helper/mucbrowser.rb lib/xmpp4r/muc/x/mucuserinvite.rb lib/xmpp4r/muc/helper/simplemucclient.rb MUC lib/xmpp4r/sasl.rb SASL lib/xmpp4r/bytestreams/helper/filetransfer.rb TransferSource FileTransfer lib/xmpp4r/delay/x/delay.rb Delay lib/xmpp4r/dataforms/x/data.rb Dataforms lib/xmpp4r/discovery/iq/discoinfo.rb lib/xmpp4r/discovery/iq/discoitems.rb Discovery lib/xmpp4r/vcard/helper/vcard.rb lib/xmpp4r/vcard/iq/vcard.rb Vcard Jabber Module: Jabber

The client class provides everything needed to build a basic XMPP Client.

If you want your connection to survive disconnects and timeouts, catch exception in Stream#on_exception and re-call Client#connect and Client#auth. Don‘t forget to re-send initial Presence and everything else you need to setup your session.

Methods

Attributes

jid  [R]  The client’s JID

Public Class methods

Create a new Client. If threaded mode is activated, callbacks are called as soon as messages are received; If it isn’t, you have to call Stream#process from time to time.

Remember to always put a resource in your JID unless the server can do SASL.

[Source]

    # File lib/xmpp4r/client.rb, line 31
31:     def initialize(jid, threaded = true)
32:       super(threaded)
33:       @jid = (jid.kind_of?(JID) ? jid : JID.new(jid.to_s))
34:     end

Public Instance methods

Authenticate with the server

Throws AuthenticationFailure

Authentication mechanisms are used in the following preference:

password:[String]

[Source]

     # File lib/xmpp4r/client.rb, line 108
108:     def auth(password)
109:       begin
110:         if @stream_mechanisms.include? 'DIGEST-MD5'
111:           auth_sasl SASL.new(self, 'DIGEST-MD5'), password
112:         elsif @stream_mechanisms.include? 'PLAIN'
113:           auth_sasl SASL.new(self, 'PLAIN'), password
114:         else
115:           auth_nonsasl(password)
116:         end
117:       rescue
118:         Jabber::debuglog("#{$!.class}: #{$!}\n#{$!.backtrace.join("\n")}")
119:         raise AuthenticationFailure.new, $!.to_s
120:       end
121:     end

Send auth with given password and wait for result (non-SASL)

Throws ErrorException

password:[String] the password
digest:[Boolean] use Digest authentication

[Source]

     # File lib/xmpp4r/client.rb, line 180
180:     def auth_nonsasl(password, digest=true)
181:       authset = nil
182:       if digest
183:         authset = Iq::new_authset_digest(@jid, @streamid.to_s, password)
184:       else
185:         authset = Iq::new_authset(@jid, password)
186:       end
187:       send_with_id(authset) do |r|
188:         true
189:       end
190:       $defout.flush
191: 
192:       true
193:     end

Use a SASL authentication mechanism and bind to a resource

If there was no resource given in the jid, the jid/resource generated by the server will be accepted.

This method should not be used directly. Instead, Client#auth may look for the best mechanism suitable.

sasl:Descendant of [Jabber::SASL::Base]
password:[String]

[Source]

     # File lib/xmpp4r/client.rb, line 133
133:     def auth_sasl(sasl, password)
134:       sasl.auth(password)
135: 
136:       # Restart stream after SASL auth
137:       stop
138:       start
139:       # And wait for features - again
140:       @features_lock.lock
141:       @features_lock.unlock
142: 
143:       # Resource binding (RFC3920 - 7)
144:       if @stream_features.has_key? 'bind'
145:         iq = Iq.new(:set)
146:         bind = iq.add REXML::Element.new('bind')
147:         bind.add_namespace @stream_features['bind']
148:         if jid.resource
149:           resource = bind.add REXML::Element.new('resource')
150:           resource.text = jid.resource
151:         end
152: 
153:         send_with_id(iq) { |reply|
154:           reported_jid = reply.first_element('jid')
155:           if reply.type == :result and reported_jid and reported_jid.text
156:             @jid = JID.new(reported_jid.text)
157:           end
158: 
159:           true
160:         }
161:       end
162: 
163:       # Session starting
164:       if @stream_features.has_key? 'session'
165:         iq = Iq.new(:set)
166:         session = iq.add REXML::Element.new('session')
167:         session.add_namespace @stream_features['session']
168: 
169:         send_with_id(iq) { true }
170:       end
171:     end

Close the connection, sends </stream:stream> tag first

[Source]

    # File lib/xmpp4r/client.rb, line 80
80:     def close
81:       send("</stream:stream>")
82:       super
83:     end

connect to the server (chaining-friendly)

If you omit the optional host argument SRV records for your jid will be resolved. If none works, fallback is connecting to the domain part of the jid.

host:[String] Optional c2s host, will be extracted from jid if nil
return:self

[Source]

    # File lib/xmpp4r/client.rb, line 45
45:     def connect(host = nil, port = 5222)
46:       if host.nil?
47:         begin
48:           srv = []
49:           Resolv::DNS.open { |dns|
50:             # If ruby version is too old and SRV is unknown, this will raise a NameError
51:             # which is catched below
52:             Jabber::debuglog("RESOLVING:\n_xmpp-client._tcp.#{@jid.domain} (SRV)")
53:             srv = dns.getresources("_xmpp-client._tcp.#{@jid.domain}", Resolv::DNS::Resource::IN::SRV)
54:           }
55:           # Sort SRV records: lowest priority first, highest weight first
56:           srv.sort! { |a,b| (a.priority != b.priority) ? (a.priority <=> b.priority) : (b.weight <=> a.weight) }
57: 
58:           srv.each { |record|
59:             begin
60:               connect(record.target.to_s, record.port)
61:               # Success
62:               return self
63:             rescue SocketError
64:               # Try next SRV record
65:             end
66:           }
67:         rescue NameError
68:           $stderr.puts "Resolv::DNS does not support SRV records. Please upgrade to ruby-1.8.3 or later!"
69:         end
70:         # Fallback to normal connect method
71:       end
72:       
73:       super(host.nil? ? jid.domain : host, port)
74:       self
75:     end

Change the client’s password

Threading is suggested, as this code waits for an answer.

Raises an exception upon error response (ErrorException from Stream#send_with_id).

new_password:[String] New password

[Source]

     # File lib/xmpp4r/client.rb, line 233
233:     def password=(new_password)
234:       iq = Iq::new_query(:set, @jid.domain)
235:       iq.query.add_namespace('jabber:iq:register')
236:       iq.query.add(REXML::Element.new('username')).text = @jid.node
237:       iq.query.add(REXML::Element.new('password')).text = new_password
238: 
239:       err = nil
240:       send_with_id(iq) { |answer|
241:         if answer.type == :result
242:           true
243:         else
244:           false
245:         end
246:       }
247:     end

Register a new user account (may be used instead of Client#auth)

This method may raise ErrorException if the registration was not successful.

[Source]

     # File lib/xmpp4r/client.rb, line 201
201:     def register(password)
202:       reg = Iq.new_register(jid.node, password)
203:       reg.to = jid.domain
204:       send_with_id(reg) { |answer|
205:         true
206:       }
207:     end

Remove the registration of a user account

*WARNING:* this deletes your roster and everything else stored on the server!

[Source]

     # File lib/xmpp4r/client.rb, line 214
214:     def remove_registration
215:       reg = Iq.new_register
216:       reg.to = jid.domain
217:       reg.query.add(REXML::Element.new('remove'))
218:       send_with_id(reg) { |answer|
219:         p answer.to_s
220:         true
221:       }
222:     end

Start the stream-parser and send the client-specific stream opening element

[Source]

    # File lib/xmpp4r/client.rb, line 87
87:     def start
88:       super
89:       send(generate_stream_start(@jid.domain)) { |e|
90:         if e.name == 'stream'
91:           true
92:         else
93:           false
94:         end
95:       }
96:     end

[Validate]