Reconnection works now

This commit is contained in:
Manevolent
2018-08-13 09:48:30 -04:00
parent 89c483d3b9
commit ca869089cf
3 changed files with 100 additions and 60 deletions
@@ -26,6 +26,7 @@ import com.github.manevolent.ts3j.util.Ts3Debugging;
import com.github.manevolent.ts3j.util.Pair;
import org.bouncycastle.crypto.InvalidCipherTextException;
import java.io.EOFException;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.SocketTimeoutException;
@@ -225,6 +226,8 @@ public abstract class AbstractTeamspeakClientSocket
for (PacketKind kind : PacketKind.values()) {
packetStatistics.put(kind, new PacketStatistics());
}
setTransformation(new InitPacketTransformation());
}
public ClientConnectionState getState() {
@@ -762,7 +765,7 @@ public abstract class AbstractTeamspeakClientSocket
}
}
throw new IllegalStateException("no longer reading");
throw new EOFException();
}
/**
@@ -900,6 +903,8 @@ public abstract class AbstractTeamspeakClientSocket
while (isReading()) {
try {
readQueue.put(readPacket());
} catch (EOFException e) {
break;
} catch (Throwable e) {
if (e instanceof InterruptedException) {
Thread.yield();
@@ -912,6 +917,7 @@ public abstract class AbstractTeamspeakClientSocket
}
try {
if (getState() != ClientConnectionState.DISCONNECTED)
setState(ClientConnectionState.DISCONNECTED);
} catch (Throwable e1) {
exceptionHandler.accept(e1);
@@ -24,6 +24,7 @@ import com.github.manevolent.ts3j.util.HighPrecisionRecurrentTask;
import com.github.manevolent.ts3j.util.Ts3Debugging;
import com.github.manevolent.ts3j.util.Pair;
import java.io.EOFException;
import java.io.IOException;
import java.net.*;
import java.nio.ByteBuffer;
@@ -37,15 +38,7 @@ public class LocalTeamspeakClientSocket
extends AbstractTeamspeakClientSocket
implements CommandProcessor {
private final DatagramSocket socket;
{
try {
socket = new DatagramSocket();
} catch (SocketException e) {
throw new RuntimeException(e);
}
}
private DatagramSocket socket;
private final DatagramPacket packet = new DatagramPacket(new byte[500], 500);
@@ -53,6 +46,7 @@ public class LocalTeamspeakClientSocket
private final ExecutorService commandExecutionService = Executors.newCachedThreadPool();
private final Object commandSendLock = new Object();
private volatile InetSocketAddress remote;
private Microphone microphone;
private Thread microphoneThread;
@@ -161,9 +155,23 @@ public class LocalTeamspeakClientSocket
protected NetworkPacket readNetworkPacket(int timeout) throws
IOException,
SocketTimeoutException {
DatagramSocket socket = this.socket;
InetSocketAddress remote = this.remote;
while (socket.isBound()) {
socket.setSoTimeout(timeout);
try {
socket.receive(packet);
} catch (SocketException ex) {
if (socket.isClosed()) throw new EOFException();
else throw ex;
}
if (remote == null || getState() == ClientConnectionState.DISCONNECTED)
break;
else if (!packet.getAddress().equals(remote.getAddress()) || packet.getPort() != remote.getPort())
continue;
PacketHeader header;
@@ -191,12 +199,25 @@ public class LocalTeamspeakClientSocket
);
}
throw new IOException("disconnected");
}
@Override
protected void writeNetworkPacket(NetworkPacket packet) throws IOException {
InetSocketAddress remote = this.remote;
ClientConnectionState state = this.getState();
if (state == ClientConnectionState.DISCONNECTED)
throw new IllegalStateException(state.name());
else if (remote == null)
throw new IOException(new NullPointerException("remote"));
Ts3Debugging.debug("[NETWORK] WRITE id=" + packet.getHeader().getPacketId() + " len=" +
packet.getDatagram().getLength()
+ " to " +
socket.getRemoteSocketAddress());
remote.toString());
packet.getDatagram().setSocketAddress(remote);
socket.send(packet.getDatagram());
}
@@ -227,6 +248,8 @@ public class LocalTeamspeakClientSocket
}
serverId = null;
remote = null;
}
/**
@@ -239,15 +262,22 @@ public class LocalTeamspeakClientSocket
public void connect(InetSocketAddress remote, String password, long timeout)
throws IOException, TimeoutException {
try {
Ts3Debugging.debug("Connecting to " + remote + "...");
ClientConnectionState connectionState = getState();
if (connectionState != ClientConnectionState.DISCONNECTED)
throw new IllegalStateException(connectionState.name());
Ts3Debugging.debug("Connecting to " + remote + "...");
setClientId(0);
if (remote.isUnresolved())
remote = new InetSocketAddress(remote.getAddress().getHostAddress(), remote.getPort());
if (socket != null) socket.close();
socket = new DatagramSocket();
this.remote = remote;
serverId = null;
awaitingCommands.clear();
acceptingReturnCode = 0;
@@ -256,8 +286,6 @@ public class LocalTeamspeakClientSocket
if (password != null) setOption("client.password", password);
socket.connect(remote);
setState(ClientConnectionState.CONNECTING);
waitForState(ClientConnectionState.CONNECTED, timeout);
@@ -282,7 +310,7 @@ public class LocalTeamspeakClientSocket
@Override
protected boolean isReading() {
return socket.isConnected();
return super.isReading();
}
@Override
@@ -931,6 +959,7 @@ public class LocalTeamspeakClientSocket
throws
IOException, TimeoutException,
ExecutionException, InterruptedException {
try {
switch (getState()) {
case CONNECTING:
case RETRIEVING_DATA:
@@ -941,8 +970,13 @@ public class LocalTeamspeakClientSocket
new SingleCommand("clientdisconnect", ProtocolRole.CLIENT))
);
waitForState(ClientConnectionState.DISCONNECTED, 30000L);
break;
}
} finally {
setState(ClientConnectionState.DISCONNECTED);
}
}
}
@@ -17,8 +17,9 @@ import static org.junit.Assert.assertEquals;
public class ServerConnectionTest {
public static void main(String[] args) throws Exception {
while (true) {
try {
LocalTeamspeakClientSocket client = new LocalTeamspeakClientSocket();
Ts3Debugging.setEnabled(true);
LocalIdentity identity = LocalIdentity.load(
@@ -26,9 +27,8 @@ public class ServerConnectionTest {
);
identity.improveSecurity(10);
LocalTeamspeakClientSocket client = new LocalTeamspeakClientSocket();
while (true) {
try {
client.setIdentity(identity);
client.setNickname("Hello from Java");