附加代码:
参考RxtxChannel进行的实现适配
rxtx活跃性不高。选用了jSerialComm。
1、依赖包:
<dependency> <groupId>com.fazecast</groupId> <artifactId>jSerialComm</artifactId> <version>2.11.0</version> </dependency>
2、核心改造类:SerialPortChannel
public class SerialPortChannel extends OioByteStreamChannel { private static final SerialDeviceAddress LOCAL_ADDRESS = new SerialDeviceAddress("com1"); private final DefaultSerialPortChannelConfig config; private boolean open = true; private SerialDeviceAddress deviceAddress; private SerialPort serialPort; public SerialPortChannel() { super(null); this.config = new DefaultSerialPortChannelConfig(this); } @Override public SerialPortConfig config() { return config; } @Override public boolean isOpen() { return open; } @Override protected AbstractUnsafe newUnsafe() { return new SerialUnsafe(); } @Override protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception { SerialDeviceAddress remote = (SerialDeviceAddress) remoteAddress; this.deviceAddress=remote; this.serialPort=SerialPort.getCommPort(remote.value()); serialPort.setComPortParameters(config().getOption(BAUD_RATE), config().getOption(DATA_BITS).value(), config().getOption(STOP_BITS).value(), config().getOption(PARITY_BIT).value()); serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING,5000,5000); boolean openPort = serialPort.openPort(); if (openPort){ System.out.println("打开串口成功openPort = " + openPort); }else { System.out.println("打开串口失败openPort = " + openPort); } } protected void doInit() throws Exception { System.out.println("doInit "); activate(serialPort.getInputStream(), serialPort.getOutputStream()); } @Override public SerialDeviceAddress localAddress() { return (SerialDeviceAddress) super.localAddress(); } @Override public SerialDeviceAddress remoteAddress() { return this.deviceAddress; } @Override protected SerialDeviceAddress localAddress0() { return LOCAL_ADDRESS; } @Override protected SerialDeviceAddress remoteAddress0() { return this.deviceAddress; } @Override protected void doBind(SocketAddress localAddress) throws Exception { throw new UnsupportedOperationException(); } @Override protected void doDisconnect() throws Exception { doClose(); } @Override protected void doClose() throws Exception { open = false; try { super.doClose(); } finally { if (serialPort != null) { serialPort.closePort(); serialPort = null; } } } @Override protected boolean isInputShutdown() { return !open; } @Override protected ChannelFuture shutdownInput() { return newFailedFuture(new UnsupportedOperationException("shutdownInput")); } private final class SerialUnsafe extends AbstractUnsafe { @Override public void connect( final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) { if (!promise.setUncancellable() || !ensureOpen(promise)) { return; } try { final boolean wasActive = isActive(); doConnect(remoteAddress, localAddress); int waitTime = config().getOption(WAIT_TIME); if (waitTime > 0) { eventLoop().schedule(new Runnable() { @Override public void run() { try { doInit(); safeSetSuccess(promise); if (!wasActive && isActive()) { pipeline().fireChannelActive(); } } catch (Throwable t) { safeSetFailure(promise, t); closeIfClosed(); } } }, waitTime, TimeUnit.MILLISECONDS); } else { doInit(); safeSetSuccess(promise); if (!wasActive && isActive()) { pipeline().fireChannelActive(); } } } catch (Throwable t) { safeSetFailure(promise, t); closeIfClosed(); } } } }
3、DefaultSerialPortChannelConfig:
public class DefaultSerialPortCha