Class: Jabber::Bytestreams::IBB

Class | Jabber::Bytestreams::IBB
In: | lib/xmpp4r/bytestreams/helper/ibb/base.rb
Parent: | Object

In-Band Bytestreams (JEP-0047) implementation

Don‘t use directly, use IBBInitiator and IBBTarget

In-Band Bytestreams should only be used when transferring very small amounts of binary data, because it is slow and increases server load drastically.

Note that the constructor takes a lot of arguments. In-Band Bytestreams do not specify a way to initiate the stream, this should be done via Stream Initiation.

### Methods

active? close flush new read write

### Constants

NS_IBB | = | 'http://jabber.org/protocol/ibb'

### Public Class methods

new(stream, session_id, my_jid, peer_jid)

Create a new bytestream

Will register a <message/> callback to intercept data of this stream. This data will be buffered, you can retrieve it with receive

[Source]

        # File lib/xmpp4r/bytestreams/helper/ibb/base.rb, line 30
    30:       def initialize(stream, session_id, my_jid, peer_jid)
    31:         @stream = stream
    32:         @session_id = session_id
    33:         @my_jid = (my_jid.kind_of?(String) ? JID.new(my_jid) : my_jid)
    34:         @peer_jid = (peer_jid.kind_of?(String) ? JID.new(peer_jid) : peer_jid)
    35:
    36:         @active = false
    37:         @seq_send = 0
    38:         @seq_recv = 0
    39:         @queue = []
    40:         @queue_lock = Mutex.new
    41:         @pending = Semaphore.new
    42:         @sendbuf = ''
    43:         @sendbuf_lock = Mutex.new
    44:
    45:         @block_size = 4096  # Recommended by JEP0047
    46:       end

### Public Instance methods

active?()

[Source]

        # File lib/xmpp4r/bytestreams/helper/ibb/base.rb, line 48
    48:       def active?
    49:         @active
    50:       end

close()

Close the stream

Waits for acknowledge from peer, may throw ServerError

[Source]

         # File lib/xmpp4r/bytestreams/helper/ibb/base.rb, line 128
    128:       def close
    129:         if active?
    130:           flush
    131:           deactivate
    132:
    133:           iq = Iq.new(:set, @peer_jid)
    134:           close = iq.add REXML::Element.new('close')
    135:           close.add_namespace IBB::NS_IBB
    136:           close.attributes['sid'] = @session_id
    137:
    138:           @stream.send_with_id(iq)
    139:         end
    140:       end

flush()

Empty the send-buffer by sending remaining data

[Source]

        # File lib/xmpp4r/bytestreams/helper/ibb/base.rb, line 72
    72:       def flush
    73:         @sendbuf_lock.synchronize {
    74:           while @sendbuf.size > 0
    75:             send_data(@sendbuf[0..@block_size-1])
    76:             @sendbuf = @sendbuf[@block_size..-1].to_s
    77:           end
    78:         }
    79:       end

read()

Receive data

Will wait until the Message with the next sequence number is in the stanza queue.

[Source]

         # File lib/xmpp4r/bytestreams/helper/ibb/base.rb, line 86
     86:       def read
     87:         if active?
     88:           res = nil
     89:
     90:           while res.nil?
     91:             @queue_lock.synchronize {
     92:               @queue.each { |item|
     93:                 # Find next data
     94:                 if item.type == :data and item.seq == @seq_recv.to_s
     95:                   res = item
     96:                   break
     97:                 # No data? Find close
     98:                 elsif item.type == :close and res.nil?
     99:                   res = item
    100:                 end
    101:               }
    102:
    103:               @queue.delete_if { |item| item == res }
    104:             }
    105:
    106:             # No data? Wait for next to arrive...
    107:             @pending.wait unless res
    108:           end
    109:
    110:           if res.type == :data
    111:             @seq_recv += 1
    112:             @seq_recv = 0 if @seq_recv > 65535
    113:             res.data
    114:           elsif res.type == :close
    115:             deactivate
    116:             nil # Closed
    117:           end
    118:         else
    119:           nil
    120:         end
    121:       end

write(buf)

Send data

Data is buffered to match block_size in each packet. If you need the data to be sent immediately, use flush afterwards.

buf: | [String]

[Source]

        # File lib/xmpp4r/bytestreams/helper/ibb/base.rb, line 59
    59:       def write(buf)
    60:         @sendbuf_lock.synchronize {
    61:           @sendbuf += buf
    62:
    63:           while @sendbuf.size >= @block_size
    64:             send_data(@sendbuf[0..@block_size-1])
    65:             @sendbuf = @sendbuf[@block_size..-1].to_s
    66:           end
    67:         }
    68:       end

[Validate]