Class Jabber::Client
In: lib/xmpp4r/client.rb
Parent: Connection
Message Presence XMPPStanza Iq XMPPElement ErrorResponse X IqQuery JabberError ComponentAuthenticationFailure ArgumentError SOCKS5Error ServerError NoNameXmlnsRegistered ClientAuthenticationFailure Connection Client Component Client Singleton IdGenerator Comparable JID StandardError REXML::Element Stream IqQuery IqQueryVersion IqQueryRoster IqQueryBytestreams IqQueryRPC IqQueryMUCOwner IqQueryMUCAdmin IqQueryDiscoItems IqQueryDiscoInfo Responder SimpleResponder XRosterItem RosterXItem XMPPElement RosterItem IqFeature StreamHost IqSiFile IqSiFileRange IqSi StreamHostUsed C Body HTML UserItem XMUCUserInvite Tune Configuration Items Item IqPubSub Publish Event IqPubSubOwner Subscription Unsubscribe Feature Item Identity XDataField XDataReported XDataTitle XDataInstructions IqVcard XRoster RosterX X XMUC XMUCUser XDelay XData Iq IqCommand SOCKS5Bytestreams SOCKS5BytestreamsTarget SOCKS5BytestreamsInitiator SOCKS5BytestreamsServerStreamHost TCPSocket SOCKS5Socket IBB IBBTarget IBBInitiator XMLRPC::ParserWriterChooseMixin Client Server XMLRPC::ParseContentType XMLRPC::BasicServer MUCClient SimpleMUCClient MUC::UserItem XMUCUserItem IqQueryMUCAdminItem XParent Base Anonymous DigestMD5 Plain PubSub::ServiceHelper Helper SubscriptionConfig NodeConfig OwnerNodeConfig EventItems EventItem ServiceHelper NodeHelper FileSource Base Bot CallbackList Callback StreamParser Semaphore Helper Responder SOCKS5BytestreamsPeer SOCKS5BytestreamsServer IBBQueueItem Helper MUCBrowser NodeBrowser Responder Helper Helper lib/xmpp4r/message.rb lib/xmpp4r/connection.rb lib/xmpp4r/xmppstanza.rb lib/xmpp4r/iq.rb lib/xmpp4r/callbacks.rb lib/xmpp4r/idgenerator.rb lib/xmpp4r/stream.rb lib/xmpp4r/client.rb lib/xmpp4r/jid.rb lib/xmpp4r/x.rb lib/xmpp4r/streamparser.rb lib/xmpp4r/semaphore.rb lib/xmpp4r/errors.rb lib/xmpp4r/component.rb lib/xmpp4r/presence.rb lib/xmpp4r/xmppelement.rb lib/xmpp4r/query.rb XParent lib/xmpp4r/version/helper/responder.rb lib/xmpp4r/version/helper/simpleresponder.rb lib/xmpp4r/version/iq/version.rb Version lib/xmpp4r/roster/x/roster.rb lib/xmpp4r/roster/helper/roster.rb lib/xmpp4r/roster/iq/roster.rb Roster lib/xmpp4r/feature_negotiation/iq/feature.rb FeatureNegotiation lib/xmpp4r/command/iq/command.rb lib/xmpp4r/command/helper/responder.rb Command lib/xmpp4r/bytestreams/iq/si.rb lib/xmpp4r/bytestreams/helper/ibb/initiator.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb lib/xmpp4r/bytestreams/iq/bytestreams.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb lib/xmpp4r/bytestreams/helper/ibb/target.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb lib/xmpp4r/bytestreams/helper/ibb/base.rb Bytestreams lib/xmpp4r/caps/helper/helper.rb lib/xmpp4r/caps/c.rb Caps lib/xmpp4r/xhtml/html.rb XHTML lib/xmpp4r/rpc/helper/server.rb lib/xmpp4r/rpc/helper/client.rb lib/xmpp4r/rpc/iq/rpc.rb RPC lib/xmpp4r/muc/iq/mucadminitem.rb lib/xmpp4r/muc/x/muc.rb lib/xmpp4r/muc/item.rb lib/xmpp4r/muc/helper/simplemucclient.rb lib/xmpp4r/muc/iq/mucadmin.rb lib/xmpp4r/muc/helper/mucbrowser.rb lib/xmpp4r/muc/x/mucuseritem.rb lib/xmpp4r/muc/x/mucuserinvite.rb lib/xmpp4r/muc/iq/mucowner.rb lib/xmpp4r/muc/helper/mucclient.rb MUC lib/xmpp4r/delay/x/delay.rb Delay lib/xmpp4r/sasl.rb SASL lib/xmpp4r/tune/helper/helper.rb lib/xmpp4r/tune/tune.rb UserTune lib/xmpp4r/pubsub/children/item.rb lib/xmpp4r/pubsub/children/configuration.rb lib/xmpp4r/pubsub/children/subscription.rb lib/xmpp4r/pubsub/helper/servicehelper.rb lib/xmpp4r/pubsub/children/unsubscribe.rb lib/xmpp4r/pubsub/children/publish.rb lib/xmpp4r/pubsub/children/event.rb lib/xmpp4r/pubsub/iq/pubsub.rb lib/xmpp4r/pubsub/helper/nodebrowser.rb lib/xmpp4r/pubsub/helper/nodehelper.rb lib/xmpp4r/pubsub/children/items.rb lib/xmpp4r/pubsub/children/subscription_config.rb lib/xmpp4r/pubsub/children/node_config.rb PubSub lib/xmpp4r/httpbinding/client.rb HTTPBinding lib/xmpp4r/discovery/iq/discoinfo.rb lib/xmpp4r/discovery/helper/responder.rb lib/xmpp4r/discovery/iq/discoitems.rb Discovery lib/xmpp4r/dataforms/x/data.rb Dataforms lib/xmpp4r/bytestreams/helper/filetransfer.rb TransferSource FileTransfer lib/xmpp4r/vcard/helper/vcard.rb lib/xmpp4r/vcard/iq/vcard.rb Vcard lib/xmpp4r/framework/base.rb lib/xmpp4r/framework/bot.rb Framework Jabber dot/m_99_0.png

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.

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

