gauge poking is needed after local application is disconnected same as before it's connected
This commit is contained in:
parent
635866c588
commit
f108884b87
|
@ -16,7 +16,6 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
import static com.devexperts.logging.Logging.getLogging;
|
import static com.devexperts.logging.Logging.getLogging;
|
||||||
import static com.rusefi.config.generated.Fields.TS_PROTOCOL;
|
import static com.rusefi.config.generated.Fields.TS_PROTOCOL;
|
||||||
|
@ -31,12 +30,12 @@ public class BinaryProtocolProxy {
|
||||||
*/
|
*/
|
||||||
public static final int USER_IO_TIMEOUT = 10 * Timeouts.MINUTE;
|
public static final int USER_IO_TIMEOUT = 10 * Timeouts.MINUTE;
|
||||||
|
|
||||||
public static ServerSocketReference createProxy(IoStream targetEcuSocket, int serverProxyPort, AtomicInteger relayCommandCounter) throws IOException {
|
public static ServerSocketReference createProxy(IoStream targetEcuSocket, int serverProxyPort, ClientApplicationActivityListener clientApplicationActivityListener) throws IOException {
|
||||||
CompatibleFunction<Socket, Runnable> clientSocketRunnableFactory = clientSocket -> () -> {
|
CompatibleFunction<Socket, Runnable> clientSocketRunnableFactory = clientSocket -> () -> {
|
||||||
TcpIoStream clientStream = null;
|
TcpIoStream clientStream = null;
|
||||||
try {
|
try {
|
||||||
clientStream = new TcpIoStream("[[proxy]] ", clientSocket);
|
clientStream = new TcpIoStream("[[proxy]] ", clientSocket);
|
||||||
runProxy(targetEcuSocket, clientStream, relayCommandCounter, USER_IO_TIMEOUT);
|
runProxy(targetEcuSocket, clientStream, clientApplicationActivityListener, USER_IO_TIMEOUT);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("BinaryProtocolProxy::run " + e);
|
log.error("BinaryProtocolProxy::run " + e);
|
||||||
close(clientStream);
|
close(clientStream);
|
||||||
|
@ -45,7 +44,14 @@ public class BinaryProtocolProxy {
|
||||||
return BinaryProtocolServer.tcpServerSocket(serverProxyPort, "proxy", clientSocketRunnableFactory, Listener.empty());
|
return BinaryProtocolServer.tcpServerSocket(serverProxyPort, "proxy", clientSocketRunnableFactory, Listener.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void runProxy(IoStream targetEcu, IoStream clientStream, AtomicInteger relayCommandCounter, int timeoutMs) throws IOException {
|
public interface ClientApplicationActivityListener {
|
||||||
|
ClientApplicationActivityListener VOID = () -> {
|
||||||
|
};
|
||||||
|
|
||||||
|
void onActivity();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runProxy(IoStream targetEcu, IoStream clientStream, ClientApplicationActivityListener listener, int timeoutMs) throws IOException {
|
||||||
/*
|
/*
|
||||||
* Each client socket is running on it's own thread
|
* Each client socket is running on it's own thread
|
||||||
*/
|
*/
|
||||||
|
@ -60,6 +66,7 @@ public class BinaryProtocolProxy {
|
||||||
byte[] packet = clientRequest.getPacket();
|
byte[] packet = clientRequest.getPacket();
|
||||||
if (packet.length > 1 && packet[0] == Fields.TS_ONLINE_PROTOCOL && packet[1] == NetworkConnector.DISCONNECT)
|
if (packet.length > 1 && packet[0] == Fields.TS_ONLINE_PROTOCOL && packet[1] == NetworkConnector.DISCONNECT)
|
||||||
throw new IOException("User requested disconnect");
|
throw new IOException("User requested disconnect");
|
||||||
|
listener.onActivity();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Two reasons for synchronization:
|
* Two reasons for synchronization:
|
||||||
|
@ -70,7 +77,6 @@ public class BinaryProtocolProxy {
|
||||||
synchronized (targetEcu) {
|
synchronized (targetEcu) {
|
||||||
sendToTarget(targetEcu, clientRequest);
|
sendToTarget(targetEcu, clientRequest);
|
||||||
controllerResponse = targetEcu.readPacket();
|
controllerResponse = targetEcu.readPacket();
|
||||||
relayCommandCounter.incrementAndGet();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Relaying controller response length=" + controllerResponse.getPacket().length);
|
log.info("Relaying controller response length=" + controllerResponse.getPacket().length);
|
||||||
|
|
|
@ -12,7 +12,6 @@ import com.rusefi.io.tcp.BinaryProtocolProxy;
|
||||||
import com.rusefi.io.tcp.ServerSocketReference;
|
import com.rusefi.io.tcp.ServerSocketReference;
|
||||||
import com.rusefi.io.tcp.TcpIoStream;
|
import com.rusefi.io.tcp.TcpIoStream;
|
||||||
import com.rusefi.proxy.NetworkConnector;
|
import com.rusefi.proxy.NetworkConnector;
|
||||||
import com.rusefi.proxy.NetworkConnectorContext;
|
|
||||||
import com.rusefi.server.ApplicationRequest;
|
import com.rusefi.server.ApplicationRequest;
|
||||||
import com.rusefi.server.rusEFISSLContext;
|
import com.rusefi.server.rusEFISSLContext;
|
||||||
import com.rusefi.tools.online.HttpUtil;
|
import com.rusefi.tools.online.HttpUtil;
|
||||||
|
@ -31,16 +30,17 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
import static com.devexperts.logging.Logging.getLogging;
|
import static com.devexperts.logging.Logging.getLogging;
|
||||||
|
import static com.rusefi.Timeouts.SECOND;
|
||||||
import static com.rusefi.binaryprotocol.BinaryProtocol.sleep;
|
import static com.rusefi.binaryprotocol.BinaryProtocol.sleep;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remote user process which facilitates connection between local tuning application and real ECU via rusEFI proxy service
|
* Remote user process which facilitates connection between local tuning application and real ECU via rusEFI proxy service
|
||||||
*/
|
*/
|
||||||
public class LocalApplicationProxy implements Closeable {
|
public class LocalApplicationProxy implements Closeable {
|
||||||
private static final ThreadFactory THREAD_FACTORY = new NamedThreadFactory("gauge poking");
|
private static final ThreadFactory THREAD_FACTORY = new NamedThreadFactory("gauge poking", true);
|
||||||
private static final Logging log = getLogging(LocalApplicationProxy.class);
|
private static final Logging log = getLogging(LocalApplicationProxy.class);
|
||||||
public static final int SERVER_PORT_FOR_APPLICATIONS = HttpUtil.getIntProperty("applications.port", 8002);
|
public static final int SERVER_PORT_FOR_APPLICATIONS = HttpUtil.getIntProperty("applications.port", 8002);
|
||||||
private final ApplicationRequest applicationRequest;
|
private final ApplicationRequest applicationRequest;
|
||||||
|
@ -101,26 +101,29 @@ public class LocalApplicationProxy implements Closeable {
|
||||||
AbstractIoStream authenticatorToProxyStream = new TcpIoStream("authenticatorToProxyStream ", rusEFISSLContext.getSSLSocket(HttpUtil.RUSEFI_PROXY_HOSTNAME, context.serverPortForRemoteApplications()), disconnectListener);
|
AbstractIoStream authenticatorToProxyStream = new TcpIoStream("authenticatorToProxyStream ", rusEFISSLContext.getSSLSocket(HttpUtil.RUSEFI_PROXY_HOSTNAME, context.serverPortForRemoteApplications()), disconnectListener);
|
||||||
LocalApplicationProxy.sendHello(authenticatorToProxyStream, applicationRequest);
|
LocalApplicationProxy.sendHello(authenticatorToProxyStream, applicationRequest);
|
||||||
|
|
||||||
AtomicInteger relayCommandCounter = new AtomicInteger();
|
AtomicLong lastActivity = new AtomicLong(System.currentTimeMillis());
|
||||||
|
BinaryProtocolProxy.ClientApplicationActivityListener clientApplicationActivityListener = () -> lastActivity.set(System.currentTimeMillis());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We need to entertain proxy server and remote controller while user has already connected to proxy but has not yet started TunerStudio
|
* We need to entertain proxy server and remote controller while user has already connected to proxy but has not yet started TunerStudio
|
||||||
*/
|
*/
|
||||||
THREAD_FACTORY.newThread(() -> {
|
THREAD_FACTORY.newThread(() -> {
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
try {
|
try {
|
||||||
while (relayCommandCounter.get() < 4 && !isTimeForApplicationToConnect(context, start)) {
|
while (true) {
|
||||||
sleep(context.gaugePokingPeriod());
|
sleep(context.gaugePokingPeriod());
|
||||||
byte[] commandPacket = GetOutputsCommand.createRequest();
|
if (isTimeForApplicationToConnect(lastActivity.get(), SECOND * 5)) {
|
||||||
|
byte[] commandPacket = GetOutputsCommand.createRequest();
|
||||||
|
// we do not really need the data, we just need to take response from the socket
|
||||||
|
authenticatorToProxyStream.sendAndGetPacket(commandPacket, "Gauge Poker", false);
|
||||||
|
}
|
||||||
|
|
||||||
// we do not really need the data, we just need to take response from the socket
|
if (isTimeForApplicationToConnect(lastActivity.get(), context.startUpIdle())) {
|
||||||
authenticatorToProxyStream.sendAndGetPacket(commandPacket, "Gauge Poker", false);
|
// we should not keep controller blocked since we are not connecting application, time to auto-disconnect
|
||||||
|
authenticatorToProxyStream.close();
|
||||||
|
disconnectListener.onDisconnect("Giving up connection");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTimeForApplicationToConnect(context, start) && relayCommandCounter.get() < 4) {
|
|
||||||
// we should not keep controller blocked since we are not connecting application, time to auto-disconnect
|
|
||||||
authenticatorToProxyStream.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Gauge poker", e);
|
log.error("Gauge poker", e);
|
||||||
|
@ -128,14 +131,14 @@ public class LocalApplicationProxy implements Closeable {
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
|
|
||||||
ServerSocketReference serverHolder = BinaryProtocolProxy.createProxy(authenticatorToProxyStream, context.authenticatorPort(), relayCommandCounter);
|
ServerSocketReference serverHolder = BinaryProtocolProxy.createProxy(authenticatorToProxyStream, context.authenticatorPort(), clientApplicationActivityListener);
|
||||||
LocalApplicationProxy localApplicationProxy = new LocalApplicationProxy(applicationRequest, serverHolder, authenticatorToProxyStream);
|
LocalApplicationProxy localApplicationProxy = new LocalApplicationProxy(applicationRequest, serverHolder, authenticatorToProxyStream);
|
||||||
connectionListener.onConnected(localApplicationProxy, authenticatorToProxyStream);
|
connectionListener.onConnected(localApplicationProxy, authenticatorToProxyStream);
|
||||||
return serverHolder;
|
return serverHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isTimeForApplicationToConnect(LocalApplicationProxyContext context, long start) {
|
private static boolean isTimeForApplicationToConnect(long start, int idle) {
|
||||||
return System.currentTimeMillis() - start > context.startUpIdle();
|
return System.currentTimeMillis() - start > idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendHello(IoStream authenticatorToProxyStream, ApplicationRequest applicationRequest) throws IOException {
|
public static void sendHello(IoStream authenticatorToProxyStream, ApplicationRequest applicationRequest) throws IOException {
|
||||||
|
|
|
@ -95,7 +95,8 @@ public class TcpCommunicationIntegrationTest {
|
||||||
|
|
||||||
// connect proxy to virtual controller
|
// connect proxy to virtual controller
|
||||||
IoStream targetEcuSocket = TestHelper.connectToLocalhost(controllerPort, LOGGER);
|
IoStream targetEcuSocket = TestHelper.connectToLocalhost(controllerPort, LOGGER);
|
||||||
BinaryProtocolProxy.createProxy(targetEcuSocket, proxyPort, new AtomicInteger());
|
final AtomicInteger relayCommandCounter = new AtomicInteger();
|
||||||
|
BinaryProtocolProxy.createProxy(targetEcuSocket, proxyPort, () -> relayCommandCounter.incrementAndGet());
|
||||||
|
|
||||||
CountDownLatch connectionEstablishedCountDownLatch = new CountDownLatch(1);
|
CountDownLatch connectionEstablishedCountDownLatch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,7 @@ public class Backend implements Closeable {
|
||||||
applications.add(applicationConnectionState);
|
applications.add(applicationConnectionState);
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryProtocolProxy.runProxy(state.getStream(), applicationClientStream, new AtomicInteger(), BinaryProtocolProxy.USER_IO_TIMEOUT);
|
BinaryProtocolProxy.runProxy(state.getStream(), applicationClientStream, BinaryProtocolProxy.ClientApplicationActivityListener.VOID, BinaryProtocolProxy.USER_IO_TIMEOUT);
|
||||||
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
log.info("Application Connector: Got error " + e);
|
log.info("Application Connector: Got error " + e);
|
||||||
|
|
|
@ -320,7 +320,7 @@ public class RemoteTab {
|
||||||
|
|
||||||
TcpIoStream.DisconnectListener disconnectListener = message -> SwingUtilities.invokeLater(() -> {
|
TcpIoStream.DisconnectListener disconnectListener = message -> SwingUtilities.invokeLater(() -> {
|
||||||
System.out.println("Disconnected " + message);
|
System.out.println("Disconnected " + message);
|
||||||
setStatus("Disconnected");
|
setStatus("Disconnected: " + message);
|
||||||
RemoteTabController.INSTANCE.setState(RemoteTabController.State.NOT_CONNECTED);
|
RemoteTabController.INSTANCE.setState(RemoteTabController.State.NOT_CONNECTED);
|
||||||
ServerSocketReference serverHolder = serverHolderAtomicReference.get();
|
ServerSocketReference serverHolder = serverHolderAtomicReference.get();
|
||||||
if (serverHolder != null)
|
if (serverHolder != null)
|
||||||
|
|
Loading…
Reference in New Issue