2016-01-24 70 views
1

我想读取InboundHandler以外的班级中的特定位置的消息。我找不到在channelRead0方法中读取它的方法,该方法在netty框架中调用。如何阅读在其他班级的网络中的消息

例如:

context.writeMessage("message"); 
String msg = context.readMessage; 

如果这是不可能的,我怎么能映射的结果,这是我在channelRead0方法得到我在另一个班级做了具体的电话吗?

回答

2

Netty框架被设计为异步驱动。使用这种类比,它可以处理大量的连接,并且只需最少的线程使用。我正在创建一个使用netty框架来调用远程位置的api,您应该对您的调用使用相同的类比。

而不是让您的API直接返回值,使其返回Future<?>Promise<?>。在您的应用程序中实现此系统有不同的方法,最简单的方法是创建一个自定义处理程序,将传入的请求映射到FIFO队列中的Promise

这方面的例子可能是以下几点:

这在很大程度上基于我在过去提交this答案。

我们开始了处理这些请求映射到我们的管道请求:

public class MyLastHandler extends SimpleInboundHandler<String> { 
    private final SynchronousQueue<Promise<String>> queue; 

    public MyLastHandler (SynchronousQueue<Promise<String>> queue) { 
     super(); 
     this.queue = queue; 
    } 

    // The following is called messageReceived(ChannelHandlerContext, String) in 5.0. 
    @Override 
    public void channelRead0(ChannelHandlerContext ctx, String msg) { 
     this.queue.remove().setSuccss(msg); 
     // Or setFailure(Throwable) 
    } 
} 

然后,我们需要有发送命令到远程服务器的方法:

Channel channel = ....; 
SynchronousQueue<Promise<String>> queue = ....; 

public Future<String> sendCommandAsync(String command) { 
    return sendCommandAsync(command, new DefaultPromise<>()); 
} 

public Future<String> sendCommandAsync(String command, Promise<String> promise) { 
    synchronized(channel) { 
     queue.offer(promise); 
     channel.write(command); 
    } 
    channel.flush(); 
} 

在完成我们的方法之后,我们需要一种方法来调用它:

sendCommandAsync("USER anonymous", 
    new DefaultPromise<>().addListener(
     (Future<String> f) -> { 
      String response = f.get(); 
      if (response.startWidth("331")) { 
       // do something 
      } 
      // etc 
     } 
    ) 
); 

如果被叫想用我们的一个API作为一个阻塞调用,他也能做到这一点:

String response = sendCommandAsync("USER anonymous").get(); 
if (response.startWidth("331")) { 
    // do something 
} 
// etc 

注意Future.get()可以抛出InterruptedException如果线程状态中断,不像一个套接字读操作,谁也只能通过套接字上的一些交互取消。这个例外在FutureListener中不应该是个问题。