diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/AbstractTeamspeakClientSocket.java b/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/AbstractTeamspeakClientSocket.java index ba95c9b..7573ce7 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/AbstractTeamspeakClientSocket.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/AbstractTeamspeakClientSocket.java @@ -558,8 +558,13 @@ public abstract class AbstractTeamspeakClientSocket } catch (TimeoutException e) { if (!response.willResend() || response.getResends() >= ResendTiming.MAX_RESENDS || System.nanoTime() - response.getFirstSent() - >= TimeUnit.MILLISECONDS.toNanos(ResendTiming.GIVE_UP_MS)) + >= TimeUnit.MILLISECONDS.toNanos(ResendTiming.GIVE_UP_MS)) { + // Commands are handled in order: the server holds back everything sent after this one + // until it arrives, so giving up on it loses the connection, as in the official client. + if (getState() == ClientConnectionState.CONNECTED) + setState(ClientConnectionState.DISCONNECTED); throw new TimeoutException("send"); + } response.resend(); } catch (CancellationException e) { throw e; @@ -984,23 +989,25 @@ public abstract class AbstractTeamspeakClientSocket private class NetworkHandler implements Runnable { @Override public void run() { - try { - while (isReading()) { - try { - Packet packet = readQueue.take(); - - // separate these so we getHandler at proper runtime instant rather than get it and let it change - // on us - - getHandler().handlePacket(packet); - } catch (InterruptedException e) { - break; - } + while (isReading()) { + Packet packet; + try { + packet = readQueue.take(); + } catch (InterruptedException e) { + break; + } + + // One bad packet must not end this thread: everything received after it would queue up unhandled + // while ACKs and pings, answered by the reader, keep the connection looking alive. + try { + // separate these so we getHandler at proper runtime instant rather than get it and let it change + // on us + getHandler().handlePacket(packet); + } catch (Throwable e) { + Ts3Debugging.debug("Problem handling packet", e); + // A disconnect interrupts whatever the handler was waiting on; that is not an error. + if (isReading()) getExceptionHandler().accept(e); } - } catch (Throwable e) { - Ts3Debugging.debug("Problem reading packet", e); - // A disconnect interrupts whatever the handler was waiting on; that is not an error. - if (isReading()) getExceptionHandler().accept(e); } } } diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/LocalTeamspeakClientSocket.java b/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/LocalTeamspeakClientSocket.java index f7b91e7..2b18bd3 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/LocalTeamspeakClientSocket.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/LocalTeamspeakClientSocket.java @@ -66,6 +66,9 @@ public class LocalTeamspeakClientSocket *
* get
*/
+ /** Whether losing the connection now would go unreported: connected, and neither side has said goodbye. */
+ private volatile boolean dropUnannounced;
+
private Map