Kotlin netty中的http分块文件传输立即完成

Kotlin netty中的http分块文件传输立即完成,kotlin,netty,chunked-encoding,Kotlin,Netty,Chunked Encoding,我正在编写一个http文件服务器,使用netty以多线程方式下载文件。当只使用HttpServerCodec()时,除了OOM:direct buffer memory error(直接缓冲区内存错误)之外,一切都可以正常工作。然后我转向ChunkedWriteHandler()处理程序 但问题是,浏览器(新边缘)要么说“无法下载文件”,要么下载大小为零的文件。我对此一无所知,需要帮助 日志显示传输过程立即完成,无需任何时间成本 [main] INFO Main - Pick up path C

我正在编写一个http文件服务器,使用
netty
以多线程方式下载文件。当只使用
HttpServerCodec()
时,除了OOM:direct buffer memory error(直接缓冲区内存错误)之外,一切都可以正常工作。然后我转向
ChunkedWriteHandler()
处理程序

但问题是,浏览器(新边缘)要么说“无法下载文件”,要么下载大小为零的文件。我对此一无所知,需要帮助

日志显示传输过程立即完成,无需任何时间成本

[main] INFO Main - Pick up path C:/Temp
[main] INFO dd.oliver.htp.HtpServer - Server start at 2333
[nioEventLoopGroup-3-1] INFO dd.oliver.htp.RequestHandler - Request C:/Temp/d.test.oliverdd
[nioEventLoopGroup-3-1] INFO dd.oliver.htp.RequestHandler - [id: 0xe5ce2ec6, L:/0:0:0:0:0:0:0:1:2333 - R:/0:0:0:0:0:0:0:1:63040] Transfer complete.
这是我的代码,它是指

这是通道初始值设定项:

类HtpChannelInitializer(val basePath:String):ChannelInitializer(){
覆盖通道(通道:SocketChannel){
ch.pipeline().addLast(“HttpCodec”,HttpServerCodec())
ch.pipeline().addLast(“HttpAggregator”,HttpObjectAggregator(65536))
ch.pipeline().addLast(“HttpChunked”,ChunkedWriteHandler())
ch.pipeline().addLast(“RequestHandle”,RequestHandler(basePath))
}
}
这是RequestHandler:

导入io.netty.channel*
导入io.netty.handler.codec.http*
导入io.netty.handler.codec.http.HttpVersion.http\u 1\u 0
导入io.netty.handler.stream.ChunkedFile
导入org.slf4j.LoggerFactory
导入java.io.xml文件
导入java.io.RandomAccessFile
private val logger=LoggerFactory.getLogger(RequestHandler::class.java)
类RequestHandler_测试(val basePath:String):SimpleChannelInboundHandler(){
...
覆盖有趣的channelReadComplete(ctx:ChannelHandlerContext){
ctx.flush()
}
覆盖有趣的channelRead0(ctx:ChannelHandlerContext,msg:HttpRequest){
val path=basePath+msg.uri()//msg.uri()示例:/or/a/b或/a/b/c.txt
logger.info(“请求$path”)
val文件=文件(路径)
if(file.isFile){
val rfile=RandomAccessFile(文件“r”)
//线
val response=DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.OK)
//标题
response.headers().set(“接受范围”、“字节”)
response.headers().set(“内容处置”、“附件;文件名=\”${file.name}\”)
response.headers().set(“内容类型”、“应用程序/八位字节流”)
response.headers().set(“内容长度”,“${rfile.Length()}”)
如果(!(msg.headers()包含(“连接”)和&msg.headers().get(“连接”)=“保持活动状态”)){
response.headers().set(HttpHeaderNames.CONNECTION,HttpHeaderValues.CLOSE);
}else if(msg.protocolVersion()==HTTP\u 1\u 0){
response.headers().set(HttpHeaderNames.CONNECTION,HttpHeaderValues.KEEP_活动);
}
//内容
//response.content().writeBytes(rfile.channel,0L,rfile.length().toInt())
//ctx.writeAndFlush(response.addListener(ChannelFutureListener.CLOSE)
ctx.write(响应)
val sendFileFuture=ctx.write(
HttpChunkedInput(ChunkedFile(rfile,0,rfile.length(),8192)),
ctx.newProgressivePromise()
)
sendFileFuture.addListener(对象:ChannelProgressiveFutureListener{
覆盖操作已进行(
未来:渠道进步未来,
进展:长期,
总数:长
) {
如果(总数<0){//总数未知
logger.info(future.channel().toString()+“传输进度:”+进度)
}否则{
logger.info(
future.channel().toString()+“传输进度:”+进度+“/”+总计
)
}
}
覆盖乐趣操作完成(未来:渠道进步未来){
logger.info(future.channel().toString()+“传输完成”)
}
})
如果(!(msg.headers()包含(“连接”)和&msg.headers().get(“连接”)=“关闭”)){
sendFileFuture.addListener(ChannelFutureListener.CLOSE)
}
}
}
...
}

明白了!波斯特也遇到了同样的问题。是
DefaultFullHttpResponse
导致错误,当更改为
DefaultHttpResponse

时,一切都将是正确的。您是否有可能将此问题简化为更小的问题?有时候,这样做会让你自己解决问题。如果没有,那么如果你能举一个小的例子,你会有更好的机会得到别人的帮助。谢谢@Steve。我已经修改了代码。