[denonmarantz] Run the Telnet socket in a dedicated thread (#9511)
* Run the Telnet socket in a dedicated thread, not from the shared thread pool. Fixes #9494 Signed-off-by: Jan-Willem Veldhuis <jwveldhuis@gmail.com>
This commit is contained in:
parent
9d36c31d76
commit
d014ac6350
@ -29,9 +29,9 @@ import org.openhab.binding.denonmarantz.internal.connector.telnet.DenonMarantzTe
|
|||||||
public class DenonMarantzConnectorFactory {
|
public class DenonMarantzConnectorFactory {
|
||||||
|
|
||||||
public DenonMarantzConnector getConnector(DenonMarantzConfiguration config, DenonMarantzState state,
|
public DenonMarantzConnector getConnector(DenonMarantzConfiguration config, DenonMarantzState state,
|
||||||
ScheduledExecutorService scheduler, HttpClient httpClient) {
|
ScheduledExecutorService scheduler, HttpClient httpClient, String thingUID) {
|
||||||
if (config.isTelnet()) {
|
if (config.isTelnet()) {
|
||||||
return new DenonMarantzTelnetConnector(config, state, scheduler);
|
return new DenonMarantzTelnetConnector(config, state, scheduler, thingUID);
|
||||||
} else {
|
} else {
|
||||||
return new DenonMarantzHttpConnector(config, state, scheduler, httpClient);
|
return new DenonMarantzHttpConnector(config, state, scheduler, httpClient);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,9 +31,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
* @author Jeroen Idserda - Initial contribution (1.x Binding)
|
* @author Jeroen Idserda - Initial contribution (1.x Binding)
|
||||||
* @author Jan-Willem Veldhuis - Refactored for 2.x
|
* @author Jan-Willem Veldhuis - Refactored for 2.x
|
||||||
*/
|
*/
|
||||||
public class DenonMarantzTelnetClient implements Runnable {
|
public class DenonMarantzTelnetClientThread extends Thread {
|
||||||
|
|
||||||
private Logger logger = LoggerFactory.getLogger(DenonMarantzTelnetClient.class);
|
private Logger logger = LoggerFactory.getLogger(DenonMarantzTelnetClientThread.class);
|
||||||
|
|
||||||
private static final Integer RECONNECT_DELAY = 60000; // 1 minute
|
private static final Integer RECONNECT_DELAY = 60000; // 1 minute
|
||||||
|
|
||||||
@ -43,8 +43,6 @@ public class DenonMarantzTelnetClient implements Runnable {
|
|||||||
|
|
||||||
private DenonMarantzTelnetListener listener;
|
private DenonMarantzTelnetListener listener;
|
||||||
|
|
||||||
private boolean running = true;
|
|
||||||
|
|
||||||
private boolean connected = false;
|
private boolean connected = false;
|
||||||
|
|
||||||
private Socket socket;
|
private Socket socket;
|
||||||
@ -53,7 +51,7 @@ public class DenonMarantzTelnetClient implements Runnable {
|
|||||||
|
|
||||||
private BufferedReader in;
|
private BufferedReader in;
|
||||||
|
|
||||||
public DenonMarantzTelnetClient(DenonMarantzConfiguration config, DenonMarantzTelnetListener listener) {
|
public DenonMarantzTelnetClientThread(DenonMarantzConfiguration config, DenonMarantzTelnetListener listener) {
|
||||||
logger.debug("Denon listener created");
|
logger.debug("Denon listener created");
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
@ -61,7 +59,7 @@ public class DenonMarantzTelnetClient implements Runnable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while (running) {
|
while (!isInterrupted()) {
|
||||||
if (!connected) {
|
if (!connected) {
|
||||||
connectTelnetSocket();
|
connectTelnetSocket();
|
||||||
}
|
}
|
||||||
@ -90,20 +88,21 @@ public class DenonMarantzTelnetClient implements Runnable {
|
|||||||
connected = false;
|
connected = false;
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (!Thread.currentThread().isInterrupted()) {
|
if (!isInterrupted()) {
|
||||||
// only log if we don't stop this on purpose causing a SocketClosed
|
// only log if we don't stop this on purpose causing a SocketClosed
|
||||||
logger.debug("Error in telnet connection ", e);
|
logger.debug("Error in telnet connection ", e);
|
||||||
}
|
}
|
||||||
connected = false;
|
connected = false;
|
||||||
listener.telnetClientConnected(false);
|
listener.telnetClientConnected(false);
|
||||||
}
|
}
|
||||||
} while (running && connected);
|
} while (!isInterrupted() && connected);
|
||||||
}
|
}
|
||||||
|
disconnect();
|
||||||
|
logger.debug("Stopped client thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendCommand(String command) {
|
public void sendCommand(String command) {
|
||||||
if (out != null) {
|
if (out != null) {
|
||||||
logger.debug("Sending command {}", command);
|
|
||||||
try {
|
try {
|
||||||
out.write(command + '\r');
|
out.write(command + '\r');
|
||||||
out.flush();
|
out.flush();
|
||||||
@ -116,7 +115,6 @@ public class DenonMarantzTelnetClient implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
this.running = false;
|
|
||||||
disconnect();
|
disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,13 +122,14 @@ public class DenonMarantzTelnetClient implements Runnable {
|
|||||||
disconnect();
|
disconnect();
|
||||||
int delay = 0;
|
int delay = 0;
|
||||||
|
|
||||||
while (this.running && (socket == null || !socket.isConnected())) {
|
while (!isInterrupted() && (socket == null || !socket.isConnected())) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(delay);
|
Thread.sleep(delay);
|
||||||
logger.debug("Connecting to {}", config.getHost());
|
logger.debug("Connecting to {}", config.getHost());
|
||||||
|
|
||||||
// Use raw socket instead of TelnetClient here because TelnetClient sends an extra newline char
|
// Use raw socket instead of TelnetClient here because TelnetClient sends an
|
||||||
// after each write which causes the connection to become unresponsive.
|
// extra newline char after each write which causes the connection to become
|
||||||
|
// unresponsive.
|
||||||
socket = new Socket();
|
socket = new Socket();
|
||||||
socket.connect(new InetSocketAddress(config.getHost(), config.getTelnetPort()), TIMEOUT);
|
socket.connect(new InetSocketAddress(config.getHost(), config.getTelnetPort()), TIMEOUT);
|
||||||
socket.setKeepAlive(true);
|
socket.setKeepAlive(true);
|
||||||
@ -141,6 +140,7 @@ public class DenonMarantzTelnetClient implements Runnable {
|
|||||||
|
|
||||||
connected = true;
|
connected = true;
|
||||||
listener.telnetClientConnected(true);
|
listener.telnetClientConnected(true);
|
||||||
|
logger.debug("Denon telnet client connected to {}", config.getHost());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.debug("Cannot connect to {}", config.getHost(), e);
|
logger.debug("Cannot connect to {}", config.getHost(), e);
|
||||||
listener.telnetClientConnected(false);
|
listener.telnetClientConnected(false);
|
||||||
@ -149,8 +149,6 @@ public class DenonMarantzTelnetClient implements Runnable {
|
|||||||
}
|
}
|
||||||
delay = RECONNECT_DELAY;
|
delay = RECONNECT_DELAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("Denon telnet client connected to {}", config.getHost());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isConnected() {
|
public boolean isConnected() {
|
||||||
@ -46,7 +46,7 @@ public class DenonMarantzTelnetConnector extends DenonMarantzConnector implement
|
|||||||
|
|
||||||
private static final BigDecimal NINETYNINE = new BigDecimal("99");
|
private static final BigDecimal NINETYNINE = new BigDecimal("99");
|
||||||
|
|
||||||
private DenonMarantzTelnetClient telnetClient;
|
private DenonMarantzTelnetClientThread telnetClientThread;
|
||||||
|
|
||||||
private boolean displayNowplaying = false;
|
private boolean displayNowplaying = false;
|
||||||
|
|
||||||
@ -54,13 +54,14 @@ public class DenonMarantzTelnetConnector extends DenonMarantzConnector implement
|
|||||||
|
|
||||||
private Future<?> telnetStateRequest;
|
private Future<?> telnetStateRequest;
|
||||||
|
|
||||||
private Future<?> telnetRunnable;
|
private String thingUID;
|
||||||
|
|
||||||
public DenonMarantzTelnetConnector(DenonMarantzConfiguration config, DenonMarantzState state,
|
public DenonMarantzTelnetConnector(DenonMarantzConfiguration config, DenonMarantzState state,
|
||||||
ScheduledExecutorService scheduler) {
|
ScheduledExecutorService scheduler, String thingUID) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
|
this.thingUID = thingUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,8 +69,9 @@ public class DenonMarantzTelnetConnector extends DenonMarantzConnector implement
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void connect() {
|
public void connect() {
|
||||||
telnetClient = new DenonMarantzTelnetClient(config, this);
|
telnetClientThread = new DenonMarantzTelnetClientThread(config, this);
|
||||||
telnetRunnable = scheduler.submit(telnetClient);
|
telnetClientThread.setName("OH-binding-" + thingUID);
|
||||||
|
telnetClientThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -98,9 +100,12 @@ public class DenonMarantzTelnetConnector extends DenonMarantzConnector implement
|
|||||||
telnetStateRequest = null;
|
telnetStateRequest = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (telnetClient != null && !telnetRunnable.isDone()) {
|
if (telnetClientThread != null) {
|
||||||
telnetRunnable.cancel(true);
|
telnetClientThread.interrupt();
|
||||||
telnetClient.shutdown();
|
// Invoke a shutdown after interrupting the thread to close the socket immediately,
|
||||||
|
// otherwise the client keeps running until a line was received from the telnet connection
|
||||||
|
telnetClientThread.shutdown();
|
||||||
|
telnetClientThread = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,7 +267,7 @@ public class DenonMarantzTelnetConnector extends DenonMarantzConnector implement
|
|||||||
logger.warn("Trying to send empty command");
|
logger.warn("Trying to send empty command");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
telnetClient.sendCommand(command);
|
telnetClientThread.sendCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -314,7 +314,8 @@ public class DenonMarantzHandler extends BaseThingHandler implements DenonMarant
|
|||||||
if (connector != null) {
|
if (connector != null) {
|
||||||
connector.dispose();
|
connector.dispose();
|
||||||
}
|
}
|
||||||
connector = connectorFactory.getConnector(config, denonMarantzState, scheduler, httpClient);
|
connector = connectorFactory.getConnector(config, denonMarantzState, scheduler, httpClient,
|
||||||
|
this.getThing().getUID().getAsString());
|
||||||
connector.connect();
|
connector.connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user