org.jivesoftware.smack.XMPPConnection Maven / Gradle / Ivy
/**
*
* Copyright 2009 Jive Software.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smack;
import java.net.InetAddress;
import java.util.concurrent.TimeUnit;
import javax.xml.namespace.QName;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.OutgoingQueueFullException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.filter.IQReplyFilter;
import org.jivesoftware.smack.filter.StanzaFilter;
import org.jivesoftware.smack.iqrequest.IQRequestHandler;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.MessageBuilder;
import org.jivesoftware.smack.packet.Nonza;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.PresenceBuilder;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.StanzaFactory;
import org.jivesoftware.smack.packet.XmlElement;
import org.jivesoftware.smack.util.Consumer;
import org.jivesoftware.smack.util.Predicate;
import org.jivesoftware.smack.util.XmppElementUtil;
import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.EntityFullJid;
/**
* The XMPPConnection interface provides an interface for connections from a client to an XMPP server and
* implements shared methods which are used by the different types of connections (e.g.
* {@link org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection} or XMPPTCPConnection
). To create a connection to an XMPP server
* a simple usage of this API might look like the following:
*
* {@code
* // Create the configuration for this new connection
* XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
* configBuilder.setUsernameAndPassword("username", "password");
* configBuilder.setXmppDomain("jabber.org");
*
* AbstractXMPPConnection connection = new XMPPTCPConnection(configBuilder.build());
* connection.connect();
* connection.login();
*
* Message message = connection.getStanzaFactory().buildMessageStanza()
* .to("[email protected])
* .setBody("Hi, how are you?")
* .build();
* connection.sendStanza(message);
*
* connection.disconnect();
* }
*
* Note that the XMPPConnection interface does intentionally not declare any methods that manipulate
* the connection state, e.g. connect()
, disconnect()
. You should use the
* most-generic superclass connection type that is able to provide the methods you require. In most cases
* this should be {@link AbstractXMPPConnection}. And use or hand out instances of the
* XMPPConnection interface when you don't need to manipulate the connection state.
*
*
* XMPPConnections can be reused between connections. This means that an Connection may be connected,
* disconnected and then connected again. Listeners of the XMPPConnection will be retained across
* connections.
*
* Processing Incoming Stanzas
* Smack provides a flexible framework for processing incoming stanzas using two constructs:
*
* - {@link StanzaCollector}: lets you synchronously wait for new stanzas
* - {@link StanzaListener}: an interface for asynchronously notifying you of incoming stanzas
*
*
* Incoming Stanza Listeners
* Most callbacks (listeners, handlers, …) than you can add to a connection come in three different variants:
*
* - asynchronous - e.g., {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}
* - synchronous - e.g., {@link #addSyncStanzaListener(StanzaListener, StanzaFilter)}
* - other - e.g., {@link #addStanzaListener(StanzaListener, StanzaFilter)}
*
*
* Asynchronous callbacks are run decoupled from the connections main event loop. Hence, a callback triggered by
* stanza B may (appear to) invoked before a callback triggered by stanza A, even though stanza A arrived before B.
*
*
* Synchronous callbacks are invoked concurrently, but it is ensured that the same callback is never run concurrently
* and that they are executed in order. That is, if both stanza A and B trigger the same callback, and A arrives before
* B, then the callback will be invoked with A first, and then B. Furthermore, those callbacks are not executed within
* the main loop. However it is still advisable that those callbacks do not block or only block briefly.
*
*
* Other callbacks are run synchronous to the main event loop of a connection and are executed within the main loop.
* This means that if such a callback blocks, the main event loop also blocks, which can easily cause deadlocks.
* Therefore, you should avoid using those callbacks unless you know what you are doing.
*
* Stanza Filters
* Stanza filters allow you to define the predicates for which listeners or collectors should be invoked. For more
* information about stanza filters, see {@link org.jivesoftware.smack.filter}.
* Provider Architecture
* XMPP is an extensible protocol. Smack allows for this extensible with its provider architecture that allows to
* plug-in providers that are able to parse the various XML extension elements used for XMPP's extensibility. For
* more information see {@link org.jivesoftware.smack.provider}.
* Debugging
* See {@link org.jivesoftware.smack.debugger} for Smack's API to debug XMPP connections.
* Modular Connection Architecture
* Smack's new modular connection architecture will one day replace the monolithic architecture. Its main entry
* point {@link org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection} has more information.
*
* @author Matt Tucker
* @author Guenther Niess
* @author Florian Schmaus
*/
public interface XMPPConnection {
/**
* Returns the XMPP Domain of the service provided by the XMPP server and used for this connection. After
* authenticating with the server the returned value may be different.
*
* @return the XMPP domain of this XMPP session.
*/
DomainBareJid getXMPPServiceDomain();
/**
* Returns the host name of the server where the XMPP server is running. This would be the
* IP address of the server or a name that may be resolved by a DNS server.
*
* @return the host name of the server where the XMPP server is running or null if not yet connected.
*/
String getHost();
/**
* Returns the port number of the XMPP server for this connection. The default port
* for normal connections is 5222.
*
* @return the port number of the XMPP server or 0 if not yet connected.
*/
int getPort();
/**
* Returns the full XMPP address of the user that is logged in to the connection or
* null
if not logged in yet. An XMPP address is in the form
* username@server/resource.
*
* @return the full XMPP address of the user logged in.
*/
EntityFullJid getUser();
/**
* Returns the local address currently in use for this connection, or null
if
* this is invalid for the type of underlying connection.
*
* @return the local address currently in use for this connection
*/
InetAddress getLocalAddress();
/**
* Returns the stream ID for this connection, which is the value set by the server
* when opening an XMPP stream. This value will be null
if not connected to the server.
*
* @return the ID of this connection returned from the XMPP server or null
if
* not connected to the server.
* @see RFC 6120 § 4.7.3. id
*/
String getStreamId();
/**
* Returns true if currently connected to the XMPP server.
*
* @return true if connected.
*/
boolean isConnected();
/**
* Returns true if currently authenticated by successfully calling the login method.
*
* @return true if authenticated.
*/
boolean isAuthenticated();
/**
* Returns true if currently authenticated anonymously.
*
* @return true if authenticated anonymously.
*/
boolean isAnonymous();
/**
* Returns true if the connection to the server has successfully negotiated encryption.
*
* @return true if a secure connection to the server.
*/
boolean isSecureConnection();
/**
* Returns true if network traffic is being compressed. When using stream compression network
* traffic can be reduced up to 90%. Therefore, stream compression is ideal when using a slow
* speed network connection. However, the server will need to use more CPU time in order to
* un/compress network data so under high load the server performance might be affected.
*
* @return true if network traffic is being compressed.
*/
boolean isUsingCompression();
StanzaFactory getStanzaFactory();
/**
* Sends the specified stanza to the server.
*
* @param stanza the stanza to send.
* @throws NotConnectedException if the connection is not connected.
* @throws InterruptedException if the calling thread was interrupted.
* */
void sendStanza(Stanza stanza) throws NotConnectedException, InterruptedException;
void sendStanzaNonBlocking(Stanza stanza) throws NotConnectedException, OutgoingQueueFullException;
/**
* Try to send the given stanza. Returns {@code true} if the stanza was successfully put into the outgoing stanza
* queue, otherwise, if {@code false} is returned, the stanza could not be scheduled for sending (for example
* because the outgoing element queue is full). Note that this means that the stanza possibly was not put onto the
* wire, even if {@code true} is returned, it just has been successfully scheduled for sending.
*
* Note: Implementations are not required to provide that functionality. In that case this method is mapped
* to {@link #sendStanza(Stanza)} and will possibly block until the stanza could be scheduled for sending.
*
*
* @param stanza the stanza to send.
* @return {@code true} if the stanza was successfully scheduled to be sent, {@code false} otherwise.
* @throws NotConnectedException if the connection is not connected.
* @since 4.4.0
* @deprecated use {@link #sendStanzaNonBlocking(Stanza)} instead.
*/
// TODO: Remove in Smack 4.7.
@Deprecated
boolean trySendStanza(Stanza stanza) throws NotConnectedException;
/**
* Try to send the given stanza. Returns {@code true} if the stanza was successfully put into the outgoing stanza
* queue within the given timeout period, otherwise, if {@code false} is returned, the stanza could not be scheduled
* for sending (for example because the outgoing element queue is full). Note that this means that the stanza
* possibly was not put onto the wire, even if {@code true} is returned, it just has been successfully scheduled for
* sending.
*
* Note: Implementations are not required to provide that functionality. In that case this method is mapped
* to {@link #sendStanza(Stanza)} and will possibly block until the stanza could be scheduled for sending.
*
*
* @param stanza the stanza to send.
* @param timeout how long to wait before giving up, in units of {@code unit}.
* @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter.
* @return {@code true} if the stanza was successfully scheduled to be sent, {@code false} otherwise.
* @throws NotConnectedException if the connection is not connected.
* @throws InterruptedException if the calling thread was interrupted.
* @since 4.4.0
* @deprecated use {@link #sendStanzaNonBlocking(Stanza)} instead.
*/
// TODO: Remove in Smack 4.7.
@Deprecated
boolean trySendStanza(Stanza stanza, long timeout, TimeUnit unit) throws NotConnectedException, InterruptedException;
/**
* Send a Nonza.
*
* This method is not meant for end-user usage! It allows sending plain stream elements, which should not be
* done by a user manually. Doing so may result in a unstable or unusable connection. Certain Smack APIs use
* this method to send plain stream elements.
*
*
* @param nonza the Nonza to send.
* @throws NotConnectedException if the XMPP connection is not connected.
* @throws InterruptedException if the calling thread was interrupted.
*/
void sendNonza(Nonza nonza) throws NotConnectedException, InterruptedException;
void sendNonzaNonBlocking(Nonza stanza) throws NotConnectedException, OutgoingQueueFullException;
/**
* Adds a connection listener to this connection that will be notified when
* the connection closes or fails.
*
* @param connectionListener a connection listener.
*/
void addConnectionListener(ConnectionListener connectionListener);
/**
* Removes a connection listener from this connection.
*
* @param connectionListener a connection listener.
*/
void removeConnectionListener(ConnectionListener connectionListener);
/**
* Send an IQ request and wait for the response.
*
* @param request the IQ request
* @param the type of the expected result IQ.
* @return an IQ with type 'result'
* @throws NoResponseException if there was no response from the remote entity.
* @throws XMPPErrorException if there was an XMPP error returned.
* @throws NotConnectedException if the XMPP connection is not connected.
* @throws InterruptedException if the calling thread was interrupted.
* @since 4.3
*/
@SuppressWarnings("TypeParameterUnusedInFormals")
I sendIqRequestAndWaitForResponse(IQ request)
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException;
/**
* Creates a new stanza collector collecting IQ responses that are replies to the IQ request
.
* Does also send the request
IQ. The stanza filter for the collector is an
* {@link IQReplyFilter}, guaranteeing that stanza id and JID in the 'from' address have
* expected values.
*
* @param request the IQ request to filter responses from
* @return a new stanza collector.
* @throws NotConnectedException if the XMPP connection is not connected.
* @throws InterruptedException if the calling thread was interrupted.
*/
StanzaCollector createStanzaCollectorAndSend(IQ request) throws NotConnectedException, InterruptedException;
/**
* Creates a new stanza collector for this connection. A stanza filter determines
* which stanzas will be accumulated by the collector. A StanzaCollector is
* more suitable to use than a {@link StanzaListener} when you need to wait for
* a specific result.
*
* @param stanzaFilter the stanza filter to use.
* @param stanza the stanza to send right after the collector got created
* @return a new stanza collector.
* @throws InterruptedException if the calling thread was interrupted.
* @throws NotConnectedException if the XMPP connection is not connected.
*/
StanzaCollector createStanzaCollectorAndSend(StanzaFilter stanzaFilter, Stanza stanza)
throws NotConnectedException, InterruptedException;
/**
* Creates a new stanza collector for this connection. A stanza filter
* determines which stanzas will be accumulated by the collector. A
* StanzaCollector is more suitable to use than a {@link StanzaListener}
* when you need to wait for a specific result.
*
* Note: If you send a Stanza right after using this method, then
* consider using
* {@link #createStanzaCollectorAndSend(StanzaFilter, Stanza)} instead.
* Otherwise make sure cancel the StanzaCollector in every case, e.g. even
* if an exception is thrown, or otherwise you may leak the StanzaCollector.
*
*
* @param stanzaFilter the stanza filter to use.
* @return a new stanza collector.
*/
StanzaCollector createStanzaCollector(StanzaFilter stanzaFilter);
/**
* Create a new stanza collector with the given stanza collector configuration.
*
* Please make sure to cancel the collector when it is no longer required. See also
* {@link #createStanzaCollector(StanzaFilter)}.
*
*
* @param configuration the stanza collector configuration.
* @return a new stanza collector.
* @since 4.1
*/
StanzaCollector createStanzaCollector(StanzaCollector.Configuration configuration);
/**
* Remove a stanza collector of this connection.
*
* @param collector a stanza collectors which was created for this connection.
*/
void removeStanzaCollector(StanzaCollector collector);
/**
* Registers a stanza listener with this connection. The listener will be invoked when a (matching) incoming stanza
* is received. The stanza filter determines which stanzas will be delivered to the listener. It is guaranteed that
* the same listener will not be invoked concurrently and the order of invocation will reflect the order in
* which the stanzas have been received. If the same stanza listener is added again with a different filter, only
* the new filter will be used.
*
* @param stanzaListener the stanza listener to notify of new received stanzas.
* @param stanzaFilter the stanza filter to use.
* @since 4.4.0
*/
void addStanzaListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter);
/**
* Removes a stanza listener for received stanzas from this connection.
*
* @param stanzaListener the stanza listener to remove.
* @return true if the stanza listener was removed.
* @since 4.4.0
*/
boolean removeStanzaListener(StanzaListener stanzaListener);
/**
* Registers a synchronous stanza listener with this connection. A stanza listener will be invoked only when
* an incoming stanza is received. A stanza filter determines which stanzas will be delivered to the listener. If
* the same stanza listener is added again with a different filter, only the new filter will be used.
*
* Important: This stanza listeners will be called in the same single thread that processes all
* incoming stanzas. Only use this kind of stanza filter if it does not perform any XMPP activity that waits for a
* response. Consider using {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} when possible, i.e. when
* the invocation order doesn't have to be the same as the order of the arriving stanzas. If the order of the
* arriving stanzas, consider using a {@link StanzaCollector} when possible.
*
*
* @param stanzaListener the stanza listener to notify of new received stanzas.
* @param stanzaFilter the stanza filter to use.
* @since 4.1
*/
void addSyncStanzaListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter);
/**
* Removes a stanza listener for received stanzas from this connection.
*
* @param stanzaListener the stanza listener to remove.
* @return true if the stanza listener was removed
* @since 4.1
*/
boolean removeSyncStanzaListener(StanzaListener stanzaListener);
/**
* Registers an asynchronous stanza listener with this connection. A stanza listener will be invoked only
* when an incoming stanza is received. A stanza filter determines which stanzas will be delivered to the listener.
* If the same stanza listener is added again with a different filter, only the new filter will be used.
*
* Unlike {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} stanza listeners added with this method will be
* invoked asynchronously in their own thread. Use this method if the order of the stanza listeners must not depend
* on the order how the stanzas where received.
*
*
* @param stanzaListener the stanza listener to notify of new received stanzas.
* @param stanzaFilter the stanza filter to use.
* @since 4.1
*/
void addAsyncStanzaListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter);
/**
* Removes an asynchronous stanza listener for received stanzas from this connection.
*
* @param stanzaListener the stanza listener to remove.
* @return true if the stanza listener was removed
* @since 4.1
*/
boolean removeAsyncStanzaListener(StanzaListener stanzaListener);
/**
* Registers a stanza listener with this connection. The listener will be
* notified of every stanza that this connection sends. A stanza filter determines
* which stanzas will be delivered to the listener. Note that the thread
* that writes stanzas will be used to invoke the listeners. Therefore, each
* stanza listener should complete all operations quickly or use a different
* thread for processing.
*
* @param stanzaListener the stanza listener to notify of sent stanzas.
* @param stanzaFilter the stanza filter to use.
*/
void addStanzaSendingListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter);
/**
* Removes a stanza listener for sending stanzas from this connection.
*
* @param stanzaListener the stanza listener to remove.
*/
void removeStanzaSendingListener(StanzaListener stanzaListener);
/**
* Registers a stanza interceptor with this connection. The interceptor will be
* invoked every time a stanza is about to be sent by this connection. Interceptors
* may modify the stanza to be sent. A stanza filter determines which stanzas
* will be delivered to the interceptor.
*
*
* NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}.
*
*
* @param messageInterceptor the stanza interceptor to notify of stanzas about to be sent.
* @param messageFilter the stanza filter to use.
*/
void addMessageInterceptor(Consumer messageInterceptor, Predicate messageFilter);
/**
* Removes a message interceptor.
*
* @param messageInterceptor the message interceptor to remove.
*/
void removeMessageInterceptor(Consumer messageInterceptor);
/**
* Registers a stanza interceptor with this connection. The interceptor will be
* invoked every time a stanza is about to be sent by this connection. Interceptors
* may modify the stanza to be sent. A stanza filter determines which stanzas
* will be delivered to the interceptor.
*
*
* NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}.
*
*
* @param presenceInterceptor the stanza interceptor to notify of stanzas about to be sent.
* @param presenceFilter the stanza filter to use.
*/
void addPresenceInterceptor(Consumer presenceInterceptor, Predicate presenceFilter);
/**
* Removes a presence interceptor.
*
* @param presenceInterceptor the stanza interceptor to remove.
*/
void removePresenceInterceptor(Consumer presenceInterceptor);
/**
* Returns the current value of the reply timeout in milliseconds for request for this
* XMPPConnection instance.
*
* @return the reply timeout in milliseconds
*/
long getReplyTimeout();
/**
* Set the stanza reply timeout in milliseconds. In most cases, Smack will throw a
* {@link NoResponseException} if no reply to a request was received within the timeout period.
*
* @param timeout for a reply in milliseconds
*/
void setReplyTimeout(long timeout);
/**
* Get the connection counter of this XMPPConnection instance. Those can be used as ID to
* identify the connection, but beware that the ID may not be unique if you create more then
* 2*Integer.MAX_VALUE
instances as the counter could wrap.
*
* @return the connection counter of this XMPPConnection
*/
int getConnectionCounter();
enum FromMode {
/**
* Leave the 'from' attribute unchanged. This is the behavior of Smack < 4.0
*/
UNCHANGED,
/**
* Omit the 'from' attribute. According to RFC 6120 8.1.2.1 1. XMPP servers "MUST (...)
* override the 'from' attribute specified by the client". It is therefore safe to specify
* FromMode.OMITTED here.
*/
OMITTED,
/**
* Set the from to the clients full JID. This is usually not required.
*/
USER
}
/**
* Set the FromMode for this connection instance. Defines how the 'from' attribute of outgoing
* stanzas should be populated by Smack.
*
* @param fromMode TODO javadoc me please
*/
void setFromMode(FromMode fromMode);
/**
* Get the currently active FromMode.
*
* @return the currently active {@link FromMode}
*/
FromMode getFromMode();
/**
* Get the feature stanza extensions for a given stream feature of the
* server, or null
if the server doesn't support that feature.
*
* @param {@link ExtensionElement} type of the feature.
* @param qname the qualified name of the XML element of feature.
* @return a stanza extensions of the feature or null
* @since 4.4
*/
@SuppressWarnings("TypeParameterUnusedInFormals")
F getFeature(QName qname);
/**
* Get the feature stanza extensions for a given stream feature of the
* server, or null
if the server doesn't support that feature.
*
* @param {@link ExtensionElement} type of the feature.
* @param featureClass the class of the feature.
* @return a stanza extensions of the feature or null
* @since 4.4
*/
default F getFeature(Class featureClass) {
QName qname = XmppElementUtil.getQNameFor(featureClass);
return getFeature(qname);
}
/**
* Return true if the server supports the given stream feature.
*
* @param element TODO javadoc me please
* @param namespace TODO javadoc me please
* @return true if the server supports the stream feature.
*/
default boolean hasFeature(String element, String namespace) {
QName qname = new QName(namespace, element);
return hasFeature(qname);
}
/**
* Return true if the server supports the given stream feature.
*
* @param qname the qualified name of the XML element of feature.
* @return true if the server supports the stream feature.
*/
boolean hasFeature(QName qname);
/**
* Send an IQ request asynchronously. The connection's default reply timeout will be used.
*
* @param request the IQ request to send.
* @return a SmackFuture for the response.
*/
SmackFuture sendIqRequestAsync(IQ request);
/**
* Send an IQ request asynchronously.
*
* @param request the IQ request to send.
* @param timeout the reply timeout in milliseconds.
* @return a SmackFuture for the response.
*/
SmackFuture sendIqRequestAsync(IQ request, long timeout);
/**
* Send a stanza asynchronously, waiting for exactly one response stanza using the given reply filter. The
* connection's default reply timeout will be used.
*
* @param stanza the stanza to send.
* @param replyFilter the filter used for the response stanza.
* @param the type of the stanza to send.
* @return a SmackFuture for the response.
*/
SmackFuture sendAsync(S stanza, StanzaFilter replyFilter);
/**
* Send a stanza asynchronously, waiting for exactly one response stanza using the given reply filter.
*
* @param stanza the stanza to send.
* @param replyFilter the filter used for the response stanza.
* @param timeout the reply timeout in milliseconds.
* @param the type of the stanza to send.
* @return a SmackFuture for the response.
*/
SmackFuture sendAsync(S stanza, StanzaFilter replyFilter, long timeout);
/**
* Add a callback that is called exactly once and synchronously with the incoming stanza that matches the given
* stanza filter.
*
* @param callback the callback invoked once the stanza filter matches a stanza.
* @param stanzaFilter the filter to match stanzas or null to match all.
*/
void addOneTimeSyncCallback(StanzaListener callback, StanzaFilter stanzaFilter);
/**
* Register an IQ request handler with this connection.
*
* IQ request handler process incoming IQ requests, i.e. incoming IQ stanzas of type 'get' or 'set', and return a result.
*
* @param iqRequestHandler the IQ request handler to register.
* @return the previously registered IQ request handler or null.
*/
IQRequestHandler registerIQRequestHandler(IQRequestHandler iqRequestHandler);
/**
* Convenience method for {@link #unregisterIQRequestHandler(String, String, org.jivesoftware.smack.packet.IQ.Type)}.
*
* @param iqRequestHandler TODO javadoc me please
* @return the previously registered IQ request handler or null.
*/
IQRequestHandler unregisterIQRequestHandler(IQRequestHandler iqRequestHandler);
/**
* Unregister an IQ request handler with this connection.
*
* @param element the IQ element the IQ request handler is responsible for.
* @param namespace the IQ namespace the IQ request handler is responsible for.
* @param type the IQ type the IQ request handler is responsible for.
* @return the previously registered IQ request handler or null.
*/
IQRequestHandler unregisterIQRequestHandler(String element, String namespace, IQ.Type type);
/**
* Returns the timestamp in milliseconds when the last stanza was received.
*
* @return the timestamp in milliseconds
*/
long getLastStanzaReceived();
}