Class Jabber::Client
In: lib/xmpp4r/client.rb
Parent: Connection
Message Presence XMPPStanza Iq XMPPElement X IqQuery Error Singleton IdGenerator Connection Client Component Client Comparable JID RuntimeError ErrorException AuthenticationFailure NoNameXmlnsRegistered SOCKS5Error REXML::Element Stream SOCKS5Bytestreams SOCKS5BytestreamsTarget SOCKS5BytestreamsInitiator XMPPElement StreamHost IqSiFileRange IqSiFile StreamHostUsed IqSi IqFeature XRosterItem RosterItem XMUCUserItem XMUCUserInvite IqPubSub Items Subscription IqPubSubOwner Item Event Feature Identity Item XDataField XDataReported XDataTitle XDataInstructions IqVcard SOCKS5BytestreamsServerStreamHost TCPSocket SOCKS5Socket IqQuery IqQueryBytestreams IqQueryVersion IqQueryRoster IqQueryRPC IqQueryMUCOwner IqQueryDiscoItems IqQueryDiscoInfo IBB IBBTarget IBBInitiator Responder SimpleResponder Iq IqCommand RosterXItem XRoster RosterX X XMUCUser XMUC XDelay XData XMLRPC::ParserWriterChooseMixin Client Server XMLRPC::ParseContentType XMLRPC::BasicServer XParent MUCClient SimpleMUCClient Base DigestMD5 Plain FileSource ServiceHelper NodeHelper CallbackList Callback Semaphore StreamParser SOCKS5BytestreamsPeer SOCKS5BytestreamsServer IBBQueueItem Responder Helper MUCBrowser Helper NodeBrowser Helper lib/xmpp4r/authenticationfailure.rb lib/xmpp4r/xmppstanza.rb lib/xmpp4r/callbacks.rb lib/xmpp4r/idgenerator.rb lib/xmpp4r/connection.rb lib/xmpp4r/iq.rb lib/xmpp4r/jid.rb lib/xmpp4r/errorexception.rb lib/xmpp4r/semaphore.rb lib/xmpp4r/client.rb lib/xmpp4r/stream.rb lib/xmpp4r/x.rb lib/xmpp4r/streamparser.rb lib/xmpp4r/error.rb lib/xmpp4r/component.rb lib/xmpp4r/query.rb lib/xmpp4r/xmppelement.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/server.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.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 XParent lib/xmpp4r/version/iq/version.rb lib/xmpp4r/version/helper/responder.rb lib/xmpp4r/version/helper/simpleresponder.rb Version lib/xmpp4r/command/iq/command.rb lib/xmpp4r/command/helper/responder.rb Command 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/rpc/helper/server.rb lib/xmpp4r/rpc/helper/client.rb lib/xmpp4r/rpc/iq/rpc.rb RPC 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/iq/mucowner.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/pubsub/stanzas/subscription.rb lib/xmpp4r/pubsub/helper/servicehelper.rb lib/xmpp4r/pubsub/stanzas/item.rb lib/xmpp4r/pubsub/helper/nodehelper.rb lib/xmpp4r/pubsub/iq/pubsub.rb lib/xmpp4r/pubsub/stanzas/event.rb lib/xmpp4r/pubsub/helper/nodebrowser.rb lib/xmpp4r/pubsub/stanzas/items.rb PubSub lib/xmpp4r/httpbinding/client.rb HTTPBinding lib/xmpp4r/discovery/iq/discoinfo.rb lib/xmpp4r/discovery/iq/discoitems.rb Discovery lib/xmpp4r/dataforms/x/data.rb Dataforms lib/xmpp4r/vcard/helper/vcard.rb lib/xmpp4r/vcard/iq/vcard.rb Vcard Jabber dot/m_81_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 29
29:     def initialize(jid, threaded = true)
30:       super(threaded)
31:       @jid = (jid.kind_of?(JID) ? jid : JID.new(jid.to_s))
32:     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 106
106:     def auth(password)
107:       begin
108:         if @stream_mechanisms.include? 'DIGEST-MD5'
109:           auth_sasl SASL.new(self, 'DIGEST-MD5'), password
110:         elsif @stream_mechanisms.include? 'PLAIN'
111:           auth_sasl SASL.new(self, 'PLAIN'), password
112:         else
113:           auth_nonsasl(password)
114:         end
115:       rescue
116:         Jabber::debuglog("#{$!.class}: #{$!}\n#{$!.backtrace.join("\n")}")
117:         raise AuthenticationFailure.new, $!.to_s
118:       end
119:     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 177
177:     def auth_nonsasl(password, digest=true)
178:       authset = nil
179:       if digest
180:         authset = Iq::new_authset_digest(@jid, @streamid.to_s, password)
181:       else
182:         authset = Iq::new_authset(@jid, password)
183:       end
184:       send_with_id(authset) do |r|
185:         true
186:       end
187:       $defout.flush
188: 
189:       true
190:     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 131
131:     def auth_sasl(sasl, password)
132:       sasl.auth(password)
133: 
134:       # Restart stream after SASL auth
135:       stop
136:       start
137:       # And wait for features - again
138:       @features_sem.wait
139: 
140:       # Resource binding (RFC3920 - 7)
141:       if @stream_features.has_key? 'bind'
142:         iq = Iq.new(:set)
143:         bind = iq.add REXML::Element.new('bind')
144:         bind.add_namespace @stream_features['bind']
145:         if jid.resource
146:           resource = bind.add REXML::Element.new('resource')
147:           resource.text = jid.resource
148:         end
149: 
150:         send_with_id(iq) { |reply|
151:           reported_jid = reply.first_element('jid')
152:           if reply.type == :result and reported_jid and reported_jid.text
153:             @jid = JID.new(reported_jid.text)
154:           end
155: 
156:           true
157:         }
158:       end
159: 
160:       # Session starting
161:       if @stream_features.has_key? 'session'
162:         iq = Iq.new(:set)
163:         session = iq.add REXML::Element.new('session')
164:         session.add_namespace @stream_features['session']
165: 
166:         send_with_id(iq) { true }
167:       end
168:     end

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

