如何在其他类中读取netty中的消息

时间:2016-01-24 15:20:03

标签: java netty

我想在InboundHandler以外的类中的特定位置阅读消息。我无法在channelRead0方法中找到一种方法来读取它,这种方法是从netty框架调用的。

例如:

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

如果无法做到这一点,我如何将channelRead0方法中的结果映射到我在另一个类中进行的特定调用?

1 个答案:

答案 0 :(得分: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

中的问题