Java Vert.x在垂直线之间发送NetSocket

Java Vert.x在垂直线之间发送NetSocket,java,sockets,vert.x,Java,Sockets,Vert.x,我正在使用Vert.x创建一个简单的TCP服务器,数据以压缩包的形式在客户端和服务器之间发送 我想使用垂直线来创建这种性质的东西(其中[something]是垂直线,箭头显示数据流): 问题是我不确定如何将NetSocket从一个垂直页面(从解压数据包的结果)传送到下一个垂直页面。当然,我可以将解压数据包的结果发送到解析数据包垂直链接,但当解析数据包垂直链接收到此数据时,它将没有任何句柄来使用它对发送方的引用回复NetSocket 本质上,我需要通过事件总线携带NetSocket,这样一旦到达最

我正在使用Vert.x创建一个简单的TCP服务器,数据以压缩包的形式在客户端和服务器之间发送

我想使用垂直线来创建这种性质的东西(其中
[something]
是垂直线,箭头显示数据流):

问题是我不确定如何将NetSocket从一个垂直页面(从
解压数据包的结果
)传送到下一个垂直页面。当然,我可以将
解压数据包的结果发送到
解析数据包
垂直链接,但当
解析数据包
垂直链接收到此数据时,它将没有任何句柄来使用它对发送方的引用回复NetSocket


本质上,我需要通过事件总线携带NetSocket,这样一旦到达最终的垂直链接,它就可以回复数据。

正如在评论中所说的,您可能需要一组处理程序而不是垂直链接。例如,看看处理程序是如何工作的。处理程序是一个简单的lambda,它执行一个小任务,可以决定将工作传递给下一个任务,或者调用失败方法中止执行

一个非常基本的实现就是保留一个添加的lambda(Java函数接口)列表,一旦收到套接字,就迭代该列表

如果需要在处理程序中执行异步IO,则不能使用需要异步执行的简单迭代器,基本异步迭代器包装器可以是:

abstract class AsyncIterator<T> implements Handler<T> {

  private final Iterator<T> iterator;
  private boolean end = false;

  public AsyncIterator(Iterable<T> iterable) {
    this(iterable.iterator());
  }

  public AsyncIterator(Iterator<T> iterator) {
    this.iterator = iterator;
    next();
  }

  public final boolean hasNext() {
    return !end;
  }

  public final void next() {
    if (iterator.hasNext()) {
      handle(iterator.next());
    } else {
      end = true;
      handle(null);
    }
  }

  public final void remove() {
    iterator.remove();
  }
}
抽象类AsyncIterator实现处理程序{
私有最终迭代器;
私有布尔结束=false;
公共异步迭代器(Iterable Iterable){
这个(iterable.iterator());
}
公共异步迭代器(迭代器迭代器){
this.iterator=迭代器;
next();
}
公共最终布尔值hasNext(){
返回!结束;
}
公开最终作废下一次(){
if(iterator.hasNext()){
句柄(iterator.next());
}否则{
结束=真;
句柄(空);
}
}
公开最终作废删除(){
iterator.remove();
}
}
你只需要像这样使用它:

new AsyncIterator<Object>(keys) {
    @Override
    public void handle(Object key) {
      if (hasNext()) {
        // here your handler code...
        // once it is complete your handler need to call:
        next();
      } else {
        // no more entries to iterate...
        // close your socket?
      }
    }
  };
});
新的异步迭代器(键){
@凌驾
公共无效句柄(对象键){
if(hasNext()){
//这里是您的处理程序代码。。。
//完成后,处理程序需要调用:
next();
}否则{
//没有更多要迭代的条目。。。
//合上你的插座?
}
}
};
});

实际上,您不必在顶点之间传递NetSocket

在Vert.x中,每个套接字自动注册事件处理程序,您可以在场景中使用它。检查文件:

每个套接字自动在事件总线上注册一个处理程序,当在该处理程序中接收到任何缓冲区时,它会将它们写入自身

这使您能够通过将缓冲区发送到处理程序的地址,将数据写入可能位于完全不同的verticle甚至不同的Vert.x实例中的套接字

处理程序的地址由writeHandlerID提供

由于writeHandlerID是一个普通字符串,所以从verticle1将其发送到verticle2并不是什么大问题。在verticle2中,eventbus.send(writeHandlerID,[您想要回复的内容])。就这样


我们已经在应用程序中应用了此技巧。

如果您真的需要将此技巧拆分为多个竖线,请思考一下?有人会像创建层/类一样创建垂直链接,但这会带来额外的管理和性能损失。从中学到这一点后,我现在使用一个Verticle引导一个微服务,并对结果感到满意。如果它只是接受一个TCP连接并进行一些数据转换,我相信一个Verticle就足够了。嗯,好的,谢谢。事实上,这很有用。在我的脑海中,我认为更多的垂直物将有助于将负载分散到机器上。有没有类似于Netty的ByteBuf的产品?我希望一次只遍历一个数据类型的缓冲区,而不希望创建包装器。如果您在追求并行性,您可以创建同一垂直体的多个实例,这将允许您将工作分散到多个核心上。看见
new AsyncIterator<Object>(keys) {
    @Override
    public void handle(Object key) {
      if (hasNext()) {
        // here your handler code...
        // once it is complete your handler need to call:
        next();
      } else {
        // no more entries to iterate...
        // close your socket?
      }
    }
  };
});