package com.lefu.remote.netty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.lefu.remote.netty.blocking.BlockingRead;
import com.lefu.remote.netty.blocking.DefaultBlockingRead;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.Attribute;
/**
* 为阻塞读提供的业务句柄适配类
* @author jiang.li
*
*/
public abstract class BlockingReadHandlerAdapter extends ChannelInboundHandlerAdapter {
private final Logger log = LoggerFactory.getLogger(getClass());
private ChannelHandlerFactory channelHandlerFactory;
public BlockingReadHandlerAdapter() {
}
public BlockingReadHandlerAdapter(ChannelHandlerFactory channelHandlerFactory) {
this.channelHandlerFactory = channelHandlerFactory;
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
if (channelHandlerFactory == null) {
throw new NullPointerException("ChannelHandlerFactory is null, you show set it in your InboundHandler");
}
if (channelHandlerFactory.isBlockingRead()) {
Attribute<BlockingRead> r = ctx.channel().attr(BlockingRead.CHANNEL_BLOCKING_READ_KEY);
r.set(new DefaultBlockingRead(ctx, channelHandlerFactory.getTimeout()));
log.warn("Blocking read is enabled, do not use it in server handler.");
}
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
if (channelHandlerFactory.isBlockingRead()) {
Attribute<BlockingRead> r = ctx.channel().attr(BlockingRead.CHANNEL_BLOCKING_READ_KEY);
r.get().clear();
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (channelHandlerFactory.isBlockingRead()) {
Attribute<BlockingRead> r = ctx.channel().attr(BlockingRead.CHANNEL_BLOCKING_READ_KEY);
if (r.get() == null) {
throw new NullPointerException("ChannelHandlerFactory is not allow blocking read or channelRegistered was overrided ?");
}
((DefaultBlockingRead)r.get()).put(msg);
}
doRead(ctx, msg);
}
protected abstract void doRead(ChannelHandlerContext ctx, Object msg) throws Exception;
public ChannelHandlerFactory getChannelHandlerFactory() {
return channelHandlerFactory;
}
public void setChannelHandlerFactory(ChannelHandlerFactory channelHandlerFactory) {
this.channelHandlerFactory = channelHandlerFactory;
}
}