/** * * 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 org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NotConnectedException; 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.Nonza; import org.jivesoftware.smack.packet.Stanza; import org.jxmpp.jid.DomainBareJid; import org.jxmpp.jid.EntityFullJid; /** * The XMPPConnection interface provides an interface for connections to an XMPP server and * implements shared methods which are used by the different types of connections (e.g. * XMPPTCPConnection or XMPPBOSHConnection). To create a connection to an XMPP server * a simple usage of this API might look like the following: *

* *

 * // Create a connection to the igniterealtime.org XMPP server.
 * XMPPTCPConnection con = new XMPPTCPConnection("igniterealtime.org");
 * // Connect to the server
 * con.connect();
 * // Most servers require you to login before performing other tasks.
 * con.login("jsmith", "mypass");
 * // Start a new conversation with John Doe and send him a message.
 * Chat chat = ChatManager.getInstanceFor(con).createChat("jdoe@igniterealtime.org", new MessageListener() {
 *     public void processMessage(Chat chat, Message message) {
 *         // Print out any messages we get back to standard out.
 *         System.out.println("Received message: " + message);
 *     }
 * });
 * chat.sendMessage("Howdy!");
 * // Disconnect from the server
 * con.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 specific connection type, e.g. XMPPTCPConnection as declared type and use 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. *

* * @author Matt Tucker * @author Guenther Niess */ public interface XMPPConnection { /** * Returns the name of the service provided by the XMPP server for this connection. * This is also called XMPP domain of the connected server. After * authenticating with the server the returned value may be different. * * @return the name of the service provided by the XMPP server. // TODO remove this once the java bugs are fixed, causing a warning // * @deprecated use {@link #getXMPPServiceDomain()} instead. */ // @Deprecated public DomainBareJid getServiceName(); /** * 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. */ public 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. */ public 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. */ public 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. */ public EntityFullJid getUser(); /** * 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 */ public String getStreamId(); /** * Returns true if currently connected to the XMPP server. * * @return true if connected. */ public boolean isConnected(); /** * Returns true if currently authenticated by successfully calling the login method. * * @return true if authenticated. */ public boolean isAuthenticated(); /** * Returns true if currently authenticated anonymously. * * @return true if authenticated anonymously. */ public boolean isAnonymous(); /** * Returns true if the connection to the server has successfully negotiated encryption. * * @return true if a secure connection to the server. */ public 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. */ public boolean isUsingCompression(); /** * Sends the specified stanza(/packet) to the server. * * @param packet the stanza(/packet) to send. * @throws NotConnectedException * @throws InterruptedException * @deprecated use {@link #sendStanza(Stanza)} instead. */ @Deprecated public void sendPacket(Stanza packet) throws NotConnectedException, InterruptedException; /** * Sends the specified stanza to the server. * * @param stanza the stanza to send. * @throws NotConnectedException if the connection is not connected. * @throws InterruptedException * */ public void sendStanza(Stanza stanza) 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 * @throws InterruptedException */ public void sendNonza(Nonza nonza) throws NotConnectedException, InterruptedException; /** * Adds a connection listener to this connection that will be notified when * the connection closes or fails. * * @param connectionListener a connection listener. */ public void addConnectionListener(ConnectionListener connectionListener); /** * Removes a connection listener from this connection. * * @param connectionListener a connection listener. */ public void removeConnectionListener(ConnectionListener connectionListener); /** * Creates a new stanza(/packet) collector collecting packets that are replies to packet. * Does also send packet. The stanza(/packet) filter for the collector is an * {@link IQReplyFilter}, guaranteeing that stanza(/packet) id and JID in the 'from' address have * expected values. * * @param packet the stanza(/packet) to filter responses from * @return a new stanza(/packet) collector. * @throws NotConnectedException * @throws InterruptedException */ public StanzaCollector createStanzaCollectorAndSend(IQ packet) throws NotConnectedException, InterruptedException; /** * Creates a new stanza(/packet) collector for this connection. A stanza(/packet) filter determines * which packets 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 packetFilter the stanza(/packet) filter to use. * @param packet the packet to send right after the collector got created * @return a new stanza(/packet) collector. * @throws InterruptedException * @throws NotConnectedException */ public StanzaCollector createStanzaCollectorAndSend(StanzaFilter packetFilter, Stanza packet) throws NotConnectedException, InterruptedException; /** * Creates a new stanza(/packet) collector for this connection. A stanza(/packet) filter * determines which packets 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(/Packet) 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 packetFilter the stanza(/packet) filter to use. * @return a new stanza(/packet) collector. */ public StanzaCollector createStanzaCollector(StanzaFilter packetFilter); /** * Create a new stanza(/packet) collector with the given stanza(/packet) collector configuration. *

* Please make sure to cancel the collector when it is no longer required. See also * {@link #createStanzaCollector(StanzaFilter)}. *

* * @param configuration the stanza(/packet) collector configuration. * @return a new stanza(/packet) collector. * @since 4.1 */ public StanzaCollector createStanzaCollector(StanzaCollector.Configuration configuration); /** * Remove a stanza(/packet) collector of this connection. * * @param collector a stanza(/packet) collectors which was created for this connection. */ public void removeStanzaCollector(StanzaCollector collector); /** * Registers a stanza(/packet) listener with this connection. *

* This method has been deprecated. It is important to differentiate between using an asynchronous stanza(/packet) listener * (preferred where possible) and a synchronous stanza(/packet) lister. Refer * {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} and * {@link #addSyncStanzaListener(StanzaListener, StanzaFilter)} for more information. *

* * @param packetListener the stanza(/packet) listener to notify of new received packets. * @param packetFilter the stanza(/packet) filter to use. * @deprecated use {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} or * {@link #addSyncStanzaListener(StanzaListener, StanzaFilter)}. */ @Deprecated public void addPacketListener(StanzaListener packetListener, StanzaFilter packetFilter); /** * Removes a stanza(/packet) listener for received packets from this connection. * * @param packetListener the stanza(/packet) listener to remove. * @return true if the stanza(/packet) listener was removed * @deprecated use {@link #removeAsyncStanzaListener(StanzaListener)} or {@link #removeSyncStanzaListener(StanzaListener)}. */ @Deprecated public boolean removePacketListener(StanzaListener packetListener); /** * Registers a synchronous stanza(/packet) listener with this connection. A stanza(/packet) listener will be invoked only when * an incoming stanza(/packet) is received. A stanza(/packet) filter determines which packets will be delivered to the listener. If * the same stanza(/packet) listener is added again with a different filter, only the new filter will be used. *

* Important: This stanza(/packet) listeners will be called in the same single thread that processes all * incoming stanzas. Only use this kind of stanza(/packet) 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 packets. If the order of the * arriving packets, consider using a {@link StanzaCollector} when possible. *

* * @param packetListener the stanza(/packet) listener to notify of new received packets. * @param packetFilter the stanza(/packet) filter to use. * @see #addPacketInterceptor(StanzaListener, StanzaFilter) * @since 4.1 */ public void addSyncStanzaListener(StanzaListener packetListener, StanzaFilter packetFilter); /** * Removes a stanza(/packet) listener for received packets from this connection. * * @param packetListener the stanza(/packet) listener to remove. * @return true if the stanza(/packet) listener was removed * @since 4.1 */ public boolean removeSyncStanzaListener(StanzaListener packetListener); /** * Registers an asynchronous stanza(/packet) listener with this connection. A stanza(/packet) listener will be invoked only * when an incoming stanza(/packet) is received. A stanza(/packet) filter determines which packets will be delivered to the listener. * If the same stanza(/packet) listener is added again with a different filter, only the new filter will be used. *

* Unlike {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} stanza(/packet) listeners added with this method will be * invoked asynchronously in their own thread. Use this method if the order of the stanza(/packet) listeners must not depend * on the order how the stanzas where received. *

* * @param packetListener the stanza(/packet) listener to notify of new received packets. * @param packetFilter the stanza(/packet) filter to use. * @see #addPacketInterceptor(StanzaListener, StanzaFilter) * @since 4.1 */ public void addAsyncStanzaListener(StanzaListener packetListener, StanzaFilter packetFilter); /** * Removes an asynchronous stanza(/packet) listener for received packets from this connection. * * @param packetListener the stanza(/packet) listener to remove. * @return true if the stanza(/packet) listener was removed * @since 4.1 */ public boolean removeAsyncStanzaListener(StanzaListener packetListener); /** * Registers a stanza(/packet) listener with this connection. The listener will be * notified of every stanza(/packet) that this connection sends. A stanza(/packet) filter determines * which packets will be delivered to the listener. Note that the thread * that writes packets will be used to invoke the listeners. Therefore, each * stanza(/packet) listener should complete all operations quickly or use a different * thread for processing. * * @param packetListener the stanza(/packet) listener to notify of sent packets. * @param packetFilter the stanza(/packet) filter to use. */ public void addPacketSendingListener(StanzaListener packetListener, StanzaFilter packetFilter); /** * Removes a stanza(/packet) listener for sending packets from this connection. * * @param packetListener the stanza(/packet) listener to remove. */ public void removePacketSendingListener(StanzaListener packetListener); /** * Registers a stanza(/packet) interceptor with this connection. The interceptor will be * invoked every time a stanza(/packet) is about to be sent by this connection. Interceptors * may modify the stanza(/packet) to be sent. A stanza(/packet) filter determines which packets * will be delivered to the interceptor. * *

* NOTE: For a similar functionality on incoming packets, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}. * * @param packetInterceptor the stanza(/packet) interceptor to notify of packets about to be sent. * @param packetFilter the stanza(/packet) filter to use. */ public void addPacketInterceptor(StanzaListener packetInterceptor, StanzaFilter packetFilter); /** * Removes a stanza(/packet) interceptor. * * @param packetInterceptor the stanza(/packet) interceptor to remove. */ public void removePacketInterceptor(StanzaListener packetInterceptor); /** * Returns the current value of the reply timeout in milliseconds for request for this * XMPPConnection instance. * * @return the stanza(/packet) reply timeout in milliseconds * @deprecated use {@link #getReplyTimeout()} instead. */ @Deprecated // TODO Remove in Smack 4.3 public long getPacketReplyTimeout(); /** * Set the stanza(/packet) 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 the stanza(/packet) reply timeout in milliseconds * @deprecated use {@link #setReplyTimeout(long)} instead. */ @Deprecated // TODO Remove in Smack 4.3 public void setPacketReplyTimeout(long timeout); /** * Returns the current value of the reply timeout in milliseconds for request for this * XMPPConnection instance. * * @return the reply timeout in milliseconds */ public long getReplyTimeout(); /** * Set the stanza(/packet) 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 */ public 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 */ public int getConnectionCounter(); public static 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 */ public void setFromMode(FromMode fromMode); /** * Get the currently active FromMode. * * @return the currently active {@link FromMode} */ public FromMode getFromMode(); /** * Get the feature stanza(/packet) extensions for a given stream feature of the * server, or null if the server doesn't support that feature. * * @param element * @param namespace * @return a stanza(/packet) extensions of the feature or null */ public F getFeature(String element, String namespace); /** * Return true if the server supports the given stream feature. * * @param element * @param namespace * @return true if the server supports the stream feature. */ public boolean hasFeature(String element, String namespace); /** * Send a stanza and wait asynchronously for a response by using replyFilter. *

* If there is a response, then callback will be invoked. The callback will be * invoked at most once and it will be not invoked after the connections default reply timeout * has been elapsed. *

* * @param stanza the stanza to send (required) * @param replyFilter the filter used to determine response stanza (required) * @param callback the callback invoked if there is a response (required) * @throws NotConnectedException * @throws InterruptedException */ public void sendStanzaWithResponseCallback(Stanza stanza, StanzaFilter replyFilter, StanzaListener callback) throws NotConnectedException, InterruptedException; /** * Send a stanza and wait asynchronously for a response by using replyFilter. *

* If there is a response, then callback will be invoked. If there is no response * after the connections default reply timeout, then exceptionCallback will be invoked * with a {@link SmackException.NoResponseException}. The callback will be invoked at most once. *

* * @param stanza the stanza to send (required) * @param replyFilter the filter used to determine response stanza (required) * @param callback the callback invoked if there is a response (required) * @param exceptionCallback the callback invoked if there is an exception (optional) * @throws NotConnectedException * @throws InterruptedException */ public void sendStanzaWithResponseCallback(Stanza stanza, StanzaFilter replyFilter, StanzaListener callback, ExceptionCallback exceptionCallback) throws NotConnectedException, InterruptedException; /** * Send a stanza and wait asynchronously for a response by using replyFilter. *

* If there is a response, then callback will be invoked. If there is no response * after timeout milliseconds, then exceptionCallback will be invoked * with a {@link SmackException.NoResponseException}. The callback will be invoked at most once. *

* * @param stanza the stanza to send (required) * @param replyFilter the filter used to determine response stanza (required) * @param callback the callback invoked if there is a response (required) * @param exceptionCallback the callback invoked if there is an exception (optional) * @param timeout the timeout in milliseconds to wait for a response * @throws NotConnectedException * @throws InterruptedException */ public void sendStanzaWithResponseCallback(Stanza stanza, StanzaFilter replyFilter, final StanzaListener callback, final ExceptionCallback exceptionCallback, long timeout) throws NotConnectedException, InterruptedException; /** * Send a IQ stanza and invoke callback if there is a result of * {@link org.jivesoftware.smack.packet.IQ.Type#result} with that result IQ. The callback will * not be invoked after the connections default reply timeout has been elapsed. * * @param iqRequest the IQ stanza to send (required) * @param callback the callback invoked if there is result response (required) * @throws NotConnectedException * @throws InterruptedException */ public void sendIqWithResponseCallback(IQ iqRequest, StanzaListener callback) throws NotConnectedException, InterruptedException; /** * Send a IQ stanza and invoke callback if there is a result of * {@link org.jivesoftware.smack.packet.IQ.Type#result} with that result IQ. If there is an * error response exceptionCallback will be invoked, if not null, with the received * error as {@link XMPPException.XMPPErrorException}. If there is no response after the * connections default reply timeout, then exceptionCallback will be invoked with a * {@link SmackException.NoResponseException}. * * @param iqRequest the IQ stanza to send (required) * @param callback the callback invoked if there is result response (required) * @param exceptionCallback the callback invoked if there is an Exception optional * @throws NotConnectedException * @throws InterruptedException */ public void sendIqWithResponseCallback(IQ iqRequest, StanzaListener callback, ExceptionCallback exceptionCallback) throws NotConnectedException, InterruptedException; /** * Send a IQ stanza and invoke callback if there is a result of * {@link org.jivesoftware.smack.packet.IQ.Type#result} with that result IQ. If there is an * error response exceptionCallback will be invoked, if not null, with the received * error as {@link XMPPException.XMPPErrorException}. If there is no response after * timeout, then exceptionCallback will be invoked with a * {@link SmackException.NoResponseException}. * * @param iqRequest the IQ stanza to send (required) * @param callback the callback invoked if there is result response (required) * @param exceptionCallback the callback invoked if there is an Exception optional * @param timeout the timeout in milliseconds to wait for a response * @throws NotConnectedException * @throws InterruptedException */ public void sendIqWithResponseCallback(IQ iqRequest, final StanzaListener callback, final ExceptionCallback exceptionCallback, long timeout) throws NotConnectedException, InterruptedException; /** * Add a callback that is called exactly once and synchronously with the incoming stanza that matches the given * stanza(/packet) filter. * * @param callback the callback invoked once the stanza(/packet) filter matches a stanza. * @param packetFilter the filter to match stanzas or null to match all. */ public void addOneTimeSyncCallback(StanzaListener callback, StanzaFilter packetFilter); /** * 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. */ public IQRequestHandler registerIQRequestHandler(IQRequestHandler iqRequestHandler); /** * Convenience method for {@link #unregisterIQRequestHandler(String, String, org.jivesoftware.smack.packet.IQ.Type)}. * * @param iqRequestHandler * @return the previously registered IQ request handler or null. */ public 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. */ public 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 */ public long getLastStanzaReceived(); }