2017-11-18 9 views
1

Netty TCP 서버가 형식 데이터를 수신하는 8000 포트에서 실행 중입니다. Marine API 라이브러리를 사용하여 횡설수설을 소켓에서 입력 스트림을 필요로하는 의미있는 정보로 변환합니다.Netty TCP 소켓 InputStream

SentenceReader sentenceReader = new SentenceReader(socket.getInputStream()); 
sentenceReader.addSentenceListener(new MultiSentenceListener()); 
sentenceReader.start(); 

어떻게 Netty 서버 포트를 사용할 수 있습니까?

답변

1

SentenceReader에는 "스트림 된"데이터를 수락 할 수있는 방법이 없지만 서브 클래 싱을 사용하면 데이터를 수락 할 수 있습니다.

SentenceReader의 핵심은 일반적으로이 DataReader를이 별도의 스레드 SentenceReader 자체에서 폴링 데이터를위한 DataReader를 사용하여, 우리는 우리가 필요로하는 것을 얻기 위해이 구조를 수정할 수 있습니다.

먼저 우리 자신의 클래스로 SentenceReader을 서브 클래스 화하고 적절한 생성자와 메소드를 제공하고 시작 및 중지 메소드의 효과를 제거하십시오. 우리는 지금 파일로 null를 제공 (향후 버전 직접에서 DataReader를 통과하는 방법을 제공 희망) 우리는 지금 우리 자신의 Netty 핸들러 내부에 내부 클래스 DataReader의 모든 기능을 구현해야

public class NettySentenceReader extends SentenceReader { 
    public NettySentenceReader() { 
     super((InputStream)null); 
    } 

    @Override 
    public void start() { 
    } 

    @Override 
    public void stop() { 
    } 
} 

을 복제하기 !

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)); 
    } 
}); 
+0

'경우 (ctx.isAc : 같은 동작

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 파이프 라인으로이를 통합하는 데 필요한 tive())'isActive() 메서드가 존재하지 않습니다. –

+0

fireSentenceEvent (net.sf.marineapi.nmea.sentence.Sentence) '가'net.sf.marineapi.nmea.io.SentenceReader '에 public이 아닙니다. 외부 패키지 –

+0

에서 액세스 할 수없는 경우 해당 메소드에 액세스 할 수없는 경우 리플렉션을 사용하여 해당 메소드에 대한 액세스 권한을 강제로 가져야하지만 오늘은 내일 할 것이라고 설명 할 시간이 없습니다 – Ferrybig

1

InputStream이 차단 중이며 Netty가 비동기 - 비 차단 API이기 때문에 쉽게 연결할 수 없습니다.