Netty統(tǒng)計(jì)連接數(shù)
思路
netty如何統(tǒng)計(jì)當(dāng)前的連接數(shù)?
當(dāng)有連接接入netty server的時(shí)候,ChannelInboundHandlerAdapter中就會調(diào)用regiser和active方法。我們只需要在這里對計(jì)數(shù)器遞增即可。
同時(shí)當(dāng)有連接斷開(客戶端程序手動斷開的時(shí)候,客戶端異常斷開不會完成四次揮手,服務(wù)端沒法立刻判斷客戶端是否離開), ChannelInboundHandlerAdapter中會調(diào)用unregisert和inactive方法,我們需要在這里對計(jì)數(shù)器進(jìn)行遞減即可。
注意點(diǎn)
1 例子中的NettyConnectServerHandler不是sharedable的,每次都需要new來創(chuàng)建。
所以統(tǒng)計(jì)的變量應(yīng)該是傳入的參數(shù)。
2 保證多線程的時(shí)候統(tǒng)計(jì)變量不會出現(xiàn)問題,使用AtomicInteger來保證。
核心代碼
public class NettyConnectServerHandler extends ChannelInboundHandlerAdapter {
private AtomicInteger connectNum;
public NettyConnectServerHandler(AtomicInteger connectNum) {
this.connectNum = connectNum;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf in = (ByteBuf) msg;
try {
while (in.isReadable()) { // (1)
System.out.print((char) in.readByte());
System.out.flush();
}
} finally {
ReferenceCountUtil.release(msg); // (2)
}
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
super.channelRegistered(ctx);
if (connectNum.incrementAndGet() % 100 == 0) {
System.out.println("current connected" + connectNum.get());
}
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
super.channelUnregistered(ctx);
if (connectNum.decrementAndGet() % 100 == 0) {
System.out.println("current connected" + connectNum.get());
}
}
}