Прежде всего, извините за мой кривой английский:)
У меня возникли некоторые проблемы во время записи http-сервера Netty, который отправляет / получает большие файлы (~ 2 ГБ).И я был бы очень признателен, если бы кто-нибудь помог или объяснил.
Мое клиентское приложение (веб-браузер) отправляет файлы через XMLHttpRequest следующим образом:
var sampleFile = document.getElementById("sampleFile").files[0]; //chosen file by <input type="file" .../>
var xhr = new XMLHttpRequest();
xhr.open("POST","http://127.0.0.1:8091/upload/some_file_name.txt", true);
xhr.send(sampleFile);
На стороне сервера:
Класс WebSocketServer:
ServerBootstrap bootstrapHttp = new ServerBootstrap(
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
bootstrapHttp.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() {
ChannelPipeline pipeline = pipeline();
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("aggregator", new HttpChunkAggregator(1024*1024*1024));
pipeline.addLast("encoder", new HttpResponseEncoder());
pipeline.addLast("deflater", new HttpContentCompressor());
pipeline.addLast("handler", new HttpRequestServerHandler());
return pipeline;
}
});
bootstrapHttp.bind(new InetSocketAddress(port));
Класс HttpRequestServerHandler:
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
Object msg = e.getMessage();
if (msg instanceof HttpRequest) {
HttpRequest req = (HttpRequest)msg;
if (req.getMethod() != POST) {
return;
}
if (decodedURI.startsWith(UPLOAD_FILE_PATH)) {
HttpRequest request = (HttpRequest) e.getMessage();
RandomAccessFile raf = new RandomAccessFile("foobar.tmp", "rw");
ChannelBuffer buf = request.getContent();
FileChannel fChannel = raf.getChannel();
Channel msgChannel= e.getChannel();
fChannel.write( buf.toByteBuffer() );
raf.close();
fChannel.close();
msgChannel.close();
}
}
При отправке файла среднего размера все работает замечательно.Проблема с большими файлами (> 300 МБ).После некоторого времени обработки возникает исключение:
java.lang.OutOfMemoryError: пространство кучи Java в org.jboss.netty.buffer.HeapChannelBuffer. (HeapChannelBuffer.java:47) в org.jboss.netty.buffer.BigEndianHeapChannelBuffer. (BigEndianHeapChannelBuffer.java:39) в org.jboss.netty.buffer.ChannelBuffers.buffer (ChannelBuffers.java:139) в org.jboss.netty.buffer (HeffBuber)org.jboss.netty.buffer.DynamicChannelBuffer.ensureWritableBytes (DynamicChannelBuffer.java:84) в org.jboss.netty.buffer.DynamicChannelBuffer.writeBytes (DynamicChannelBuffer.java:2ffss.ffava.b.buy.bu.by.by.by.by.by.bject.bb.bb) orgAbstractChannelBuffer.java:457) в org.jboss.netty.buffer.AbstractChannelBuffer.writeBytes (AbstractChannelBuffer.java:450) в org.jboss.netty.handler.codec.http.HttpChunkAggregator.mett40_harget_RegRegChateRegReader_jtgRegCat.jboss.netty.channel.Channels.fireMessageReceived (Channels.java:302) в org.jboss.netty.handler.codec.replay.ReplayingDecoder.unfoldAndFireMessageReceived (ReplayingDecoder.java:522) в org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode (ReplayingDecoder.java:50j.codec.replay.ReplayingDecoder.messageReceived (ReplayingDecoder.java:443) в org.jboss.netty.channel.Channels.fireMessageReceived (Channels.java:274) в org.jboss.netty.channel.Channels.fireMessageReavad Channels.261) at org.jboss.netty.channel.socket.nio.NioWorker.read (NioWorker.java:351)
Он даже не доходит до моего обработчика сообщений, полученных.Как я могу предположить, некоторый внутренний ChannelBuffer переполнен.Я пытался увеличить параметр HttpChunkAggregator (1024 *1024* 1024).Однако это бы не помогло.Я вижу только одно решение - разделить файл на стороне клиента (используя html5), отправить эти куски и вставить их вместе на сервер.Но это кажется довольно сложным.Есть ли какой-нибудь более простой способ исправить это (в области Netty)?
Спасибо!С наилучшими пожеланиями.