Я перехожу с raw NIO на netty. Ответ, который мне нужно отправить обратно, выглядит следующим образом
short
long
long
long
file
У меня есть следующий рабочий пример, и мне было интересно, как переместить FileRegion в кодировщик.
MessageToByteEncoder
@Override
protected void encode(final ChannelHandlerContext ctx, final BlockResponse msg,
final ByteBuf out) throws Exception {
out.writeShort(DataServerMessage.DATA_SERVER_RESPONSE_MESSAGE);
out.writeLong(msg.getBlockId());
out.writeLong(msg.getOffset());
out.writeLong(msg.getLength());
}
ChannelInboundHandlerAdapter
ctx.write(new BlockResponse(blockId, offset, readLength));
FileChannel channel = closer.register(file.getChannel());
ChannelFuture future = ctx.writeAndFlush(new DefaultFileRegion(channel, offset, readLength));
future.addListener(ChannelFutureListener.CLOSE);
Я думаю, что если бы я написал в адаптере для ответа writeAndFlush (и поместил туда файл), то я мог бы сделать еще один writeAndFlush в кодировщике, но тогда кодировщик должен был бы закрыть его. Есть другой способ?
Благодарность!
РЕДАКТИРОВАТЬ:
Вот обновленный код, который работает:
public static final class Encoder extends MessageToMessageEncoder<BlockResponse> {
private static final int HEADER_LENGTH = 2 + 4 * 3; // short, 3 longs
@Override
protected void encode(final ChannelHandlerContext ctx, final BlockResponse msg,
final List<Object> out) throws Exception {
out.add(createHeader(ctx, msg));
if (msg.getChannel() != null) {
out.add(new DefaultFileRegion(msg.getChannel(), msg.getOffset(), msg.getLength()));
}
}
private ByteBuf createHeader(final ChannelHandlerContext ctx, final BlockResponse msg) {
ByteBuf header = ctx.alloc().buffer(HEADER_LENGTH);
header.writeShort(DataServerMessage.DATA_SERVER_RESPONSE_MESSAGE);
header.writeLong(msg.getBlockId());
header.writeLong(msg.getOffset());
header.writeLong(msg.getLength());
return header;
}
}
ChannelInboundHandlerAdapter
ChannelFuture future =
ctx.writeAndFlush(new BlockResponse(blockId, offset, readLength, channel));
future.addListener(ChannelFutureListener.CLOSE);
future.addListener(new ClosableResourceChannelListener(file));
1 ответ
Если вам нужно также запустить FileRegion из кодировщика, вам нужно использовать MessageToMessageEncoder и выделить ByteBuf своим собственным внутри там.
Похожие вопросы
Новые вопросы
netty
Платформа с открытым исходным кодом для асинхронных событий, управляемая сетью, написанная на Java. Это клиент-серверная инфраструктура NIO, которая позволяет быстро и легко разрабатывать сетевые приложения, такие как серверы протоколов и клиенты.