mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-26 00:02:06 +01:00
Typo in XMPPTCPConnection s/ResumptiodDefault/ResumptionDefault/
This commit is contained in:
parent
15c1c8ad19
commit
7ceb5f09df
1 changed files with 179 additions and 160 deletions
|
@ -20,7 +20,6 @@ import org.jivesoftware.smack.AbstractConnectionListener;
|
||||||
import org.jivesoftware.smack.AbstractXMPPConnection;
|
import org.jivesoftware.smack.AbstractXMPPConnection;
|
||||||
import org.jivesoftware.smack.ConnectionConfiguration;
|
import org.jivesoftware.smack.ConnectionConfiguration;
|
||||||
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
|
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
|
||||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
|
||||||
import org.jivesoftware.smack.StanzaListener;
|
import org.jivesoftware.smack.StanzaListener;
|
||||||
import org.jivesoftware.smack.SmackConfiguration;
|
import org.jivesoftware.smack.SmackConfiguration;
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
|
@ -68,14 +67,19 @@ import org.jivesoftware.smack.sm.packet.StreamManagement.Resumed;
|
||||||
import org.jivesoftware.smack.sm.packet.StreamManagement.StreamManagementFeature;
|
import org.jivesoftware.smack.sm.packet.StreamManagement.StreamManagementFeature;
|
||||||
import org.jivesoftware.smack.sm.predicates.Predicate;
|
import org.jivesoftware.smack.sm.predicates.Predicate;
|
||||||
import org.jivesoftware.smack.sm.provider.ParseStreamManagement;
|
import org.jivesoftware.smack.sm.provider.ParseStreamManagement;
|
||||||
import org.jivesoftware.smack.packet.PlainStreamElement;
|
import org.jivesoftware.smack.packet.Nonza;
|
||||||
import org.jivesoftware.smack.packet.XMPPError;
|
import org.jivesoftware.smack.packet.XMPPError;
|
||||||
|
import org.jivesoftware.smack.proxy.ProxyInfo;
|
||||||
import org.jivesoftware.smack.util.ArrayBlockingQueueWithShutdown;
|
import org.jivesoftware.smack.util.ArrayBlockingQueueWithShutdown;
|
||||||
import org.jivesoftware.smack.util.Async;
|
import org.jivesoftware.smack.util.Async;
|
||||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
import org.jivesoftware.smack.util.StringUtils;
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
import org.jivesoftware.smack.util.TLSUtils;
|
import org.jivesoftware.smack.util.TLSUtils;
|
||||||
|
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||||
import org.jivesoftware.smack.util.dns.HostAddress;
|
import org.jivesoftware.smack.util.dns.HostAddress;
|
||||||
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
import org.jxmpp.util.XmppStringUtils;
|
import org.jxmpp.util.XmppStringUtils;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
@ -152,14 +156,6 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
*/
|
*/
|
||||||
private boolean disconnectedButResumeable = false;
|
private boolean disconnectedButResumeable = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag to indicate if the socket was closed intentionally by Smack.
|
|
||||||
* <p>
|
|
||||||
* This boolean flag is used concurrently, therefore it is marked volatile.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
private volatile boolean socketClosed = false;
|
|
||||||
|
|
||||||
private boolean usingTLS = false;
|
private boolean usingTLS = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -172,19 +168,27 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
*/
|
*/
|
||||||
protected PacketReader packetReader;
|
protected PacketReader packetReader;
|
||||||
|
|
||||||
private final SynchronizationPoint<Exception> initalOpenStreamSend = new SynchronizationPoint<Exception>(this);
|
private final SynchronizationPoint<Exception> initalOpenStreamSend = new SynchronizationPoint<>(
|
||||||
|
this, "initial open stream element send to server");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private final SynchronizationPoint<XMPPException> maybeCompressFeaturesReceived = new SynchronizationPoint<XMPPException>(
|
private final SynchronizationPoint<XMPPException> maybeCompressFeaturesReceived = new SynchronizationPoint<XMPPException>(
|
||||||
this);
|
this, "stream compression feature");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private final SynchronizationPoint<XMPPException> compressSyncPoint = new SynchronizationPoint<XMPPException>(
|
private final SynchronizationPoint<XMPPException> compressSyncPoint = new SynchronizationPoint<XMPPException>(
|
||||||
this);
|
this, "stream compression");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A synchronization point which is successful if this connection has received the closing
|
||||||
|
* stream element from the remote end-point, i.e. the server.
|
||||||
|
*/
|
||||||
|
private final SynchronizationPoint<Exception> closingStreamReceived = new SynchronizationPoint<>(
|
||||||
|
this, "stream closing element received");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default bundle and defer callback, used for new connections.
|
* The default bundle and defer callback, used for new connections.
|
||||||
|
@ -213,10 +217,10 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
private String smSessionId;
|
private String smSessionId;
|
||||||
|
|
||||||
private final SynchronizationPoint<XMPPException> smResumedSyncPoint = new SynchronizationPoint<XMPPException>(
|
private final SynchronizationPoint<XMPPException> smResumedSyncPoint = new SynchronizationPoint<XMPPException>(
|
||||||
this);
|
this, "stream resumed element");
|
||||||
|
|
||||||
private final SynchronizationPoint<XMPPException> smEnabledSyncPoint = new SynchronizationPoint<XMPPException>(
|
private final SynchronizationPoint<XMPPException> smEnabledSyncPoint = new SynchronizationPoint<XMPPException>(
|
||||||
this);
|
this, "stream enabled element");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The client's preferred maximum resumption time in seconds.
|
* The client's preferred maximum resumption time in seconds.
|
||||||
|
@ -316,8 +320,9 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
*
|
*
|
||||||
* @param jid the bare JID used by the client.
|
* @param jid the bare JID used by the client.
|
||||||
* @param password the password or authentication token.
|
* @param password the password or authentication token.
|
||||||
|
* @throws XmppStringprepException
|
||||||
*/
|
*/
|
||||||
public XMPPTCPConnection(CharSequence jid, String password) {
|
public XMPPTCPConnection(CharSequence jid, String password) throws XmppStringprepException {
|
||||||
this(XmppStringUtils.parseLocalpart(jid.toString()), password, XmppStringUtils.parseDomain(jid.toString()));
|
this(XmppStringUtils.parseLocalpart(jid.toString()), password, XmppStringUtils.parseDomain(jid.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,10 +336,11 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
* @param username
|
* @param username
|
||||||
* @param password
|
* @param password
|
||||||
* @param serviceName
|
* @param serviceName
|
||||||
|
* @throws XmppStringprepException
|
||||||
*/
|
*/
|
||||||
public XMPPTCPConnection(CharSequence username, String password, String serviceName) {
|
public XMPPTCPConnection(CharSequence username, String password, String serviceName) throws XmppStringprepException {
|
||||||
this(XMPPTCPConnectionConfiguration.builder().setUsernameAndPassword(username, password).setServiceName(
|
this(XMPPTCPConnectionConfiguration.builder().setUsernameAndPassword(username, password).setXmppDomain(
|
||||||
serviceName).build());
|
JidCreate.domainBareFrom(serviceName)).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -360,31 +366,21 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void afterSuccessfulLogin(final boolean resumed) throws NotConnectedException {
|
protected void afterSuccessfulLogin(final boolean resumed) throws NotConnectedException, InterruptedException {
|
||||||
// Reset the flag in case it was set
|
// Reset the flag in case it was set
|
||||||
disconnectedButResumeable = false;
|
disconnectedButResumeable = false;
|
||||||
super.afterSuccessfulLogin(resumed);
|
super.afterSuccessfulLogin(resumed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected synchronized void loginNonAnonymously(String username, String password, String resource) throws XMPPException, SmackException, IOException {
|
protected synchronized void loginInternal(String username, String password, Resourcepart resource) throws XMPPException,
|
||||||
if (saslAuthentication.hasNonAnonymousAuthentication()) {
|
SmackException, IOException, InterruptedException {
|
||||||
// Authenticate using SASL
|
// Authenticate using SASL
|
||||||
if (password != null) {
|
saslAuthentication.authenticate(username, password, config.getAuthzid());
|
||||||
saslAuthentication.authenticate(username, password, resource);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
saslAuthentication.authenticate(resource, config.getCallbackHandler());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new SmackException("No non-anonymous SASL authentication mechanism available");
|
|
||||||
}
|
|
||||||
|
|
||||||
// If compression is enabled then request the server to use stream compression. XEP-170
|
// If compression is enabled then request the server to use stream compression. XEP-170
|
||||||
// recommends to perform stream compression before resource binding.
|
// recommends to perform stream compression before resource binding.
|
||||||
if (config.isCompressionEnabled()) {
|
maybeEnableCompression();
|
||||||
useCompression();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSmResumptionPossible()) {
|
if (isSmResumptionPossible()) {
|
||||||
smResumedSyncPoint.sendAndWaitForResponse(new Resume(clientHandledStanzasCount, smSessionId));
|
smResumedSyncPoint.sendAndWaitForResponse(new Resume(clientHandledStanzasCount, smSessionId));
|
||||||
|
@ -436,37 +432,11 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
afterSuccessfulLogin(false);
|
afterSuccessfulLogin(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void loginAnonymously() throws XMPPException, SmackException, IOException {
|
|
||||||
// Wait with SASL auth until the SASL mechanisms have been received
|
|
||||||
saslFeatureReceived.checkIfSuccessOrWaitOrThrow();
|
|
||||||
|
|
||||||
if (saslAuthentication.hasAnonymousAuthentication()) {
|
|
||||||
saslAuthentication.authenticateAnonymously();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new SmackException("No anonymous SASL authentication mechanism available");
|
|
||||||
}
|
|
||||||
|
|
||||||
// If compression is enabled then request the server to use stream compression
|
|
||||||
if (config.isCompressionEnabled()) {
|
|
||||||
useCompression();
|
|
||||||
}
|
|
||||||
|
|
||||||
bindResourceAndEstablishSession(null);
|
|
||||||
|
|
||||||
afterSuccessfulLogin(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSecureConnection() {
|
public boolean isSecureConnection() {
|
||||||
return usingTLS;
|
return usingTLS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSocketClosed() {
|
|
||||||
return socketClosed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shuts the current connection down. After this method returns, the connection must be ready
|
* Shuts the current connection down. After this method returns, the connection must be ready
|
||||||
* for re-use by connect.
|
* for re-use by connect.
|
||||||
|
@ -478,7 +448,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
// Try to send a last SM Acknowledgement. Most servers won't find this information helpful, as the SM
|
// Try to send a last SM Acknowledgement. Most servers won't find this information helpful, as the SM
|
||||||
// state is dropped after a clean disconnect anyways. OTOH it doesn't hurt much either.
|
// state is dropped after a clean disconnect anyways. OTOH it doesn't hurt much either.
|
||||||
sendSmAcknowledgementInternal();
|
sendSmAcknowledgementInternal();
|
||||||
} catch (NotConnectedException e) {
|
} catch (InterruptedException | NotConnectedException e) {
|
||||||
LOGGER.log(Level.FINE, "Can not send final SM ack as connection is not connected", e);
|
LOGGER.log(Level.FINE, "Can not send final SM ack as connection is not connected", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -496,18 +466,27 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
if (disconnectedButResumeable) {
|
if (disconnectedButResumeable) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// First shutdown the writer, this will result in a closing stream element getting send to
|
||||||
|
// the server
|
||||||
|
if (packetWriter != null) {
|
||||||
|
packetWriter.shutdown(instant);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// After we send the closing stream element, check if there was already a
|
||||||
|
// closing stream element sent by the server or wait with a timeout for a
|
||||||
|
// closing stream element to be received from the server.
|
||||||
|
Exception res = closingStreamReceived.checkIfSuccessOrWait();
|
||||||
|
LOGGER.info("closingstream " + res);
|
||||||
|
} catch (InterruptedException | NoResponseException e) {
|
||||||
|
LOGGER.log(Level.INFO, "Exception while waiting for closing stream element from the server " + this, e);
|
||||||
|
}
|
||||||
|
|
||||||
if (packetReader != null) {
|
if (packetReader != null) {
|
||||||
packetReader.shutdown();
|
packetReader.shutdown();
|
||||||
}
|
}
|
||||||
if (packetWriter != null) {
|
|
||||||
packetWriter.shutdown(instant);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set socketClosed to true. This will cause the PacketReader
|
|
||||||
// and PacketWriter to ignore any Exceptions that are thrown
|
|
||||||
// because of a read/write from/to a closed stream.
|
|
||||||
// It is *important* that this is done before socket.close()!
|
|
||||||
socketClosed = true;
|
|
||||||
try {
|
try {
|
||||||
socket.close();
|
socket.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -540,12 +519,12 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(PlainStreamElement element) throws NotConnectedException {
|
public void sendNonza(Nonza element) throws NotConnectedException, InterruptedException {
|
||||||
packetWriter.sendStreamElement(element);
|
packetWriter.sendStreamElement(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void sendStanzaInternal(Stanza packet) throws NotConnectedException {
|
protected void sendStanzaInternal(Stanza packet) throws NotConnectedException, InterruptedException {
|
||||||
packetWriter.sendStreamElement(packet);
|
packetWriter.sendStreamElement(packet);
|
||||||
if (isSmEnabled()) {
|
if (isSmEnabled()) {
|
||||||
for (StanzaFilter requestAckPredicate : requestAckPredicates) {
|
for (StanzaFilter requestAckPredicate : requestAckPredicates) {
|
||||||
|
@ -560,6 +539,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
private void connectUsingConfiguration() throws IOException, ConnectionException {
|
private void connectUsingConfiguration() throws IOException, ConnectionException {
|
||||||
List<HostAddress> failedAddresses = populateHostAddresses();
|
List<HostAddress> failedAddresses = populateHostAddresses();
|
||||||
SocketFactory socketFactory = config.getSocketFactory();
|
SocketFactory socketFactory = config.getSocketFactory();
|
||||||
|
ProxyInfo proxyInfo = config.getProxyInfo();
|
||||||
|
int timeout = config.getConnectTimeout();
|
||||||
if (socketFactory == null) {
|
if (socketFactory == null) {
|
||||||
socketFactory = SocketFactory.getDefault();
|
socketFactory = SocketFactory.getDefault();
|
||||||
}
|
}
|
||||||
|
@ -579,7 +560,12 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
final String inetAddressAndPort = inetAddress + " at port " + port;
|
final String inetAddressAndPort = inetAddress + " at port " + port;
|
||||||
LOGGER.finer("Trying to establish TCP connection to " + inetAddressAndPort);
|
LOGGER.finer("Trying to establish TCP connection to " + inetAddressAndPort);
|
||||||
try {
|
try {
|
||||||
socket.connect(new InetSocketAddress(inetAddress, port), config.getConnectTimeout());
|
if (proxyInfo == null) {
|
||||||
|
socket.connect(new InetSocketAddress(inetAddress, port), timeout);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
proxyInfo.getProxySocketConnection().connect(socket, inetAddress, port, timeout);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (inetAddresses.hasNext()) {
|
if (inetAddresses.hasNext()) {
|
||||||
continue innerloop;
|
continue innerloop;
|
||||||
|
@ -638,13 +624,6 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
// Start the packet reader. The startup() method will block until we
|
// Start the packet reader. The startup() method will block until we
|
||||||
// get an opening stream packet back from server
|
// get an opening stream packet back from server
|
||||||
packetReader.init();
|
packetReader.init();
|
||||||
|
|
||||||
if (isFirstInitialization) {
|
|
||||||
// Notify listeners that a new connection has been established
|
|
||||||
for (ConnectionCreationListener listener : getConnectionCreationListeners()) {
|
|
||||||
listener.connectionCreated(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initReaderAndWriter() throws IOException {
|
private void initReaderAndWriter() throws IOException {
|
||||||
|
@ -682,14 +661,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
KeyManager[] kms = null;
|
KeyManager[] kms = null;
|
||||||
PasswordCallback pcb = null;
|
PasswordCallback pcb = null;
|
||||||
|
|
||||||
if(config.getCallbackHandler() == null) {
|
if (context == null) {
|
||||||
ks = null;
|
if(config.getKeystoreType().equals("PKCS11")) {
|
||||||
} else if (context == null) {
|
|
||||||
if(config.getKeystoreType().equals("NONE")) {
|
|
||||||
ks = null;
|
|
||||||
pcb = null;
|
|
||||||
}
|
|
||||||
else if(config.getKeystoreType().equals("PKCS11")) {
|
|
||||||
try {
|
try {
|
||||||
Constructor<?> c = Class.forName("sun.security.pkcs11.SunPKCS11").getConstructor(InputStream.class);
|
Constructor<?> c = Class.forName("sun.security.pkcs11.SunPKCS11").getConstructor(InputStream.class);
|
||||||
String pkcs11Config = "name = SmartCard\nlibrary = "+config.getPKCS11Library();
|
String pkcs11Config = "name = SmartCard\nlibrary = "+config.getPKCS11Library();
|
||||||
|
@ -759,8 +732,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
final HostnameVerifier verifier = getConfiguration().getHostnameVerifier();
|
final HostnameVerifier verifier = getConfiguration().getHostnameVerifier();
|
||||||
if (verifier == null) {
|
if (verifier == null) {
|
||||||
throw new IllegalStateException("No HostnameVerifier set. Use connectionConfiguration.setHostnameVerifier() to configure.");
|
throw new IllegalStateException("No HostnameVerifier set. Use connectionConfiguration.setHostnameVerifier() to configure.");
|
||||||
} else if (!verifier.verify(getServiceName(), sslSocket.getSession())) {
|
} else if (!verifier.verify(getXMPPServiceDomain().toString(), sslSocket.getSession())) {
|
||||||
throw new CertificateException("Hostname verification of certificate failed. Certificate does not authenticate " + getServiceName());
|
throw new CertificateException("Hostname verification of certificate failed. Certificate does not authenticate " + getXMPPServiceDomain());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set that TLS was successful
|
// Set that TLS was successful
|
||||||
|
@ -773,12 +746,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
* @return a instance of XMPPInputOutputStream or null if no suitable instance was found
|
* @return a instance of XMPPInputOutputStream or null if no suitable instance was found
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private XMPPInputOutputStream maybeGetCompressionHandler() {
|
private static XMPPInputOutputStream maybeGetCompressionHandler(Compress.Feature compression) {
|
||||||
Compress.Feature compression = getFeature(Compress.Feature.ELEMENT, Compress.NAMESPACE);
|
|
||||||
if (compression == null) {
|
|
||||||
// Server does not support compression
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
for (XMPPInputOutputStream handler : SmackConfiguration.getCompresionHandlers()) {
|
for (XMPPInputOutputStream handler : SmackConfiguration.getCompresionHandlers()) {
|
||||||
String method = handler.getCompressionMethod();
|
String method = handler.getCompressionMethod();
|
||||||
if (compression.getMethods().contains(method))
|
if (compression.getMethods().contains(method))
|
||||||
|
@ -808,12 +776,21 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
* @throws XMPPException
|
* @throws XMPPException
|
||||||
* @throws NoResponseException
|
* @throws NoResponseException
|
||||||
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
private void useCompression() throws NotConnectedException, NoResponseException, XMPPException {
|
private void maybeEnableCompression() throws NotConnectedException, NoResponseException, XMPPException, InterruptedException {
|
||||||
|
if (!config.isCompressionEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
maybeCompressFeaturesReceived.checkIfSuccessOrWait();
|
maybeCompressFeaturesReceived.checkIfSuccessOrWait();
|
||||||
|
Compress.Feature compression = getFeature(Compress.Feature.ELEMENT, Compress.NAMESPACE);
|
||||||
|
if (compression == null) {
|
||||||
|
// Server does not support compression
|
||||||
|
return;
|
||||||
|
}
|
||||||
// If stream compression was offered by the server and we want to use
|
// If stream compression was offered by the server and we want to use
|
||||||
// compression then send compression request to the server
|
// compression then send compression request to the server
|
||||||
if ((compressionHandler = maybeGetCompressionHandler()) != null) {
|
if ((compressionHandler = maybeGetCompressionHandler(compression)) != null) {
|
||||||
compressSyncPoint.sendAndWaitForResponseOrThrow(new Compress(compressionHandler.getCompressionMethod()));
|
compressSyncPoint.sendAndWaitForResponseOrThrow(new Compress(compressionHandler.getCompressionMethod()));
|
||||||
} else {
|
} else {
|
||||||
LOGGER.warning("Could not enable compression because no matching handler/method pair was found");
|
LOGGER.warning("Could not enable compression because no matching handler/method pair was found");
|
||||||
|
@ -821,25 +798,26 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establishes a connection to the XMPP server and performs an automatic login
|
* Establishes a connection to the XMPP server. It basically
|
||||||
* only if the previous connection state was logged (authenticated). It basically
|
* creates and maintains a socket connection to the server.
|
||||||
* creates and maintains a socket connection to the server.<p>
|
* <p>
|
||||||
* <p/>
|
|
||||||
* Listeners will be preserved from a previous connection if the reconnection
|
* Listeners will be preserved from a previous connection if the reconnection
|
||||||
* occurs after an abrupt termination.
|
* occurs after an abrupt termination.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @throws XMPPException if an error occurs while trying to establish the connection.
|
* @throws XMPPException if an error occurs while trying to establish the connection.
|
||||||
* @throws SmackException
|
* @throws SmackException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void connectInternal() throws SmackException, IOException, XMPPException {
|
protected void connectInternal() throws SmackException, IOException, XMPPException, InterruptedException {
|
||||||
|
closingStreamReceived.init();
|
||||||
// Establishes the TCP connection to the server and does setup the reader and writer. Throws an exception if
|
// Establishes the TCP connection to the server and does setup the reader and writer. Throws an exception if
|
||||||
// there is an error establishing the connection
|
// there is an error establishing the connection
|
||||||
connectUsingConfiguration();
|
connectUsingConfiguration();
|
||||||
|
|
||||||
// We connected successfully to the servers TCP port
|
// We connected successfully to the servers TCP port
|
||||||
socketClosed = false;
|
|
||||||
initConnection();
|
initConnection();
|
||||||
|
|
||||||
// Wait with SASL auth until the SASL mechanisms have been received
|
// Wait with SASL auth until the SASL mechanisms have been received
|
||||||
|
@ -848,13 +826,6 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
// Make note of the fact that we're now connected.
|
// Make note of the fact that we're now connected.
|
||||||
connected = true;
|
connected = true;
|
||||||
callConnectionConnectedListener();
|
callConnectionConnectedListener();
|
||||||
|
|
||||||
// Automatically makes the login if the user was previously connected successfully
|
|
||||||
// to the server and the connection was terminated abruptly
|
|
||||||
if (wasAuthenticated) {
|
|
||||||
login();
|
|
||||||
notifyReconnection();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -885,7 +856,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void afterFeaturesReceived() throws SecurityRequiredException, NotConnectedException {
|
protected void afterFeaturesReceived() throws SecurityRequiredException, NotConnectedException, InterruptedException {
|
||||||
StartTls startTlsFeature = getFeature(StartTls.ELEMENT, StartTls.NAMESPACE);
|
StartTls startTlsFeature = getFeature(StartTls.ELEMENT, StartTls.NAMESPACE);
|
||||||
if (startTlsFeature != null) {
|
if (startTlsFeature != null) {
|
||||||
if (startTlsFeature.required() && config.getSecurityMode() == SecurityMode.disabled) {
|
if (startTlsFeature.required() && config.getSecurityMode() == SecurityMode.disabled) {
|
||||||
|
@ -894,7 +865,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.getSecurityMode() != ConnectionConfiguration.SecurityMode.disabled) {
|
if (config.getSecurityMode() != ConnectionConfiguration.SecurityMode.disabled) {
|
||||||
send(new StartTls());
|
sendNonza(new StartTls());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If TLS is required but the server doesn't offer it, disconnect
|
// If TLS is required but the server doesn't offer it, disconnect
|
||||||
|
@ -919,20 +890,21 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
* to be sent by the server.
|
* to be sent by the server.
|
||||||
*
|
*
|
||||||
* @throws SmackException if the parser could not be reset.
|
* @throws SmackException if the parser could not be reset.
|
||||||
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
void openStream() throws SmackException {
|
void openStream() throws SmackException, InterruptedException {
|
||||||
// If possible, provide the receiving entity of the stream open tag, i.e. the server, as much information as
|
// If possible, provide the receiving entity of the stream open tag, i.e. the server, as much information as
|
||||||
// possible. The 'to' attribute is *always* available. The 'from' attribute if set by the user and no external
|
// possible. The 'to' attribute is *always* available. The 'from' attribute if set by the user and no external
|
||||||
// mechanism is used to determine the local entity (user). And the 'id' attribute is available after the first
|
// mechanism is used to determine the local entity (user). And the 'id' attribute is available after the first
|
||||||
// response from the server (see e.g. RFC 6120 § 9.1.1 Step 2.)
|
// response from the server (see e.g. RFC 6120 § 9.1.1 Step 2.)
|
||||||
CharSequence to = getServiceName();
|
CharSequence to = getXMPPServiceDomain();
|
||||||
CharSequence from = null;
|
CharSequence from = null;
|
||||||
CharSequence localpart = config.getUsername();
|
CharSequence localpart = config.getUsername();
|
||||||
if (localpart != null) {
|
if (localpart != null) {
|
||||||
from = XmppStringUtils.completeJidFrom(localpart, to);
|
from = XmppStringUtils.completeJidFrom(localpart, to);
|
||||||
}
|
}
|
||||||
String id = getStreamId();
|
String id = getStreamId();
|
||||||
send(new StreamOpen(to, from, id));
|
sendNonza(new StreamOpen(to, from, id));
|
||||||
try {
|
try {
|
||||||
packetReader.parser = PacketParserUtils.newXmppParser(reader);
|
packetReader.parser = PacketParserUtils.newXmppParser(reader);
|
||||||
}
|
}
|
||||||
|
@ -995,8 +967,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
// We found an opening stream.
|
// We found an opening stream.
|
||||||
if ("jabber:client".equals(parser.getNamespace(null))) {
|
if ("jabber:client".equals(parser.getNamespace(null))) {
|
||||||
streamId = parser.getAttributeValue("", "id");
|
streamId = parser.getAttributeValue("", "id");
|
||||||
String reportedServiceName = parser.getAttributeValue("", "from");
|
String reportedServerDomain = parser.getAttributeValue("", "from");
|
||||||
assert(reportedServiceName.equals(config.getServiceName()));
|
assert(config.getXMPPServiceDomain().equals(reportedServerDomain));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "error":
|
case "error":
|
||||||
|
@ -1151,8 +1123,33 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
break;
|
break;
|
||||||
case XmlPullParser.END_TAG:
|
case XmlPullParser.END_TAG:
|
||||||
if (parser.getName().equals("stream")) {
|
if (parser.getName().equals("stream")) {
|
||||||
// Disconnect the connection
|
if (!parser.getNamespace().equals("http://etherx.jabber.org/streams")) {
|
||||||
disconnect();
|
LOGGER.warning(XMPPTCPConnection.this + " </stream> but different namespace " + parser.getNamespace());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the queue was already shut down before reporting success on closing stream tag
|
||||||
|
// received. This avoids a race if there is a disconnect(), followed by a connect(), which
|
||||||
|
// did re-start the queue again, causing this writer to assume that the queue is not
|
||||||
|
// shutdown, which results in a call to disconnect().
|
||||||
|
final boolean queueWasShutdown = packetWriter.queue.isShutdown();
|
||||||
|
closingStreamReceived.reportSuccess();
|
||||||
|
|
||||||
|
if (queueWasShutdown) {
|
||||||
|
// We received a closing stream element *after* we initiated the
|
||||||
|
// termination of the session by sending a closing stream element to
|
||||||
|
// the server first
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// We received a closing stream element from the server without us
|
||||||
|
// sending a closing stream element first. This means that the
|
||||||
|
// server wants to terminate the session, therefore disconnect
|
||||||
|
// the connection
|
||||||
|
LOGGER.info(XMPPTCPConnection.this
|
||||||
|
+ " received closing </stream> element."
|
||||||
|
+ " Server wants to terminate the connection, calling disconnect()");
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XmlPullParser.END_DOCUMENT:
|
case XmlPullParser.END_DOCUMENT:
|
||||||
|
@ -1165,9 +1162,10 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
|
closingStreamReceived.reportFailure(e);
|
||||||
// The exception can be ignored if the the connection is 'done'
|
// The exception can be ignored if the the connection is 'done'
|
||||||
// or if the it was caused because the socket got closed
|
// or if the it was caused because the socket got closed
|
||||||
if (!(done || isSocketClosed())) {
|
if (!(done || packetWriter.queue.isShutdown())) {
|
||||||
// Close the connection and notify connection listeners of the
|
// Close the connection and notify connection listeners of the
|
||||||
// error.
|
// error.
|
||||||
notifyConnectionError(e);
|
notifyConnectionError(e);
|
||||||
|
@ -1186,7 +1184,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
* Needs to be protected for unit testing purposes.
|
* Needs to be protected for unit testing purposes.
|
||||||
*/
|
*/
|
||||||
protected SynchronizationPoint<NoResponseException> shutdownDone = new SynchronizationPoint<NoResponseException>(
|
protected SynchronizationPoint<NoResponseException> shutdownDone = new SynchronizationPoint<NoResponseException>(
|
||||||
XMPPTCPConnection.this);
|
XMPPTCPConnection.this, "shutdown completed");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set, the stanza(/packet) writer is shut down
|
* If set, the stanza(/packet) writer is shut down
|
||||||
|
@ -1234,9 +1232,14 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void throwNotConnectedExceptionIfDoneAndResumptionNotPossible() throws NotConnectedException {
|
protected void throwNotConnectedExceptionIfDoneAndResumptionNotPossible() throws NotConnectedException {
|
||||||
if (done() && !isSmResumptionPossible()) {
|
final boolean done = done();
|
||||||
|
if (done) {
|
||||||
|
final boolean smResumptionPossbile = isSmResumptionPossible();
|
||||||
// Don't throw a NotConnectedException is there is an resumable stream available
|
// Don't throw a NotConnectedException is there is an resumable stream available
|
||||||
throw new NotConnectedException();
|
if (!smResumptionPossbile) {
|
||||||
|
throw new NotConnectedException(XMPPTCPConnection.this, "done=" + done
|
||||||
|
+ " smResumptionPossible=" + smResumptionPossbile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1245,39 +1248,37 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
*
|
*
|
||||||
* @param element the element to send.
|
* @param element the element to send.
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
protected void sendStreamElement(Element element) throws NotConnectedException {
|
protected void sendStreamElement(Element element) throws NotConnectedException, InterruptedException {
|
||||||
throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
|
throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
|
||||||
|
try {
|
||||||
boolean enqueued = false;
|
queue.put(element);
|
||||||
while (!enqueued) {
|
}
|
||||||
try {
|
catch (InterruptedException e) {
|
||||||
queue.put(element);
|
// put() may throw an InterruptedException for two reasons:
|
||||||
enqueued = true;
|
// 1. If the queue was shut down
|
||||||
}
|
// 2. If the thread was interrupted
|
||||||
catch (InterruptedException e) {
|
// so we have to check which is the case
|
||||||
throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
|
throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
|
||||||
// If the method above did not throw, then the sending thread was interrupted
|
// If the method above did not throw, then the sending thread was interrupted
|
||||||
// TODO in a later version of Smack the InterruptedException should be thrown to
|
throw e;
|
||||||
// allow users to interrupt a sending thread that is currently blocking because
|
|
||||||
// the queue is full.
|
|
||||||
LOGGER.log(Level.WARNING, "Sending thread was interrupted", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shuts down the stanza(/packet) writer. Once this method has been called, no further
|
* Shuts down the stanza(/packet) writer. Once this method has been called, no further
|
||||||
* packets will be written to the server.
|
* packets will be written to the server.
|
||||||
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
void shutdown(boolean instant) {
|
void shutdown(boolean instant) {
|
||||||
instantShutdown = instant;
|
instantShutdown = instant;
|
||||||
shutdownTimestamp = System.currentTimeMillis();
|
|
||||||
queue.shutdown();
|
queue.shutdown();
|
||||||
|
shutdownTimestamp = System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
shutdownDone.checkIfSuccessOrWait();
|
shutdownDone.checkIfSuccessOrWait();
|
||||||
}
|
}
|
||||||
catch (NoResponseException e) {
|
catch (NoResponseException | InterruptedException e) {
|
||||||
LOGGER.log(Level.WARNING, "shutdownDone was not marked as successful by the writer thread", e);
|
LOGGER.log(Level.WARNING, "shutdownDone was not marked as successful by the writer thread", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1374,7 +1375,15 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writer.write(element.toXML().toString());
|
|
||||||
|
CharSequence elementXml = element.toXML();
|
||||||
|
if (elementXml instanceof XmlStringBuilder) {
|
||||||
|
((XmlStringBuilder) elementXml).write(writer);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
writer.write(elementXml.toString());
|
||||||
|
}
|
||||||
|
|
||||||
if (queue.isEmpty()) {
|
if (queue.isEmpty()) {
|
||||||
writer.flush();
|
writer.flush();
|
||||||
}
|
}
|
||||||
|
@ -1405,6 +1414,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
LOGGER.log(Level.WARNING, "Exception writing closing stream element", e);
|
LOGGER.log(Level.WARNING, "Exception writing closing stream element", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the queue contents (hopefully nothing is left).
|
// Delete the queue contents (hopefully nothing is left).
|
||||||
queue.clear();
|
queue.clear();
|
||||||
} else if (instantShutdown && isSmEnabled()) {
|
} else if (instantShutdown && isSmEnabled()) {
|
||||||
|
@ -1412,19 +1422,15 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
// into the unacknowledgedStanzas queue
|
// into the unacknowledgedStanzas queue
|
||||||
drainWriterQueueToUnacknowledgedStanzas();
|
drainWriterQueueToUnacknowledgedStanzas();
|
||||||
}
|
}
|
||||||
|
// Do *not* close the writer here, as it will cause the socket
|
||||||
try {
|
// to get closed. But we may want to receive further stanzas
|
||||||
writer.close();
|
// until the closing stream tag is received. The socket will be
|
||||||
}
|
// closed in shutdown().
|
||||||
catch (Exception e) {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
// The exception can be ignored if the the connection is 'done'
|
// The exception can be ignored if the the connection is 'done'
|
||||||
// or if the it was caused because the socket got closed
|
// or if the it was caused because the socket got closed
|
||||||
if (!(done() || isSocketClosed())) {
|
if (!(done() || queue.isShutdown())) {
|
||||||
notifyConnectionError(e);
|
notifyConnectionError(e);
|
||||||
} else {
|
} else {
|
||||||
LOGGER.log(Level.FINE, "Ignoring Exception in writePackets()", e);
|
LOGGER.log(Level.FINE, "Ignoring Exception in writePackets()", e);
|
||||||
|
@ -1459,8 +1465,19 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
* Set if Stream Management resumption should be used by default for new connections.
|
* Set if Stream Management resumption should be used by default for new connections.
|
||||||
*
|
*
|
||||||
* @param useSmResumptionDefault true to use Stream Management resumption for new connections.
|
* @param useSmResumptionDefault true to use Stream Management resumption for new connections.
|
||||||
|
* @deprecated use {@link #setUseStreamManagementResumptionDefault(boolean)} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static void setUseStreamManagementResumptiodDefault(boolean useSmResumptionDefault) {
|
public static void setUseStreamManagementResumptiodDefault(boolean useSmResumptionDefault) {
|
||||||
|
setUseStreamManagementDefault(useSmResumptionDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set if Stream Management resumption should be used by default for new connections.
|
||||||
|
*
|
||||||
|
* @param useSmResumptionDefault true to use Stream Management resumption for new connections.
|
||||||
|
*/
|
||||||
|
public static void setUseStreamManagementResumptionDefault(boolean useSmResumptionDefault) {
|
||||||
if (useSmResumptionDefault) {
|
if (useSmResumptionDefault) {
|
||||||
// Also enable SM is resumption is enabled
|
// Also enable SM is resumption is enabled
|
||||||
setUseStreamManagementDefault(useSmResumptionDefault);
|
setUseStreamManagementDefault(useSmResumptionDefault);
|
||||||
|
@ -1542,15 +1559,16 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
*
|
*
|
||||||
* @throws StreamManagementNotEnabledException if Stream Mangement is not enabled.
|
* @throws StreamManagementNotEnabledException if Stream Mangement is not enabled.
|
||||||
* @throws NotConnectedException if the connection is not connected.
|
* @throws NotConnectedException if the connection is not connected.
|
||||||
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
public void requestSmAcknowledgement() throws StreamManagementNotEnabledException, NotConnectedException {
|
public void requestSmAcknowledgement() throws StreamManagementNotEnabledException, NotConnectedException, InterruptedException {
|
||||||
if (!isSmEnabled()) {
|
if (!isSmEnabled()) {
|
||||||
throw new StreamManagementException.StreamManagementNotEnabledException();
|
throw new StreamManagementException.StreamManagementNotEnabledException();
|
||||||
}
|
}
|
||||||
requestSmAcknowledgementInternal();
|
requestSmAcknowledgementInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestSmAcknowledgementInternal() throws NotConnectedException {
|
private void requestSmAcknowledgementInternal() throws NotConnectedException, InterruptedException {
|
||||||
packetWriter.sendStreamElement(AckRequest.INSTANCE);
|
packetWriter.sendStreamElement(AckRequest.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1564,15 +1582,16 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
*
|
*
|
||||||
* @throws StreamManagementNotEnabledException if Stream Management is not enabled.
|
* @throws StreamManagementNotEnabledException if Stream Management is not enabled.
|
||||||
* @throws NotConnectedException if the connection is not connected.
|
* @throws NotConnectedException if the connection is not connected.
|
||||||
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
public void sendSmAcknowledgement() throws StreamManagementNotEnabledException, NotConnectedException {
|
public void sendSmAcknowledgement() throws StreamManagementNotEnabledException, NotConnectedException, InterruptedException {
|
||||||
if (!isSmEnabled()) {
|
if (!isSmEnabled()) {
|
||||||
throw new StreamManagementException.StreamManagementNotEnabledException();
|
throw new StreamManagementException.StreamManagementNotEnabledException();
|
||||||
}
|
}
|
||||||
sendSmAcknowledgementInternal();
|
sendSmAcknowledgementInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendSmAcknowledgementInternal() throws NotConnectedException {
|
private void sendSmAcknowledgementInternal() throws NotConnectedException, InterruptedException {
|
||||||
packetWriter.sendStreamElement(new AckAnswer(clientHandledStanzasCount));
|
packetWriter.sendStreamElement(new AckAnswer(clientHandledStanzasCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1785,8 +1804,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
try {
|
try {
|
||||||
listener.processPacket(ackedStanza);
|
listener.processPacket(ackedStanza);
|
||||||
}
|
}
|
||||||
catch (NotConnectedException e) {
|
catch (InterruptedException | NotConnectedException e) {
|
||||||
LOGGER.log(Level.FINER, "Received not connected exception", e);
|
LOGGER.log(Level.FINER, "Received exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String id = ackedStanza.getStanzaId();
|
String id = ackedStanza.getStanzaId();
|
||||||
|
@ -1798,8 +1817,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
try {
|
try {
|
||||||
listener.processPacket(ackedStanza);
|
listener.processPacket(ackedStanza);
|
||||||
}
|
}
|
||||||
catch (NotConnectedException e) {
|
catch (InterruptedException | NotConnectedException e) {
|
||||||
LOGGER.log(Level.FINER, "Received not connected exception", e);
|
LOGGER.log(Level.FINER, "Received exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue