001/** 002 * 003 * Copyright 2009 Jive Software. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smack; 018 019import java.net.InetAddress; 020import java.util.concurrent.TimeUnit; 021 022import javax.xml.namespace.QName; 023 024import org.jivesoftware.smack.SmackException.NoResponseException; 025import org.jivesoftware.smack.SmackException.NotConnectedException; 026import org.jivesoftware.smack.SmackException.OutgoingQueueFullException; 027import org.jivesoftware.smack.XMPPException.XMPPErrorException; 028import org.jivesoftware.smack.filter.IQReplyFilter; 029import org.jivesoftware.smack.filter.StanzaFilter; 030import org.jivesoftware.smack.iqrequest.IQRequestHandler; 031import org.jivesoftware.smack.packet.ExtensionElement; 032import org.jivesoftware.smack.packet.IQ; 033import org.jivesoftware.smack.packet.Message; 034import org.jivesoftware.smack.packet.MessageBuilder; 035import org.jivesoftware.smack.packet.Nonza; 036import org.jivesoftware.smack.packet.Presence; 037import org.jivesoftware.smack.packet.PresenceBuilder; 038import org.jivesoftware.smack.packet.Stanza; 039import org.jivesoftware.smack.packet.StanzaFactory; 040import org.jivesoftware.smack.packet.XmlElement; 041import org.jivesoftware.smack.util.Consumer; 042import org.jivesoftware.smack.util.Predicate; 043import org.jivesoftware.smack.util.XmppElementUtil; 044 045import org.jxmpp.jid.DomainBareJid; 046import org.jxmpp.jid.EntityFullJid; 047 048/** 049 * The XMPPConnection interface provides an interface for connections from a client to an XMPP server and 050 * implements shared methods which are used by the different types of connections (e.g. 051 * {@link org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection} or <code>XMPPTCPConnection</code>). To create a connection to an XMPP server 052 * a simple usage of this API might look like the following: 053 * 054 * <pre>{@code 055 * // Create the configuration for this new connection 056 * XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder(); 057 * configBuilder.setUsernameAndPassword("username", "password"); 058 * configBuilder.setXmppDomain("jabber.org"); 059 * 060 * AbstractXMPPConnection connection = new XMPPTCPConnection(configBuilder.build()); 061 * connection.connect(); 062 * connection.login(); 063 * 064 * Message message = connection.getStanzaFactory().buildMessageStanza() 065 * .to("mark@example.org) 066 * .setBody("Hi, how are you?") 067 * .build(); 068 * connection.sendStanza(message); 069 * 070 * connection.disconnect(); 071 * }</pre> 072 * <p> 073 * Note that the XMPPConnection interface does intentionally not declare any methods that manipulate 074 * the connection state, e.g. <code>connect()</code>, <code>disconnect()</code>. You should use the 075 * most-generic superclass connection type that is able to provide the methods you require. In most cases 076 * this should be {@link AbstractXMPPConnection}. And use or hand out instances of the 077 * XMPPConnection interface when you don't need to manipulate the connection state. 078 * </p> 079 * <p> 080 * XMPPConnections can be reused between connections. This means that an Connection may be connected, 081 * disconnected and then connected again. Listeners of the XMPPConnection will be retained across 082 * connections. 083 * </p> 084 * <h2>Processing Incoming Stanzas</h2> 085 * Smack provides a flexible framework for processing incoming stanzas using two constructs: 086 * <ul> 087 * <li>{@link StanzaCollector}: lets you synchronously wait for new stanzas</li> 088 * <li>{@link StanzaListener}: an interface for asynchronously notifying you of incoming stanzas</li> 089 * </ul> 090 * 091 * <h2>Incoming Stanza Listeners</h2> 092 * Most callbacks (listeners, handlers, …) than you can add to a connection come in three different variants: 093 * <ul> 094 * <li>asynchronous - e.g., {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}</li> 095 * <li>synchronous - e.g., {@link #addSyncStanzaListener(StanzaListener, StanzaFilter)}</li> 096 * <li>other - e.g., {@link #addStanzaListener(StanzaListener, StanzaFilter)}</li> 097 * </ul> 098 * <p> 099 * Asynchronous callbacks are run decoupled from the connections main event loop. Hence a callback triggered by 100 * stanza B may (appear to) invoked before a callback triggered by stanza A, even though stanza A arrived before B. 101 * </p> 102 * <p> 103 * Synchronous callbacks are invoked concurrently, but it is ensured that the same callback is never run concurrently 104 * and that they are executed in order. That is, if both stanza A and B trigger the same callback, and A arrives before 105 * B, then the callback will be invoked with A first, and then B. Furthermore, those callbacks are not executed within 106 * the main loop. However it is still advisable that those callbacks do not block or only block briefly. 107 * </p> 108 * <p> 109 * Other callbacks are run synchronous to the main event loop of a connection and are executed within the main loop. 110 * <b>This means that if such a callback blocks, the main event loop also blocks, which can easily cause deadlocks. 111 * Therefore, you should avoid using those callbacks unless you know what you are doing.</b> 112 * </p> 113 * <h2>Stanza Filters</h2> 114 * Stanza filters allow you to define the predicates for which listeners or collectors should be invoked. For more 115 * information about stanza filters, see {@link org.jivesoftware.smack.filter}. 116 * <h2>Provider Architecture</h2> 117 * XMPP is an extensible protocol. Smack allows for this extensible with its provider architecture that allows to 118 * plug-in providers that are able to parse the various XML extension elements used for XMPP's extensibility. For 119 * more information see {@link org.jivesoftware.smack.provider}. 120 * <h2>Debugging</h2> 121 * See {@link org.jivesoftware.smack.debugger} for Smack's API to debug XMPP connections. 122 * <h2>Modular Connection Architecture</h2> 123 * Smack's new modular connection architecture will one day replace the monolithic architecture. Its main entry 124 * point {@link org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection} has more information. 125 * 126 * @author Matt Tucker 127 * @author Guenther Niess 128 * @author Florian Schmaus 129 */ 130public interface XMPPConnection { 131 132 /** 133 * Returns the XMPP Domain of the service provided by the XMPP server and used for this connection. After 134 * authenticating with the server the returned value may be different. 135 * 136 * @return the XMPP domain of this XMPP session. 137 */ 138 DomainBareJid getXMPPServiceDomain(); 139 140 /** 141 * Returns the host name of the server where the XMPP server is running. This would be the 142 * IP address of the server or a name that may be resolved by a DNS server. 143 * 144 * @return the host name of the server where the XMPP server is running or null if not yet connected. 145 */ 146 String getHost(); 147 148 /** 149 * Returns the port number of the XMPP server for this connection. The default port 150 * for normal connections is 5222. 151 * 152 * @return the port number of the XMPP server or 0 if not yet connected. 153 */ 154 int getPort(); 155 156 /** 157 * Returns the full XMPP address of the user that is logged in to the connection or 158 * <code>null</code> if not logged in yet. An XMPP address is in the form 159 * username@server/resource. 160 * 161 * @return the full XMPP address of the user logged in. 162 */ 163 EntityFullJid getUser(); 164 165 /** 166 * Returns the local address currently in use for this connection, or <code>null</code> if 167 * this is invalid for the type of underlying connection. 168 * 169 * @return the local address currently in use for this connection 170 */ 171 InetAddress getLocalAddress(); 172 173 /** 174 * Returns the stream ID for this connection, which is the value set by the server 175 * when opening an XMPP stream. This value will be <code>null</code> if not connected to the server. 176 * 177 * @return the ID of this connection returned from the XMPP server or <code>null</code> if 178 * not connected to the server. 179 * @see <a href="http://xmpp.org/rfcs/rfc6120.html#streams-attr-id">RFC 6120 § 4.7.3. id</a> 180 */ 181 String getStreamId(); 182 183 /** 184 * Returns true if currently connected to the XMPP server. 185 * 186 * @return true if connected. 187 */ 188 boolean isConnected(); 189 190 /** 191 * Returns true if currently authenticated by successfully calling the login method. 192 * 193 * @return true if authenticated. 194 */ 195 boolean isAuthenticated(); 196 197 /** 198 * Returns true if currently authenticated anonymously. 199 * 200 * @return true if authenticated anonymously. 201 */ 202 boolean isAnonymous(); 203 204 /** 205 * Returns true if the connection to the server has successfully negotiated encryption. 206 * 207 * @return true if a secure connection to the server. 208 */ 209 boolean isSecureConnection(); 210 211 /** 212 * Returns true if network traffic is being compressed. When using stream compression network 213 * traffic can be reduced up to 90%. Therefore, stream compression is ideal when using a slow 214 * speed network connection. However, the server will need to use more CPU time in order to 215 * un/compress network data so under high load the server performance might be affected. 216 * 217 * @return true if network traffic is being compressed. 218 */ 219 boolean isUsingCompression(); 220 221 StanzaFactory getStanzaFactory(); 222 223 /** 224 * Sends the specified stanza to the server. 225 * 226 * @param stanza the stanza to send. 227 * @throws NotConnectedException if the connection is not connected. 228 * @throws InterruptedException if the calling thread was interrupted. 229 * */ 230 void sendStanza(Stanza stanza) throws NotConnectedException, InterruptedException; 231 232 void sendStanzaNonBlocking(Stanza stanza) throws NotConnectedException, OutgoingQueueFullException; 233 234 /** 235 * Try to send the given stanza. Returns {@code true} if the stanza was successfully put into the outgoing stanza 236 * queue, otherwise, if {@code false} is returned, the stanza could not be scheduled for sending (for example 237 * because the outgoing element queue is full). Note that this means that the stanza possibly was not put onto the 238 * wire, even if {@code true} is returned, it just has been successfully scheduled for sending. 239 * <p> 240 * <b>Note:</b> Implementations are not required to provide that functionality. In that case this method is mapped 241 * to {@link #sendStanza(Stanza)} and will possibly block until the stanza could be scheduled for sending. 242 * </p> 243 * 244 * @param stanza the stanza to send. 245 * @return {@code true} if the stanza was successfully scheduled to be send, {@code false} otherwise. 246 * @throws NotConnectedException if the connection is not connected. 247 * @since 4.4.0 248 * @deprecated use {@link #sendStanzaNonBlocking(Stanza)} instead. 249 */ 250 // TODO: Remove in Smack 4.7. 251 @Deprecated 252 boolean trySendStanza(Stanza stanza) throws NotConnectedException; 253 254 /** 255 * Try to send the given stanza. Returns {@code true} if the stanza was successfully put into the outgoing stanza 256 * queue within the given timeout period, otherwise, if {@code false} is returned, the stanza could not be scheduled 257 * for sending (for example because the outgoing element queue is full). Note that this means that the stanza 258 * possibly was not put onto the wire, even if {@code true} is returned, it just has been successfully scheduled for 259 * sending. 260 * <p> 261 * <b>Note:</b> Implementations are not required to provide that functionality. In that case this method is mapped 262 * to {@link #sendStanza(Stanza)} and will possibly block until the stanza could be scheduled for sending. 263 * </p> 264 * 265 * @param stanza the stanza to send. 266 * @param timeout how long to wait before giving up, in units of {@code unit}. 267 * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter. 268 * @return {@code true} if the stanza was successfully scheduled to be send, {@code false} otherwise. 269 * @throws NotConnectedException if the connection is not connected. 270 * @throws InterruptedException if the calling thread was interrupted. 271 * @since 4.4.0 272 * @deprecated use {@link #sendStanzaNonBlocking(Stanza)} instead. 273 */ 274 // TODO: Remove in Smack 4.7. 275 @Deprecated 276 boolean trySendStanza(Stanza stanza, long timeout, TimeUnit unit) throws NotConnectedException, InterruptedException; 277 278 /** 279 * Send a Nonza. 280 * <p> 281 * <b>This method is not meant for end-user usage!</b> It allows sending plain stream elements, which should not be 282 * done by a user manually. <b>Doing so may result in a unstable or unusable connection.</b> Certain Smack APIs use 283 * this method to send plain stream elements. 284 * </p> 285 * 286 * @param nonza the Nonza to send. 287 * @throws NotConnectedException if the XMPP connection is not connected. 288 * @throws InterruptedException if the calling thread was interrupted. 289 */ 290 void sendNonza(Nonza nonza) throws NotConnectedException, InterruptedException; 291 292 void sendNonzaNonBlocking(Nonza stanza) throws NotConnectedException, OutgoingQueueFullException; 293 294 /** 295 * Adds a connection listener to this connection that will be notified when 296 * the connection closes or fails. 297 * 298 * @param connectionListener a connection listener. 299 */ 300 void addConnectionListener(ConnectionListener connectionListener); 301 302 /** 303 * Removes a connection listener from this connection. 304 * 305 * @param connectionListener a connection listener. 306 */ 307 void removeConnectionListener(ConnectionListener connectionListener); 308 309 /** 310 * Send an IQ request and wait for the response. 311 * 312 * @param request the IQ request 313 * @param <I> the type of the expected result IQ. 314 * @return an IQ with type 'result' 315 * @throws NoResponseException if there was no response from the remote entity. 316 * @throws XMPPErrorException if there was an XMPP error returned. 317 * @throws NotConnectedException if the XMPP connection is not connected. 318 * @throws InterruptedException if the calling thread was interrupted. 319 * @since 4.3 320 */ 321 <I extends IQ> I sendIqRequestAndWaitForResponse(IQ request) 322 throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException; 323 324 /** 325 * Creates a new stanza collector collecting IQ responses that are replies to the IQ <code>request</code>. 326 * Does also send the <code>request</code> IQ. The stanza filter for the collector is an 327 * {@link IQReplyFilter}, guaranteeing that stanza id and JID in the 'from' address have 328 * expected values. 329 * 330 * @param request the IQ request to filter responses from 331 * @return a new stanza collector. 332 * @throws NotConnectedException if the XMPP connection is not connected. 333 * @throws InterruptedException if the calling thread was interrupted. 334 */ 335 StanzaCollector createStanzaCollectorAndSend(IQ request) throws NotConnectedException, InterruptedException; 336 337 /** 338 * Creates a new stanza collector for this connection. A stanza filter determines 339 * which stanzas will be accumulated by the collector. A StanzaCollector is 340 * more suitable to use than a {@link StanzaListener} when you need to wait for 341 * a specific result. 342 * 343 * @param stanzaFilter the stanza filter to use. 344 * @param stanza the stanza to send right after the collector got created 345 * @return a new stanza collector. 346 * @throws InterruptedException if the calling thread was interrupted. 347 * @throws NotConnectedException if the XMPP connection is not connected. 348 */ 349 StanzaCollector createStanzaCollectorAndSend(StanzaFilter stanzaFilter, Stanza stanza) 350 throws NotConnectedException, InterruptedException; 351 352 /** 353 * Creates a new stanza collector for this connection. A stanza filter 354 * determines which stanzas will be accumulated by the collector. A 355 * StanzaCollector is more suitable to use than a {@link StanzaListener} 356 * when you need to wait for a specific result. 357 * <p> 358 * <b>Note:</b> If you send a Stanza right after using this method, then 359 * consider using 360 * {@link #createStanzaCollectorAndSend(StanzaFilter, Stanza)} instead. 361 * Otherwise make sure cancel the StanzaCollector in every case, e.g. even 362 * if an exception is thrown, or otherwise you may leak the StanzaCollector. 363 * </p> 364 * 365 * @param stanzaFilter the stanza filter to use. 366 * @return a new stanza collector. 367 */ 368 StanzaCollector createStanzaCollector(StanzaFilter stanzaFilter); 369 370 /** 371 * Create a new stanza collector with the given stanza collector configuration. 372 * <p> 373 * Please make sure to cancel the collector when it is no longer required. See also 374 * {@link #createStanzaCollector(StanzaFilter)}. 375 * </p> 376 * 377 * @param configuration the stanza collector configuration. 378 * @return a new stanza collector. 379 * @since 4.1 380 */ 381 StanzaCollector createStanzaCollector(StanzaCollector.Configuration configuration); 382 383 /** 384 * Remove a stanza collector of this connection. 385 * 386 * @param collector a stanza collectors which was created for this connection. 387 */ 388 void removeStanzaCollector(StanzaCollector collector); 389 390 /** 391 * Registers a stanza listener with this connection. The listener will be invoked when a (matching) incoming stanza 392 * is received. The stanza filter determines which stanzas will be delivered to the listener. It is guaranteed that 393 * the same listener will not be invoked concurrently and the order of invocation will reflect the order in 394 * which the stanzas have been received. If the same stanza listener is added again with a different filter, only 395 * the new filter will be used. 396 * 397 * @param stanzaListener the stanza listener to notify of new received stanzas. 398 * @param stanzaFilter the stanza filter to use. 399 * @since 4.4.0 400 */ 401 void addStanzaListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter); 402 403 /** 404 * Removes a stanza listener for received stanzas from this connection. 405 * 406 * @param stanzaListener the stanza listener to remove. 407 * @return true if the stanza listener was removed. 408 * @since 4.4.0 409 */ 410 boolean removeStanzaListener(StanzaListener stanzaListener); 411 412 /** 413 * Registers a <b>synchronous</b> stanza listener with this connection. A stanza listener will be invoked only when 414 * an incoming stanza is received. A stanza filter determines which stanzas will be delivered to the listener. If 415 * the same stanza listener is added again with a different filter, only the new filter will be used. 416 * <p> 417 * <b>Important:</b> This stanza listeners will be called in the same <i>single</i> thread that processes all 418 * incoming stanzas. Only use this kind of stanza filter if it does not perform any XMPP activity that waits for a 419 * response. Consider using {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} when possible, i.e. when 420 * the invocation order doesn't have to be the same as the order of the arriving stanzas. If the order of the 421 * arriving stanzas, consider using a {@link StanzaCollector} when possible. 422 * </p> 423 * 424 * @param stanzaListener the stanza listener to notify of new received stanzas. 425 * @param stanzaFilter the stanza filter to use. 426 * @see #addStanzaInterceptor(StanzaListener, StanzaFilter) 427 * @since 4.1 428 */ 429 void addSyncStanzaListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter); 430 431 /** 432 * Removes a stanza listener for received stanzas from this connection. 433 * 434 * @param stanzaListener the stanza listener to remove. 435 * @return true if the stanza listener was removed 436 * @since 4.1 437 */ 438 boolean removeSyncStanzaListener(StanzaListener stanzaListener); 439 440 /** 441 * Registers an <b>asynchronous</b> stanza listener with this connection. A stanza listener will be invoked only 442 * when an incoming stanza is received. A stanza filter determines which stanzas will be delivered to the listener. 443 * If the same stanza listener is added again with a different filter, only the new filter will be used. 444 * <p> 445 * Unlike {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} stanza listeners added with this method will be 446 * invoked asynchronously in their own thread. Use this method if the order of the stanza listeners must not depend 447 * on the order how the stanzas where received. 448 * </p> 449 * 450 * @param stanzaListener the stanza listener to notify of new received stanzas. 451 * @param stanzaFilter the stanza filter to use. 452 * @see #addStanzaInterceptor(StanzaListener, StanzaFilter) 453 * @since 4.1 454 */ 455 void addAsyncStanzaListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter); 456 457 /** 458 * Removes an <b>asynchronous</b> stanza listener for received stanzas from this connection. 459 * 460 * @param stanzaListener the stanza listener to remove. 461 * @return true if the stanza listener was removed 462 * @since 4.1 463 */ 464 boolean removeAsyncStanzaListener(StanzaListener stanzaListener); 465 466 /** 467 * Registers a stanza listener with this connection. The listener will be 468 * notified of every stanza that this connection sends. A stanza filter determines 469 * which stanzas will be delivered to the listener. Note that the thread 470 * that writes stanzas will be used to invoke the listeners. Therefore, each 471 * stanza listener should complete all operations quickly or use a different 472 * thread for processing. 473 * 474 * @param stanzaListener the stanza listener to notify of sent stanzas. 475 * @param stanzaFilter the stanza filter to use. 476 */ 477 void addStanzaSendingListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter); 478 479 /** 480 * Removes a stanza listener for sending stanzas from this connection. 481 * 482 * @param stanzaListener the stanza listener to remove. 483 */ 484 void removeStanzaSendingListener(StanzaListener stanzaListener); 485 486 /** 487 * Registers a stanza interceptor with this connection. The interceptor will be 488 * invoked every time a stanza is about to be sent by this connection. Interceptors 489 * may modify the stanza to be sent. A stanza filter determines which stanzas 490 * will be delivered to the interceptor. 491 * 492 * <p> 493 * NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}. 494 * </p> 495 * 496 * @param stanzaInterceptor the stanza interceptor to notify of stanzas about to be sent. 497 * @param stanzaFilter the stanza filter to use. 498 * @deprecated use {@link #addMessageInterceptor(Consumer, Predicate)} or {@link #addPresenceInterceptor(Consumer, Predicate)} instead. 499 */ 500 @Deprecated 501 // TODO: Remove in Smack 4.5. 502 void addStanzaInterceptor(StanzaListener stanzaInterceptor, StanzaFilter stanzaFilter); 503 504 /** 505 * Removes a stanza interceptor. 506 * 507 * @param stanzaInterceptor the stanza interceptor to remove. 508 * @deprecated use {@link #removeMessageInterceptor(Consumer)} or {@link #removePresenceInterceptor(Consumer)} instead. 509 */ 510 @Deprecated 511 // TODO: Remove in Smack 4.5. 512 void removeStanzaInterceptor(StanzaListener stanzaInterceptor); 513 514 /** 515 * Registers a stanza interceptor with this connection. The interceptor will be 516 * invoked every time a stanza is about to be sent by this connection. Interceptors 517 * may modify the stanza to be sent. A stanza filter determines which stanzas 518 * will be delivered to the interceptor. 519 * 520 * <p> 521 * NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}. 522 * </p> 523 * 524 * @param messageInterceptor the stanza interceptor to notify of stanzas about to be sent. 525 * @param messageFilter the stanza filter to use. 526 */ 527 void addMessageInterceptor(Consumer<MessageBuilder> messageInterceptor, Predicate<Message> messageFilter); 528 529 /** 530 * Removes a message interceptor. 531 * 532 * @param messageInterceptor the message interceptor to remove. 533 */ 534 void removeMessageInterceptor(Consumer<MessageBuilder> messageInterceptor); 535 536 /** 537 * Registers a stanza interceptor with this connection. The interceptor will be 538 * invoked every time a stanza is about to be sent by this connection. Interceptors 539 * may modify the stanza to be sent. A stanza filter determines which stanzas 540 * will be delivered to the interceptor. 541 * 542 * <p> 543 * NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}. 544 * </p> 545 * 546 * @param presenceInterceptor the stanza interceptor to notify of stanzas about to be sent. 547 * @param presenceFilter the stanza filter to use. 548 */ 549 void addPresenceInterceptor(Consumer<PresenceBuilder> presenceInterceptor, Predicate<Presence> presenceFilter); 550 551 /** 552 * Removes a presence interceptor. 553 * 554 * @param presenceInterceptor the stanza interceptor to remove. 555 */ 556 void removePresenceInterceptor(Consumer<PresenceBuilder> presenceInterceptor); 557 /** 558 * Returns the current value of the reply timeout in milliseconds for request for this 559 * XMPPConnection instance. 560 * 561 * @return the reply timeout in milliseconds 562 */ 563 long getReplyTimeout(); 564 565 /** 566 * Set the stanza reply timeout in milliseconds. In most cases, Smack will throw a 567 * {@link NoResponseException} if no reply to a request was received within the timeout period. 568 * 569 * @param timeout for a reply in milliseconds 570 */ 571 void setReplyTimeout(long timeout); 572 573 /** 574 * Get the connection counter of this XMPPConnection instance. Those can be used as ID to 575 * identify the connection, but beware that the ID may not be unique if you create more then 576 * <code>2*Integer.MAX_VALUE</code> instances as the counter could wrap. 577 * 578 * @return the connection counter of this XMPPConnection 579 */ 580 int getConnectionCounter(); 581 582 enum FromMode { 583 /** 584 * Leave the 'from' attribute unchanged. This is the behavior of Smack < 4.0 585 */ 586 UNCHANGED, 587 /** 588 * Omit the 'from' attribute. According to RFC 6120 8.1.2.1 1. XMPP servers "MUST (...) 589 * override the 'from' attribute specified by the client". It is therefore safe to specify 590 * FromMode.OMITTED here. 591 */ 592 OMITTED, 593 /** 594 * Set the from to the clients full JID. This is usually not required. 595 */ 596 USER 597 } 598 599 /** 600 * Set the FromMode for this connection instance. Defines how the 'from' attribute of outgoing 601 * stanzas should be populated by Smack. 602 * 603 * @param fromMode TODO javadoc me please 604 */ 605 void setFromMode(FromMode fromMode); 606 607 /** 608 * Get the currently active FromMode. 609 * 610 * @return the currently active {@link FromMode} 611 */ 612 FromMode getFromMode(); 613 614 /** 615 * Get the feature stanza extensions for a given stream feature of the 616 * server, or <code>null</code> if the server doesn't support that feature. 617 * 618 * @param <F> {@link ExtensionElement} type of the feature. 619 * @param element TODO javadoc me please 620 * @param namespace TODO javadoc me please 621 * @return a stanza extensions of the feature or <code>null</code> 622 * @deprecated use {@link #getFeature(Class)} instead. 623 */ 624 // TODO: Remove in Smack 4.5. 625 @Deprecated 626 default <F extends XmlElement> F getFeature(String element, String namespace) { 627 QName qname = new QName(namespace, element); 628 return getFeature(qname); 629 } 630 631 /** 632 * Get the feature stanza extensions for a given stream feature of the 633 * server, or <code>null</code> if the server doesn't support that feature. 634 * 635 * @param <F> {@link ExtensionElement} type of the feature. 636 * @param qname the qualified name of the XML element of feature. 637 * @return a stanza extensions of the feature or <code>null</code> 638 * @since 4.4 639 */ 640 <F extends XmlElement> F getFeature(QName qname); 641 642 /** 643 * Get the feature stanza extensions for a given stream feature of the 644 * server, or <code>null</code> if the server doesn't support that feature. 645 * 646 * @param <F> {@link ExtensionElement} type of the feature. 647 * @param featureClass the class of the feature. 648 * @return a stanza extensions of the feature or <code>null</code> 649 * @since 4.4 650 */ 651 default <F extends XmlElement> F getFeature(Class<F> featureClass) { 652 QName qname = XmppElementUtil.getQNameFor(featureClass); 653 return getFeature(qname); 654 } 655 656 /** 657 * Return true if the server supports the given stream feature. 658 * 659 * @param element TODO javadoc me please 660 * @param namespace TODO javadoc me please 661 * @return true if the server supports the stream feature. 662 */ 663 default boolean hasFeature(String element, String namespace) { 664 QName qname = new QName(namespace, element); 665 return hasFeature(qname); 666 } 667 668 /** 669 * Return true if the server supports the given stream feature. 670 * 671 * @param qname the qualified name of the XML element of feature. 672 * @return true if the server supports the stream feature. 673 */ 674 boolean hasFeature(QName qname); 675 676 /** 677 * Send an IQ request asynchronously. The connection's default reply timeout will be used. 678 * 679 * @param request the IQ request to send. 680 * @return a SmackFuture for the response. 681 */ 682 SmackFuture<IQ, Exception> sendIqRequestAsync(IQ request); 683 684 /** 685 * Send an IQ request asynchronously. 686 * 687 * @param request the IQ request to send. 688 * @param timeout the reply timeout in milliseconds. 689 * @return a SmackFuture for the response. 690 */ 691 SmackFuture<IQ, Exception> sendIqRequestAsync(IQ request, long timeout); 692 693 /** 694 * Send a stanza asynchronously, waiting for exactly one response stanza using the given reply filter. The 695 * connection's default reply timeout will be used. 696 * 697 * @param stanza the stanza to send. 698 * @param replyFilter the filter used for the response stanza. 699 * @param <S> the type of the stanza to send. 700 * @return a SmackFuture for the response. 701 */ 702 <S extends Stanza> SmackFuture<S, Exception> sendAsync(S stanza, StanzaFilter replyFilter); 703 704 /** 705 * Send a stanza asynchronously, waiting for exactly one response stanza using the given reply filter. 706 * 707 * @param stanza the stanza to send. 708 * @param replyFilter the filter used for the response stanza. 709 * @param timeout the reply timeout in milliseconds. 710 * @param <S> the type of the stanza to send. 711 * @return a SmackFuture for the response. 712 */ 713 <S extends Stanza> SmackFuture<S, Exception> sendAsync(S stanza, StanzaFilter replyFilter, long timeout); 714 715 /** 716 * Add a callback that is called exactly once and synchronously with the incoming stanza that matches the given 717 * stanza filter. 718 * 719 * @param callback the callback invoked once the stanza filter matches a stanza. 720 * @param stanzaFilter the filter to match stanzas or null to match all. 721 */ 722 void addOneTimeSyncCallback(StanzaListener callback, StanzaFilter stanzaFilter); 723 724 /** 725 * Register an IQ request handler with this connection. 726 * <p> 727 * IQ request handler process incoming IQ requests, i.e. incoming IQ stanzas of type 'get' or 'set', and return a result. 728 * </p> 729 * @param iqRequestHandler the IQ request handler to register. 730 * @return the previously registered IQ request handler or null. 731 */ 732 IQRequestHandler registerIQRequestHandler(IQRequestHandler iqRequestHandler); 733 734 /** 735 * Convenience method for {@link #unregisterIQRequestHandler(String, String, org.jivesoftware.smack.packet.IQ.Type)}. 736 * 737 * @param iqRequestHandler TODO javadoc me please 738 * @return the previously registered IQ request handler or null. 739 */ 740 IQRequestHandler unregisterIQRequestHandler(IQRequestHandler iqRequestHandler); 741 742 /** 743 * Unregister an IQ request handler with this connection. 744 * 745 * @param element the IQ element the IQ request handler is responsible for. 746 * @param namespace the IQ namespace the IQ request handler is responsible for. 747 * @param type the IQ type the IQ request handler is responsible for. 748 * @return the previously registered IQ request handler or null. 749 */ 750 IQRequestHandler unregisterIQRequestHandler(String element, String namespace, IQ.Type type); 751 752 /** 753 * Returns the timestamp in milliseconds when the last stanza was received. 754 * 755 * @return the timestamp in milliseconds 756 */ 757 long getLastStanzaReceived(); 758}