[英]Netty TCP Socket InputStream
Netty TCP Server正在端口8000
上运行,接收NMEA
格式的数据。 它使用Marine API库将乱码转换为有意义的信息,需要从套接字输入流。
SentenceReader sentenceReader = new SentenceReader(socket.getInputStream());
sentenceReader.addSentenceListener(new MultiSentenceListener());
sentenceReader.start();
如何获取正在使用的Netty服务器端口的输入流?
由于InputStream正在阻止,而netty是异步-非阻止API,因此您不容易。
SentenceReader
没有任何方法可以接受“流入”数据,但是通过子类化,可以使其接受数据。
SentenceReader
的核心使用DataReader
来处理其数据,通常是从单独的线程SentenceReader
本身轮询此DataReader
,我们可以修改此结构以获取所需的内容。
首先,我们用自己的类将SentenceReader
子类化,为它提供所需的适当构造函数和方法,并消除start和stop方法的影响。 我们现在提供null
作为文件(并希望将来的版本提供一种直接传递数据读取器的方法)
public class NettySentenceReader extends SentenceReader {
public NettySentenceReader () {
super((InputStream)null);
}
@Override
public void start() {
}
@Override
public void stop() {
}
}
现在,我们需要在自己的Netty处理程序中实现内部类DataReader
所有功能,以复制相同的行为
public class SentenceReaderHandler extends
SimpleChannelInboundHandler<String> {
private SentenceFactory factory;
private SentenceReader parent;
public SentenceReaderHandler (SentenceReader parent) {
this.parent = parent;
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) {
if(!ctx.channel().isActive())
return;
//ActivityMonitor monitor = new ActivityMonitor(parent);
this.factory = SentenceFactory.getInstance();
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
//ActivityMonitor monitor = new ActivityMonitor(parent);
this.factory = SentenceFactory.getInstance();
}
@Override
// This method will be renamed to `messageReceived` in Netty 5.0.0
protected void channelRead0(ChannelHandlerContext ctx, String data)
throws Exception {
if (SentenceValidator.isValid(data)) {
monitor.refresh();
Sentence s = factory.createParser(data);
parent.fireSentenceEvent(s);
} else if (!SentenceValidator.isSentence(data)) {
parent.fireDataEvent(data);
}
}
@Override
public void channelInactive(ChannelHandlerContext ctx) {
//monitor.reset();
parent.fireReadingStopped();
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) {
if(!ctx.channel().isActive())
return;
//monitor.reset();
parent.fireReadingStopped();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) {
parent.handleException("Data read failed", e);
}
}
最后,我们需要将其集成到Netty管道中:
SentenceReader reader = new NettySentenceReader();
bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
private static final StringDecoder DECODER = new StringDecoder();
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast(DECODER);
pipeline.addLast(new SentenceReaderHandler(reader));
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.