2015-08-02 10 views
0

Мне нужно отслеживать подключения отдельных клиентов (записывать, читать байты и скорость (байт в секунду)) в моем простом приложении net-net netty. Как я понимаю, для этого мне нужно использовать ChannelTrafficShapingHandler. Какие методы должны быть преодолены и как я могу выполнять эти вычисления?Расчет записанных и прочитанных байтов в netty-приложении

Мои ChannelInitializer:

public class HttpServerInitializer extends ChannelInitializer<SocketChannel> { 

    @Override 
    protected void initChannel(SocketChannel ch) throws Exception { 
     ChannelPipeline pipeline = ch.pipeline(); 

     pipeline.addLast("codec", new HttpServerCodec()) 
       .addLast("traffic", new TrafficShapingHandler(AbstractTrafficShapingHandler.DEFAULT_CHECK_INTERVAL)) 
       .addLast("handler", new HttpServerHandler()); 
    } 
} 

Мой SimpleChannelInboundHandler:

public class HttpServerHandler extends SimpleChannelInboundHandler<HttpRequest> { 

    private static DefaultChannelGroup activeChannels = new DefaultChannelGroup("netty-receiver", ImmediateEventExecutor.INSTANCE); 

    @Override 
    public void channelActive(ChannelHandlerContext ctx) throws Exception { 
     activeChannels.add(ctx.channel()); 
    } 

    @Override 
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { 
     ctx.flush(); 
    } 

    @Override 
    protected void channelRead0(ChannelHandlerContext ctx, HttpRequest req) throws Exception { 
     if (is100ContinueExpected(req)) { 
      ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE)); 
     } 

     String uri = req.getUri().toLowerCase(); 

     Controller controller = ControllerFactory.getController(uri); 

     FullHttpResponse response = controller.getResponse(); 

     if (controller instanceof HelloController) { 
      ctx.executor().schedule(() -> ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE), 3, TimeUnit.SECONDS); 
     } else { 
      ctx.write(response).addListener(ChannelFutureListener.CLOSE); 
     } 
    } 

    @Override 
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 
     cause.printStackTrace(); 
     ctx.close(); 
    } 

    public static long getConnectionsQuantity() { 
     return activeChannels.size(); 
    } 

} 
+0

Это немного широк. Не могли бы вы добавить некоторые конкретные примеры кода, который вы пробовали, и что не работает/что пошло не так? –

+0

@Topher обновил мое исходное сообщение, добавил код. Теперь я должен реализовать TrafficShapingHandler, чтобы писать, читать байты и скорость (байт в секунду), но не знаю, как это сделать правильно – TMS

ответ

2

@TMS для того, чтобы иметь возможность получить статистику, в первую очередь необходимо выбрать уровень статистики: на канал, глобально или и то, и другое.

  • ChannelTrafficShapingHandler: вы должны создать один элемент для каждого канала (как вы это делали в вашем трубопроводе), он связан с одним и только одним каналом. Статистика относится только к каналу, а не к глобальному.

  • GlobalTrafficShapingHandler: вы должны создать его перед любым каналом и назначить его каждому каналу, как вы это делали, но повторно используя один и тот же объект каждый раз (без перераспределения). Статистические данные являются только глобальными, а не для каждого канала.

  • GlobalChannelTrafficShapingHandler: вы должны создать его перед (как для GlobalTSH) и назначить его каждому каналу (без перераспределения). Статистика является глобальной и для каждого канала.

После того, как вы решили, какой из них для вас, есть в основном два способа получить статистику:

  1. Через доступа к трубопроводу: получение доступа к проводнику и затем:
    • с использованием trafficCounter() метод доступа к объекту TrafficCounter:
      • для канала (только ChannelTSH)
      • для глобального видения (GlobalTSH или GlobalChannelTSH).
    • использованием channelTrafficCounters(), чтобы получить доступ ко всем TrafficCounters для всех активных каналов (GlobalChannelTSH только)
  2. путем расширения базового класса (один из ChannelTSH, GlobalTSH или GlobalChannelTSH) и, в частности метод protected void doAccounting(TrafficCounter counter).

Вы можете посмотреть на одном примере сделано для Нетти, но не импортируется, наконец, в главном потоке, который показывает, как расширить его и использовать его: see here и, в частности, how to extend GlobalChannelTSH или how to include it in your pipeline here.

Конечно, вы можете взглянуть на the API, которые частично объясняют это.

Наконец, если вы хотите иметь как статистические данные для канала и во всем мире, у вас есть выбор:

  • либо использовать GlobalChannelTSH (только один повторно все время), но вы должны сами проверить, какой канал прикрепляется к которому TrafficCounter (с использованием name()) (GlobalChannelTSH в основном намерен ограничить влияние памяти на формирование трафика при выполнении на обоих уровнях, на канал и глобально, но при использовании только для статистики, вероятно, не лучший выбор);
  • либо используют ChannelTSH (поэтому прямой доступ к TrafficCounter на канал) и GlobalTSH (только для глобального TrafficCounter).
+0

большое спасибо за ваш комментарий! – TMS