InBandBytestreamManager Class Reference

An InBandBytestreamManager dispatches In-Band Bytestreams. More...

#include <inbandbytestreammanager.h>

Inherits IqHandler.

Inheritance diagram for InBandBytestreamManager:

Inheritance graph
[legend]
Collaboration diagram for InBandBytestreamManager:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 InBandBytestreamManager (ClientBase *parent, Disco *disco)
virtual ~InBandBytestreamManager ()
bool requestInBandBytestream (const JID &to, InBandBytestreamHandler *ibbh)
void setBlockSize (int blockSize)
int blockSize () const
bool dispose (InBandBytestream *ibb)
void acceptInBandBytestream (InBandBytestream *ibb)
void rejectInBandBytestream (InBandBytestream *ibb)
void registerInBandBytestreamHandler (InBandBytestreamHandler *ibbh, bool sync=true)
void removeInBandBytestreamHandler ()
virtual bool handleIq (Stanza *stanza)
virtual bool handleIqID (Stanza *stanza, int context)

Detailed Description

An InBandBytestreamManager dispatches In-Band Bytestreams.

Initiating a bytestream

To initiate a new bytestream, you need an InBandBytestreamManager object. You will also need an InBandBytestreamHandler-derived object which will receive incoming and outgoing bytestreams (not the data but the InBandBytestream objects).
 class MyClass : public InBandBytestreamHandler
 {
   ...
   private:
     InBandBytestreamManager *m_ibbManager;
   ...
 };

Create a new InBandBytestreamManager and request a new bytestream:

 MyClass::MyClass()
 {
   m_ibbManager = new InBandBytestreamManager( m_client, m_client->disco() );
 }

 void MyClass::myFunc()
 {
   JID jid( "entity@server/resource" );
   m_ibbManager->requestInBandBytestream( jid, this );
 }

After the bytestream has been negotiated with the peer, InBandBytestreamHandler::handleOutgoingInBandBytestream() is called. Here you should attach the bytestream to a MessageSession associated with the remote entity. This is necessary since message stanzas are used for the actual data exchange and the MessageSession class offers a convenient interface to filter these out. In this example, there is a map of JID/MessageSession pairs and a map of JID/InBandBytestreams.

 void MyClass::handleOutgoingInBandBytestream( const JID& to, InBandBytestream *ibb )
 {
   MessageSessionList::iterator it = m_messageSessions.find( to.full() );
   if( it != m_messageSessions.end() )
   {
     ibb->attachTo( (*it).second );
   }
   else
   {
     MessageSession *session = new MessageSession( m_client, to );
     ibb->attachTo( session );
     m_messageSessions[to.full()] = session;
   }

   m_ibbs[to.full()] = ibb;
 }
If you want to receive data from the bytestream (In-Band Bytestreams can be bi-directional), you have to register a InBandBytestreamDataHandler here, similar to the folowing example.

When sending data you should make sure you never try to send a block larger than the negotiated blocksize (which defaults to 4096 bytes). If a block is larger than this it will not be sent.

Receiving a bytestream

To receive a bytestream you need a InBandBytestreamManager, too, and you have to register an InBandBytestreamHandler which will receive the incoming bytestreams.
   m_ibbManager->registerInBandBytestreamHandler( this );

Upon an incoming request the InBandBytestreamManager notifies the registered InBandBytestreamHandler by calling handleIncomingInBandBytestream() . The return value of the handler determines whether the stream shall be accepted or not.

 bool MyClass::handleIncomingInBandBytestream( const JID& from, InBandBytestream *ibb )
 {
   // Check whether you want to accept the bytestream

   // add an InBandBytestreamDataHandler
   ibb->registerInBandBytestreamDataHandler( this );

   // The rest of this function probaly looks similar to the implementation of
   // handleOutgoingInBandBytestream() above.
   // You should *not* start to send blocks of data from within this
   // function, though.

   // return true to accept the bytestream, false to reject it
   return true;
 }

Sending data

To actually send data, you should utilise some kind of mainloop integration that allows to call a function periodically. It is important to remember the following: The following is an example of a primitive mainloop integration:
 void MyClass::mainloop()
 {
   if( m_client->connect(false) )
   {
     ConnectionError ce = ConnNoError;
     while( ce == ConnNoError )
     {
       ce = m_client->recv();
       sendIBBData();
     }
     printf( "disconnected. reason: %d\n", ce );
   }
 }

In sendIBBData() you would then iterate over your bytestreams and send a block of data where appropriate.

 void MyClass::sendIBBData()
 {
   IBBList::iterator it = m_ibbs.begin();
   for( ; it != m_ibbs.end(); ++it )
   {
     (*it).second->sendBlock( "some data" );
   }
 }

Getting rid of bytestreams

When you're done with a bytestream you can get rid of it by calling the dispose() function. The bytestream will be recycled and you should no longer use it.
   m_ibbManager->dispose( ibb );
   ibb = 0;

Note:
You should have only one InBandBytestreamManager per Client/ClientBase lying around. One is enough for receiving and initiating bytestreams.

In the excerpts above, only one bytestream per remote entity is possible (without leaking). However, gloox in general does not impose such a limitation, nor does the In-Band Bytestreams specification.

Author:
Jakob Schroeter <js@camaya.net>
Since:
0.8

Definition at line 177 of file inbandbytestreammanager.h.


Constructor & Destructor Documentation

InBandBytestreamManager ( ClientBase parent,
Disco disco 
)

Constructs a new InBandBytestreamManager.

Parameters:
parent The ClientBase to use for sending data.
disco The Disco object to announce the IBB feature with.

Definition at line 22 of file inbandbytestreammanager.cpp.

~InBandBytestreamManager (  )  [virtual]

Virtual destructor.

Definition at line 33 of file inbandbytestreammanager.cpp.


Member Function Documentation

bool requestInBandBytestream ( const JID to,
InBandBytestreamHandler ibbh 
)

This function initiates opening of a bytestream with the MessageSession's remote entity. Data can only be sent over an open stream. Use isOpen() to find out what the stream's current state is. However, successful opening/initiation will be announced by means of the InBandBytestreamHandler interface. Multiple bytestreams (even per JID) can be initiated without waiting for success.

Parameters:
to The recipient of the requested bytestream.
ibbh The InBandBytestreamHandler to send the new bytestream to.
Returns:
False in case of an error, true otherwise. A return value of true does not indicate that the bytestream has been opened. This is announced by means of the InBandBytestreamHandler.

Definition at line 46 of file inbandbytestreammanager.cpp.

void setBlockSize ( int  blockSize  )  [inline]

Sets the default block-size. Default: 4096

Parameters:
blockSize The default block-size in byte.

Definition at line 210 of file inbandbytestreammanager.h.

int blockSize (  )  const [inline]

Returns the currently set block-size.

Returns:
The currently set block-size.

Definition at line 216 of file inbandbytestreammanager.h.

bool dispose ( InBandBytestream ibb  ) 

To get rid of a bytestream (i.e., close and delete it), call this function. You should not use the bytestream any more. The remote entity will be notified about the closing of the stream.

Parameters:
ibb The bytestream to dispose. It will be deleted here.

Definition at line 220 of file inbandbytestreammanager.cpp.

void acceptInBandBytestream ( InBandBytestream ibb  ) 

When using asynchronous InBandBytestream notifications (if you used registerInBandBytestreamHandler() with a second argument of true) you have to call either this function or rejectInBandBytestream() after receiving an InBandBytestream from the InBandBytestreamHandler. Else the initiator will never know whether the request was actually received.

Parameters:
ibb The InBandBytestream (as received from InBandBytestreamHandler) to accept.
Since:
0.8.1

Definition at line 129 of file inbandbytestreammanager.cpp.

Referenced by InBandBytestreamManager::handleIq().

void rejectInBandBytestream ( InBandBytestream ibb  ) 

When using asynchronous InBandBytestream notifications (if you used registerInBandBytestreamHandler() with a second argument of true) you have to call either this function or acceptInBandBytestream() after receiving an InBandBytestream from the InBandBytestreamHandler. Else the initiator will never know whether the request was actually received.

Parameters:
ibb The InBandBytestream (as received from InBandBytestreamHandler) to reject.
Since:
0.8.1

Definition at line 142 of file inbandbytestreammanager.cpp.

Referenced by InBandBytestreamManager::handleIq().

void registerInBandBytestreamHandler ( InBandBytestreamHandler ibbh,
bool  sync = true 
)

Use this function to register an object that will receive new incoming bytestream requests from the InBandBytestreamManager. Only one InBandBytestreamHandler can be registered at any one time.

Parameters:
ibbh The InBandBytestreamHandler derived object to receive notifications.
sync Whether incoming bytestrams shall be announced syncronously. Default: true (syncronous)

Definition at line 233 of file inbandbytestreammanager.cpp.

void removeInBandBytestreamHandler (  ) 

Removes the registered InBandBytestreamHandler.

Definition at line 240 of file inbandbytestreammanager.cpp.

bool handleIq ( Stanza stanza  )  [virtual]

Reimplement this function if you want to be notified about incoming IQs.

Parameters:
stanza The complete Stanza.
Returns:
Indicates whether a request of type 'get' or 'set' has been handled. This includes the obligatory 'result' answer. If you return false, a 'error' will be sent.

Implements IqHandler.

Definition at line 72 of file inbandbytestreammanager.cpp.

bool handleIqID ( Stanza stanza,
int  context 
) [virtual]

Reimplement this function if you want to be notified about incoming IQs with a specific value of the id attribute. You have to enable tracking of those IDs using Client::trackID(). This is usually useful for IDs that generate a positive reply, i.e. <iq type='result' id='reg'/> where a namespace filter wouldn't work.

Parameters:
stanza The complete Stanza.
context A value to restore context, stored with ClientBase::trackID().
Returns:
Indicates whether a request of type 'get' or 'set' has been handled. This includes the obligatory 'result' answer. If you return false, a 'error' will be sent.

Implements IqHandler.

Definition at line 182 of file inbandbytestreammanager.cpp.


The documentation for this class was generated from the following files:
Generated on Tue May 1 14:20:24 2007 for gloox by  doxygen 1.5.1