[Source]

    # File lib/xmpp4r/client.rb, line 27
27:     def initialize(jid)
28:       super()
29:       @jid = (jid.kind_of?(JID) ? jid : JID.new(jid.to_s))
30:     end

Public Instance methods

Authenticate with the server

Throws ClientAuthenticationFailure

Authentication mechanisms are used in the following preference:

password:[String]

[Source]

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

See Client#auth_anonymous_sasl

[Source]

     # File lib/xmpp4r/client.rb, line 169
169:     def auth_anonymous
170:       auth_anonymous_sasl
171:     end

Shortcut for anonymous connection to server

Throws ClientAuthenticationFailure

[Source]

     # File lib/xmpp4r/client.rb, line 178
178:     def auth_anonymous_sasl
179:       if self.supports_anonymous?
180:         begin
181:           auth_sasl SASL.new(self, 'ANONYMOUS'), ""
182:         rescue
183:           Jabber::debuglog("#{$!.class}: #{$!}\n#{$!.backtrace.join("\n")}")
184:           raise ClientAuthenticationFailure, $!.to_s
185:         end
186:       else
187:         raise ClientAuthenticationFailure, 'Anonymous authentication unsupported'
188:       end
189:     end

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

Throws ServerError

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

[Source]

     # File lib/xmpp4r/client.rb, line 207
