我写了一个NIO.2 http客户端。当读取响应时,可能没有收到完整的响应,所以一旦我在字节缓冲区上获得内容长度标题,我就知道剩下多少,所以我使用它或读取直到完成处理程序告诉我我有0个字节。简化问题我正在使用CompletionHandler
public void completed(Integer result, ClientSession clientSession) {
final ByteBuffer buffer = clientSession.getBuffer();
final ResponseParser responseParser = clientSession.getResponseParser();
buffer.flip();
if (responseParser.parse(buffer)) {
final HttpResponse httpResponse = responseParser.httpResponse();
doStuff(httpResponse);
buffer.clear();
} else {
clientSession.getChannel().read(buffer, clientSession, this);
}
}
如果读取的响应不完整,则通道上的读取将返回到相同的完成处理程序,并且该过程将递归直到完成。显示的完成处理程序在前面的http请求写入中指定,例如
clientSession.getChannel().write(buffer, clientSession, new ReadHandler())
一切正常,直到我加载负载并得到ReadPendingException。我的理解是,只要在完成处理程序中执行的读/写操作不超过1次,就不会发生这种情况。我的错是什么?
答案 0 :(得分:0)
您必须实现一个缓冲区队列并等待读取完成。如果队列不为空,则使用 poll() 获取缓冲区。您必须定义一个标志(忙)来监视读取操作的状态。可能您还必须实现与缓冲区元素相关的 clientSession 队列。对写操作做同样的事情。
private Queue<ByteBuffer> input = new LinkedList<>();
...
try {
clientSession.getChannel().read(buffer, clientSession, this);
}catch(ReadPendingException ex) {
input.add(buffer);
busy= true;
}
...