[Source]

    # File lib/xmpp4r/client.rb, line 78
78:     def close
79:       send("</stream:stream>")
80:       super
81:     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 43
43:     def connect(host = nil, port = 5222)
44:       if host.nil?
45:         begin
46:           srv = []
47:           Resolv::DNS.open { |dns|
48:             # If ruby version is too old and SRV is unknown, this will raise a NameError
49:             # which is catched below
50:             Jabber::debuglog("RESOLVING:\n_xmpp-client._tcp.#{@jid.domain} (SRV)")
51:             srv = dns.getresources("_xmpp-client._tcp.#{@jid.domain}", Resolv::DNS::Resource::IN::SRV)
52:           }
53:           # Sort SRV records: lowest priority first, highest weight first
54:           srv.sort! { |a,b| (a.priority != b.priority) ? (a.priority <=> b.priority) : (b.weight <=> a.weight) }
55: 
56:           srv.each { |record|
57:             begin
58:               connect(record.target.to_s, record.port)
59:               # Success
60:               return self
61:             rescue SocketError
62:               # Try next SRV record
63:             end
64:           }
65:         rescue NameError
66:           $stderr.puts "Resolv::DNS does not support SRV records. Please upgrade to ruby-1.8.3 or later!"
67:         end
68:         # Fallback to normal connect method
69:       end
70:       
71:       super(host.nil? ? jid.domain : host, port)
72:       self
73:     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 230
230:     def password=(new_password)
231:       iq = Iq::new_query(:set, @jid.domain)
232:       iq.query.add_namespace('jabber:iq:register')
233:       iq.query.add(REXML::Element.new('username')).text = @jid.node
234:       iq.query.add(REXML::Element.new('password')).text = new_password
235: 
236:       err = nil
237:       send_with_id(iq) { |answer|
238:         if answer.type == :result
239:           true
240:         else
241:           false
242:         end
243:       }
244:     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 198
198:     def register(password)
199:       reg = Iq.new_register(jid.node, password)
200:       reg.to = jid.domain
201:       send_with_id(reg) { |answer|
202:         true
203:       }
204:     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 211
211:     def remove_registration
212:       reg = Iq.new_register
213:       reg.to = jid.domain
214:       reg.query.add(REXML::Element.new('remove'))
215:       send_with_id(reg) { |answer|
216:         p answer.to_s
217:         true
218:       }
219:     end

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

[Source]

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

[Validate]