network connector to reconnect on proxy disconnect
This commit is contained in:
parent
5457287b2d
commit
c531127309
|
@ -0,0 +1,11 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Launcher network connector" type="Application" factoryName="Application">
|
||||
<option name="MAIN_CLASS_NAME" value="com.rusefi.Launcher" />
|
||||
<module name="ui" />
|
||||
<option name="PROGRAM_PARAMETERS" value="network_connector" />
|
||||
<option name="VM_PARAMETERS" value="-Dini_file_path=../firmware/tunerstudio -Dshow_etb_pane=true -Dhigh_speed_logger_rpm=10000" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
|
@ -2,16 +2,12 @@ package com.rusefi.tools;
|
|||
|
||||
import com.rusefi.auth.AutoTokenUtil;
|
||||
import com.rusefi.autodetect.PortDetector;
|
||||
import com.rusefi.io.tcp.TcpIoStream;
|
||||
import com.rusefi.proxy.NetworkConnector;
|
||||
import com.rusefi.server.Backend;
|
||||
import com.rusefi.server.SessionDetails;
|
||||
import com.rusefi.ui.AuthTokenPanel;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class NetworkConnectorStartup {
|
||||
public static void start() throws IOException, InterruptedException {
|
||||
public static void start() {
|
||||
String authToken = AuthTokenPanel.getAuthToken();
|
||||
if (!AutoTokenUtil.isToken(authToken)) {
|
||||
System.err.println("Please configure authentication token using 'set_auth_token' command");
|
||||
|
@ -24,10 +20,7 @@ public class NetworkConnectorStartup {
|
|||
return;
|
||||
}
|
||||
|
||||
SessionDetails sessionDetails = NetworkConnector.runNetworkConnector(authToken, autoDetectedPort, Backend.SERVER_PORT_FOR_CONTROLLERS, () -> {
|
||||
System.err.println("Disconnect detected");
|
||||
System.exit(-1);
|
||||
});
|
||||
System.out.println("Running with " + sessionDetails.getOneTimeToken());
|
||||
NetworkConnector.NetworkConnectorResult networkConnectorResult = NetworkConnector.runNetworkConnector(authToken, autoDetectedPort, Backend.SERVER_PORT_FOR_CONTROLLERS);
|
||||
System.out.println("Running with " + networkConnectorResult.getOneTimeToken());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,11 +72,12 @@ public class FullServerTest {
|
|||
|
||||
|
||||
// start "rusEFI network connector" to connect controller with backend since in real life controller has only local serial port it does not have network
|
||||
SessionDetails deviceSessionDetails = NetworkConnector.runNetworkConnector(MockRusEfiDevice.TEST_TOKEN_1, TestHelper.LOCALHOST + ":" + controllerPort, serverPortForControllers, TcpIoStream.DisconnectListener.VOID);
|
||||
NetworkConnector.NetworkConnectorResult networkConnectorResult = NetworkConnector.runNetworkConnector(MockRusEfiDevice.TEST_TOKEN_1, TestHelper.LOCALHOST + ":" + controllerPort, serverPortForControllers);
|
||||
ControllerInfo controllerInfo = networkConnectorResult.getControllerInfo();
|
||||
|
||||
assertTrue("controllerRegistered", controllerRegistered.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS));
|
||||
|
||||
SessionDetails authenticatorSessionDetails = new SessionDetails(deviceSessionDetails.getControllerInfo(), MockRusEfiDevice.TEST_TOKEN_3, deviceSessionDetails.getOneTimeToken());
|
||||
SessionDetails authenticatorSessionDetails = new SessionDetails(controllerInfo, MockRusEfiDevice.TEST_TOKEN_3, networkConnectorResult.getOneTimeToken());
|
||||
ApplicationRequest applicationRequest = new ApplicationRequest(authenticatorSessionDetails, userId);
|
||||
|
||||
// start authenticator
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.rusefi.proxy;
|
|||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.rusefi.NamedThreadFactory;
|
||||
import com.rusefi.Timeouts;
|
||||
import com.rusefi.binaryprotocol.IncomingDataBuffer;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.commands.HelloCommand;
|
||||
|
@ -31,9 +32,16 @@ public class BaseBroadcastingThread {
|
|||
try {
|
||||
boolean isFirstHello = true;
|
||||
while (true) {
|
||||
int ioTimeout;
|
||||
if (isFirstHello) {
|
||||
log.info("Waiting for proxy server to request session details");
|
||||
ioTimeout = Timeouts.CMD_TIMEOUT;
|
||||
} else {
|
||||
ioTimeout = BinaryProtocolProxy.USER_IO_TIMEOUT;
|
||||
}
|
||||
int length = getPacketLength(in, () -> {
|
||||
throw new UnsupportedOperationException();
|
||||
}, BinaryProtocolProxy.USER_IO_TIMEOUT);
|
||||
}, ioTimeout);
|
||||
BinaryProtocolServer.Packet packet = readPromisedBytes(in, length);
|
||||
byte[] payload = packet.getPacket();
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.rusefi.proxy;
|
|||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.opensr5.ConfigurationImage;
|
||||
import com.rusefi.Timeouts;
|
||||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.AbstractConnectionStateListener;
|
||||
|
@ -18,15 +19,20 @@ import org.jetbrains.annotations.NotNull;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.rusefi.binaryprotocol.BinaryProtocol.sleep;
|
||||
|
||||
/**
|
||||
* Connector between rusEFI ECU and rusEFI server
|
||||
* see NetworkConnectorStartup
|
||||
*/
|
||||
public class NetworkConnector {
|
||||
private final static Logging log = Logging.getLogging(NetworkConnector.class);
|
||||
public static SessionDetails runNetworkConnector(String authToken, String controllerPort, int serverPortForControllers, TcpIoStream.DisconnectListener disconnectListener) throws InterruptedException, IOException {
|
||||
public static final int RECONNECT_DELAY = 15;
|
||||
|
||||
public static NetworkConnectorResult runNetworkConnector(String authToken, String controllerPort, int serverPortForControllers) {
|
||||
LinkManager controllerConnector = new LinkManager()
|
||||
.setCompositeLogicEnabled(false)
|
||||
.setNeedPullData(false);
|
||||
|
@ -40,31 +46,55 @@ public class NetworkConnector {
|
|||
});
|
||||
|
||||
log.info("Connecting to controller...");
|
||||
onConnected.await(1, TimeUnit.MINUTES);
|
||||
try {
|
||||
onConnected.await(1, TimeUnit.MINUTES);
|
||||
} catch (InterruptedException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
if (onConnected.getCount() != 0) {
|
||||
log.info("Connection to controller failed");
|
||||
return null;
|
||||
return NetworkConnectorResult.ERROR;
|
||||
}
|
||||
|
||||
return runNetworkConnector(serverPortForControllers, controllerConnector, authToken, disconnectListener);
|
||||
ControllerInfo controllerInfo;
|
||||
try {
|
||||
controllerInfo = getControllerInfo(controllerConnector, controllerConnector.getConnector().getBinaryProtocol().getStream());
|
||||
} catch (IOException e) {
|
||||
return NetworkConnectorResult.ERROR;
|
||||
}
|
||||
|
||||
int oneTimeToken = SessionDetails.createOneTimeCode();
|
||||
|
||||
new Thread(() -> {
|
||||
Semaphore proxyReconnectSemaphore = new Semaphore(1);
|
||||
try {
|
||||
while (true) {
|
||||
log.info("Connecting to proxy server");
|
||||
proxyReconnectSemaphore.acquire();
|
||||
|
||||
try {
|
||||
runNetworkConnector(serverPortForControllers, controllerConnector, authToken, () -> {
|
||||
log.error("Disconnect from proxy server detected, now sleeping " + RECONNECT_DELAY + " seconds");
|
||||
sleep(RECONNECT_DELAY * Timeouts.SECOND);
|
||||
proxyReconnectSemaphore.release();
|
||||
}, oneTimeToken, controllerInfo);
|
||||
} catch (IOException e) {
|
||||
log.error("IO error", e);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}, "Proxy Reconnect").start();
|
||||
|
||||
return new NetworkConnectorResult(controllerInfo, oneTimeToken);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static SessionDetails runNetworkConnector(int serverPortForControllers, LinkManager linkManager, String authToken, final TcpIoStream.DisconnectListener disconnectListener) throws IOException {
|
||||
private static SessionDetails runNetworkConnector(int serverPortForControllers, LinkManager linkManager, String authToken, final TcpIoStream.DisconnectListener disconnectListener, int oneTimeToken, ControllerInfo controllerInfo) throws IOException {
|
||||
IoStream targetEcuSocket = linkManager.getConnector().getBinaryProtocol().getStream();
|
||||
HelloCommand.send(targetEcuSocket);
|
||||
String helloResponse = HelloCommand.getHelloResponse(targetEcuSocket.getDataBuffer());
|
||||
if (helloResponse == null)
|
||||
throw new IOException("Error getting hello response");
|
||||
String controllerSignature = helloResponse.trim();
|
||||
|
||||
ConfigurationImage image = linkManager.getConnector().getBinaryProtocol().getControllerConfiguration();
|
||||
String vehicleName = Fields.VEHICLENAME.getStringValue(image);
|
||||
String engineMake = Fields.ENGINEMAKE.getStringValue(image);
|
||||
String engineCode = Fields.ENGINECODE.getStringValue(image);
|
||||
ControllerInfo ci = new ControllerInfo(vehicleName, engineMake, engineCode, controllerSignature);
|
||||
|
||||
SessionDetails deviceSessionDetails = new SessionDetails(ci, authToken, SessionDetails.createOneTimeCode());
|
||||
SessionDetails deviceSessionDetails = new SessionDetails(controllerInfo, authToken, oneTimeToken);
|
||||
|
||||
BaseBroadcastingThread baseBroadcastingThread = new BaseBroadcastingThread(rusEFISSLContext.getSSLSocket(HttpUtil.RUSEFI_PROXY_HOSTNAME, serverPortForControllers),
|
||||
deviceSessionDetails,
|
||||
|
@ -83,4 +113,39 @@ public class NetworkConnector {
|
|||
baseBroadcastingThread.start();
|
||||
return deviceSessionDetails;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ControllerInfo getControllerInfo(LinkManager linkManager, IoStream targetEcuSocket) throws IOException {
|
||||
HelloCommand.send(targetEcuSocket);
|
||||
String helloResponse = HelloCommand.getHelloResponse(targetEcuSocket.getDataBuffer());
|
||||
if (helloResponse == null)
|
||||
throw new IOException("Error getting hello response");
|
||||
String controllerSignature = helloResponse.trim();
|
||||
|
||||
ConfigurationImage image = linkManager.getConnector().getBinaryProtocol().getControllerConfiguration();
|
||||
String vehicleName = Fields.VEHICLENAME.getStringValue(image);
|
||||
String engineMake = Fields.ENGINEMAKE.getStringValue(image);
|
||||
String engineCode = Fields.ENGINECODE.getStringValue(image);
|
||||
return new ControllerInfo(vehicleName, engineMake, engineCode, controllerSignature);
|
||||
}
|
||||
|
||||
public static class NetworkConnectorResult {
|
||||
static NetworkConnectorResult ERROR = new NetworkConnectorResult(null, 0);
|
||||
private final ControllerInfo controllerInfo;
|
||||
private final int oneTimeToken;
|
||||
|
||||
public NetworkConnectorResult(ControllerInfo controllerInfo, int oneTimeToken) {
|
||||
this.controllerInfo = controllerInfo;
|
||||
this.oneTimeToken = oneTimeToken;
|
||||
}
|
||||
|
||||
public ControllerInfo getControllerInfo() {
|
||||
return controllerInfo;
|
||||
}
|
||||
|
||||
public int getOneTimeToken() {
|
||||
return oneTimeToken;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue