我正在尝试使用 CompletionHandler 而不是 Futures 在 vert.x 工作线程中的 AsynchronousSocketChannel 上实现单个请求/响应。来自 vert.x 文档:
“Worker Verticle 永远不会被多个线程同时执行。”
所以这是我的代码(不确定我是否 100% 正确处理了套接字 - 请发表评论):
// ommitted: asynchronousSocketChannel.open, connect ...
eventBus.registerHandler(address, new Handler<Message<JsonObject>>() {
@Override
public void handle(final Message<JsonObject> event) {
final ByteBuffer receivingBuffer = ByteBuffer.allocateDirect(2048);
final ByteBuffer sendingBuffer = ByteBuffer.wrap("Foo".getBytes());
asynchronousSocketChannel.write(sendingBuffer, 0L, new CompletionHandler<Integer, Long>() {
public void completed(final Integer result, final Long attachment) {
if (sendingBuffer.hasRemaining()) {
long newFilePosition = attachment + result;
asynchronousSocketChannel.write(sendingBuffer, newFilePosition, this);
}
asynchronousSocketChannel.read(receivingBuffer, 0L, new CompletionHandler<Integer, Long>() {
CharBuffer charBuffer = null;
final Charset charset = Charset.defaultCharset();
final CharsetDecoder decoder = charset.newDecoder();
public void completed(final Integer result, final Long attachment) {
if (result > 0) {
long p = attachment + result;
asynchronousSocketChannel.read(receivingBuffer, p, this);
}
receivingBuffer.flip();
try {
charBuffer = decoder.decode(receivingBuffer);
event.reply(charBuffer.toString()); // pseudo code
} catch (CharacterCodingException e) { }
}
public void failed(final Throwable exc, final Long attachment) { }
});
}
public void failed(final Throwable exc, final Long attachment) { }
});
}
});
我在负载测试期间遇到了很多 ReadPendingException 和 WritePendingException,如果在句柄方法中一次真的只有一个线程,这似乎有点奇怪。如果一次只有 1 个线程与 AsynchronousSocketChannel 一起工作,怎么可能读取或写入尚未完全完成?