当前位置: 首页 > 知识库问答 >
问题:

具有异步调用方的Netty同步客户端

越姚石
2023-03-14

我正在创建一个服务器,该服务器使用来自许多来源的命令,例如JMS,SNMP,HTTP等。这些都是异步的,并且工作正常。服务器维护与单个传统硬件项目的单个连接,该项目具有具有自定义TCP协议的请求/应答体系结构。理想情况下,我想要一个像这样的阻塞类型方法的命令

public Response issueCommandToLegacyHardware(Command command)

或者这个异步类型的方法

public Future<Response> issueCommandToLegacyHardware(Command command)

我对Netty和异步编程比较陌生,基本上是边学边学。我目前的想法是,我的LegacyHardwareClient类将具有公共同步问题CommandToLegacy硬件(命令命令)

这太复杂了吗?我可以看看关于同步Netty客户端实现的例子吗?Netty有什么最佳实践吗?显然,我可以只使用标准的Java套接字,但是Netty解析自定义协议的能力以及易维护性太强了,无法放弃。

更新:只是关于实现,我使用了数组块队列

offer()和remove()对我不起作用的原因是,如果对方没有主动阻塞take()请求,offer(”命令将不会传递任何内容。相反,remove()不会返回任何内容,除非存在插入数据的阻塞put()调用。我无法使用put()/remove(),因为无法访问remove。由于尚未执行take()调用,所以offer()语句将返回false,因此我无法使用offer(()/take()。使用ArrayBlockingQueue

共有1个答案

王亮
2023-03-14

而不是使用SynchronousQueue以阻塞方式设计您的应用程序

您的公共未来

这一点的快速实现可能是:

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

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

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

上述处理程序应该放在链的最后。

公共未来的实施

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

public Future<Response> issueCommandToLegacyHardware(Command command) {
    return issueCommandToLegacyHardware(command, channel.eventLoop().newPromise());
}

public Future<Response> issueCommandToLegacyHardware(Command command, Promise<Response> promise) {
    queue.offer(promise);
    channel.write(command);
    return promise;
}

使用重载的方法也是用于Channel.write的设计模式,这使得它非常灵活。

此设计模式可在客户端代码中使用如下:

issueCommandToLegacyHardware(
    Command.TAKE_OVER_THE_WORLD_WITH_FIRE, 
    channel.eventLoop().newPromise()
).addListener(
    (Future<Response> f) -> {
        System.out.println("We have taken over the world: " + f.get());
    }
);

这种设计模式的优点是,任何地方都不会使用不必要的阻塞,只使用简单的异步逻辑。

附录一:Javadoc:

promise未来违约promise

 类似资料:
  • 我正在尝试创建一个基于网络的网络客户端。我根据网络站点中给出的示例编写了代码。但问题是,响应是由客户端处理程序处理的 我做的一件事是在HttpTarget中创建一个setResponse()方法 因此,基本上我想同步进行,即在HttpSnoopClient中发送一个请求(channel.writeandFlush(req)),然后等待,直到HttpSnoopCLientHandler收到响应 谁能

  • 同步调用异步方法最安全的方法是什么?

  • 我正在构建一个tcp客户端来接收和发送消息。我按照Netty用户指南中的步骤编写了一个简单的tcp客户端,其中包含一个扩展的自定义处理程序。 在hander中,我存储了< code > ChannelHandlerContext : 然后我有一个发送方法,它使用发送消息: 我发现的另一个选项是在客户机类中使用

  • 我正试图从同步方法运行异步方法。但是我不能等待异步方法,因为我在同步方法中。我一定不理解TPL,因为这是我第一次使用它。 每个方法都需要前一个方法来完成,因为第一个方法的数据用于第二个方法。 Await运算符只能在异步方法中使用。考虑用'async'修饰符标记此方法,并将其返回类型更改为'task' 但是,如果我使用async修饰符,这将是一个异步操作。因此,如果我对的调用没有使用await运算符

  • 我正在尝试将我的应用程序从apache http组件客户端切换到异步版本。目标是能够处理更多的出站连接(在不久的将来)。请求的负载非常小( 与同步版本的apache超文本传输协议客户端,通过把大约200请求/秒。平均响应时间约为100ms/请求。我在最大180ms后中止请求。 切换到异步后,响应时间增加了20ms/请求。吞吐量也降低到160/秒。中止的请求数量增加了一倍。 这是在对应用程序进行了很

  • 问题内容: 在过去的几个小时中,我一直在努力解决这个问题,但无法解决。我想我仍然必须习惯于函数式编程风格;) 我写了一个递归函数,它遍历目录结构并对某些文件进行处理。此功能使用异步IO方法。现在,我要在完成整个遍历后执行一些操作。 如何确保在执行完所有调用但仍使用异步IO功能后执行此操作? 问题答案: 查找“ 步骤”模块。它可以链接异步函数调用,并将结果从一个传递到另一个。