Class Jabber::HTTPBinding::Client
In: lib/xmpp4r/httpbinding/client.rb
Parent: Jabber::Client

This class implements an alternative Client using HTTP Binding (JEP0124).

This class is designed to be a drop-in replacement for Jabber::Client, except for the Jabber::HTTP::Client#connect method which takes an URI as argument.

HTTP requests are buffered to not exceed the negotiated ‘polling’ and ‘requests’ parameters.

Stanzas in HTTP resonses may be delayed to arrive in the order defined by ‘rid’ parameters.

Debugging

Turning Jabber::debug to true will make debug output not only spit out stanzas but HTTP request/response bodies, too.

Methods

Attributes

http_content_type  [RW]  Content-Type to be used for communication (you can set this to "text/html")
http_hold  [RW]  The server may hold this amount of stanzas to reduce number of HTTP requests
http_wait  [RW]  The server should wait this value seconds if there is no stanza to be received

Public Class methods

Initialize

jid:[JID or String]

[Source]

    # File lib/xmpp4r/httpbinding/client.rb, line 47
47:       def initialize(jid)
48:         super
49: 
50:         @lock = Mutex.new
51:         @pending_requests = 0
52:         @last_send = Time.at(0)
53:         @send_buffer = ''
54: 
55:         @http_requests = 1
56:         @http_wait = 20
57:         @http_hold = 1
58:         @http_content_type = 'text/xml; charset=utf-8'
59:       end

Public Instance methods

Close the session by sending <presence type=‘unavailable’/>

[Source]

     # File lib/xmpp4r/httpbinding/client.rb, line 129
129:       def close
130:         @status = DISCONNECTED
131:         send(Jabber::Presence.new.set_type(:unavailable))
132:       end

Set up the stream using uri as the HTTP Binding URI

You may optionally pass host and port parameters to make use of the JEP0124 ‘route’ feature.

uri:[URI::Generic or String]
host:[String] Optional host to route to
port:[Fixnum] Port for route feature

[Source]

     # File lib/xmpp4r/httpbinding/client.rb, line 70
 70:       def connect(uri, host=nil, port=5222)
 71:         uri = URI::parse(uri) unless uri.kind_of? URI::Generic
 72:         @uri = uri
 73: 
 74:         @allow_tls = false  # Shall be done at HTTP level
 75:         @stream_mechanisms = []
 76:         @stream_features = {}
 77:         @http_rid = IdGenerator.generate_id.to_i
 78:         @pending_rid = @http_rid
 79:         @pending_rid_lock = Semaphore.new
 80: 
 81:         req_body = REXML::Element.new('body')
 82:         req_body.attributes['rid'] = @http_rid
 83:         req_body.attributes['content'] = @http_content_type
 84:         req_body.attributes['hold'] = @http_hold.to_s
 85:         req_body.attributes['wait'] = @http_wait.to_s
 86:         req_body.attributes['to'] = @jid.domain
 87:         if host
 88:           req_body.attributes['route'] = "xmpp:#{host}:#{port}"
 89:         end
 90:         req_body.attributes['secure'] = 'true'
 91:         req_body.attributes['xmlns'] = 'http://jabber.org/protocol/httpbind'
 92:         res_body = post(req_body)
 93:         unless res_body.name == 'body'
 94:           raise 'Response body is no <body/> element'
 95:         end
 96: 
 97:         @streamid = res_body.attributes['authid']
 98:         @status = CONNECTED
 99:         @http_sid = res_body.attributes['sid']
100:         @http_wait = res_body.attributes['wait'].to_i if res_body.attributes['wait']
101:         @http_hold = res_body.attributes['hold'].to_i if res_body.attributes['hold']
102:         @http_inactivity = res_body.attributes['inactivity'].to_i
103:         @http_polling = res_body.attributes['polling'].to_i
104:         @http_polling = 5 if @http_polling == 0
105:         @http_requests = res_body.attributes['requests'].to_i
106:         @http_requests = 1 if @http_requests == 0
107: 
108:         receive_elements_with_rid(@http_rid, res_body.children)
109: 
110:         @features_sem.run
111:       end

Ensure that there is one pending request

Will be automatically called if you‘ve sent a stanza.

[Source]

     # File lib/xmpp4r/httpbinding/client.rb, line 118
118:       def ensure_one_pending_request
119:         return if is_disconnected?
120: 
121:         if @lock.synchronize { @pending_requests } < 1
122:           send_data('')
123:         end
124:       end

[Validate]