207:     def auth_nonsasl(password, digest=true)
208:       authset = nil
209:       if digest
210:         authset = Iq.new_authset_digest(@jid, @streamid.to_s, password)
211:       else
212:         authset = Iq.new_authset(@jid, password)
213:       end
214:       send_with_id(authset)
215:       $defout.flush
216: 
217:       true
218:     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 130
130:     def auth_sasl(sasl, password)
131:       sasl.auth(password)
132: 
133:       # Restart stream after SASL auth
134:       stop
135:       start
136:       # And wait for features - again
137:       @features_sem.wait
138: 
139:       # Resource binding (RFC3920 - 7)
140:       if @stream_features.has_key? 'bind'
141:         iq = Iq.new(:set)
142:         bind = iq.add REXML::Element.new('bind')
143:         bind.add_namespace @stream_features['bind']
144:         if jid.resource
145:           resource = bind.add REXML::Element.new('resource')
146:           resource.text = jid.resource
147:         end
148: 
149:         send_with_id(iq) do |reply|
150:           reported_jid = reply.first_element('jid')
151:           if reported_jid and reported_jid.text
152:             @jid = JID.new(reported_jid.text)
153:           end
154:         end
155:       end
156: 
157:       # Session starting
158:       if @stream_features.has_key? 'session'
159:         iq = Iq.new(:set)
160:         session = iq.add REXML::Element.new('session')
161:         session.add_namespace @stream_features['session']
162: 
163:         send_with_id(iq)
164:       end
165:     end

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

[Source]

    # File lib/xmpp4r/client.rb, line 77
77:     def close
78:       send("</stream:stream>")
79:       super
80:     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
use_ssl:[Boolean] Optional. Use (old, deprecated) SSL when connecting.
return:self

[Source]

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

Change the client‘s password

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

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

new_password:[String] New password

[Source]

     # File lib/xmpp4r/client.rb, line 307
307:     def password=(new_password)
308:       iq = Iq.new_query(:set, @jid.domain)
309:       iq.query.add_namespace('jabber:iq:register')
310:       iq.query.add(REXML::Element.new('username')).text = @jid.node
311:       iq.query.add(REXML::Element.new('password')).text = new_password
312: 
313:       err = nil
314:       send_with_id(iq)
315:     end

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

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

password:String
fields:{String=>String} additional registration information

XEP-0077 Defines the following fields for registration information: www.xmpp.org/extensions/xep-0077.html

‘username’ => ‘Account name associated with the user’ ‘nick’ => ‘Familiar name of the user’ ‘password’ => ‘Password or secret for the user’ ‘name’ => ‘Full name of the user’ ‘first’ => ‘First name or given name of the user’ ‘last’ => ‘Last name, surname, or family name of the user’ ‘email’ => ‘Email address of the user’ ‘address’ => ‘Street portion of a physical or mailing address’ ‘city’ => ‘Locality portion of a physical or mailing address’ ‘state’ => ‘Region portion of a physical or mailing address’ ‘zip’ => ‘Postal code portion of a physical or mailing address’ ‘phone’ => ‘Telephone number of the user’ ‘url’ => ‘URL to web page describing the user’ ‘date’ => ‘Some date (e.g., birth date, hire date, sign-up date)’

[Source]

     # File lib/xmpp4r/client.rb, line 276
276:     def register(password, fields={})
277:       reg = Iq.new_register(jid.node, password)
278:       reg.to = jid.domain
279:       fields.each { |name,value|
280:         reg.query.add(REXML::Element.new(name)).text = value
281:       }
282: 
283:       send_with_id(reg)
284:     end

Get instructions and available fields for registration

return:[instructions, fields] Where instructions is a String and fields is an Array of Strings

[Source]

     # File lib/xmpp4r/client.rb, line 223
223:     def register_info
224:       instructions = nil
225:       fields = []
226: 
227:       reg = Iq.new_registerget
228:       reg.to = jid.domain
229:       send_with_id(reg) do |answer|
230:         if answer.query
231:           answer.query.each_element { |e|
232:             if e.namespace == 'jabber:iq:register'
233:               if e.name == 'instructions'
234:                 instructions = e.text.strip
235:               else
236:                 fields << e.name
237:               end
238:             end
239:           }
240:         end
241: 
242:         true
243:       end
244: 
245:       [instructions, fields]
246:     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 291
291:     def remove_registration
292:       reg = Iq.new_register
293:       reg.to = jid.domain
294:       reg.query.add(REXML::Element.new('remove'))
295:       send_with_id(reg)
296:     end

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

[Source]

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

Reports whether or not anonymous authentication is reported by the client.

Returns true or false

[Source]

     # File lib/xmpp4r/client.rb, line 196
196:     def supports_anonymous?
197:       @stream_mechanisms.include? 'ANONYMOUS'
198:     end

[Validate]