
io.muserver.PreReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mu-server Show documentation
Show all versions of mu-server Show documentation
A simple but powerful web server framework
The newest version!
package io.muserver;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;
/**
* This pre-emptively reads a message from the channel before the HTTP handler has actually asked for it.
* The reason for this is to force more time waiting on a read at the NIO channel, and therefore detect
* client disconnections. If there is a better way, it may be revealed here: https://stackoverflow.com/questions/66075288/detecting-closed-channels-when-auto-read-is-false-in-netty-4
*/
class PreReader extends ChannelDuplexHandler {
private Object pendingMsg;
private boolean wantsToRead = false;
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
ctx.channel().config().setAutoRead(false);
ctx.read();
super.handlerAdded(ctx);
}
private void sendItMaybe(ChannelHandlerContext ctx) {
if (wantsToRead) {
Object msg = this.pendingMsg;
if (msg != null) {
this.pendingMsg = null;
this.wantsToRead = false;
ctx.fireChannelRead(msg);
ReferenceCountUtil.release(msg);
ctx.read();
}
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
// A message is available. Set it as pending but only forward to the mu handler if a read
// has been requested.
ReferenceCountUtil.retain(msg);
pendingMsg = msg;
sendItMaybe(ctx);
}
@Override
public void read(ChannelHandlerContext ctx) throws Exception {
// The mu handler wants to read. Send it the pending message if it's there; otherwise wait
wantsToRead = true;
ctx.executor().submit(() -> sendItMaybe(ctx));
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
if (pendingMsg != null) {
ReferenceCountUtil.release(pendingMsg);
ctx.fireChannelRead(pendingMsg); // without this, a reference is leaked
pendingMsg = null;
}
super.channelUnregistered(ctx);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy