如何在Netty 4+;中使用ChannelTrafficShapingHandler;?

如何在Netty 4+;中使用ChannelTrafficShapingHandler;?,netty,rate-limiting,Netty,Rate Limiting,我需要将一个大文件推送到客户端,但我想限制速度(例如100Kb/s),如何使用ChannelTrafficShapingHandler ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO

我需要将一个大文件推送到客户端,但我想限制速度(例如100Kb/s),如何使用ChannelTrafficShapingHandler

ServerBootstrap b = new ServerBootstrap();
              b.group(bossGroup, workerGroup)
               .channel(NioServerSocketChannel.class)
               .option(ChannelOption.SO_BACKLOG, 100)
               .handler(new LoggingHandler(LogLevel.INFO))
               .childHandler(new ChannelInitializer<SocketChannel>() {
                   @Override
                   public void initChannel(SocketChannel ch) throws Exception {
                       ChannelPipeline p = ch.pipeline();

                       p.addLast(
                               new StringEncoder(CharsetUtil.UTF_8),
                               new LineBasedFrameDecoder(8192),
                               new StringDecoder(CharsetUtil.UTF_8),
                               new ChannelTrafficShapingHandler(1,1,10L),
                               new ChunkedWriteHandler(),
                               new FileServerHandler()
                               );
                   }
               });
ServerBootstrap b=newserverbootstrap();
b、 组(bossGroup、workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG,100)
.handler(新的LoggingHandler(LogLevel.INFO))
.childHandler(新的通道初始值设定项(){
@凌驾
public void initChannel(SocketChannel ch)引发异常{
ChannelPipeline p=通道管道();
p、 addLast(
新的StringEncoder(CharsetUtil.UTF_8),
新的LineBasedFrameDecoder(8192),
新的字符串解码器(CharsetUtil.UTF_8),
新型信道流量整形器(1,1,10L),
新的ChunkedWriteHandler(),
新的FileServerHandler()
);
}
});

此演示不起作用,为什么?

您是否管理了FileServerHandler中的通道写入功能

如Netty API中所述

在您的处理程序中,应该考虑使用Shane.ISWrrable() 和channelWritabilityChanged(ctx)来处理可写性,或通过 返回future上的future.addListener(新的GenericFutureListener()) 通过ctx.write()

<>你也应该考虑在读或写中有对象的大小。 与所需带宽相对适应的操作:针对 实例10KB/s有10MB对象会导致突发效应, 虽然有100 KB的对象,速度为1 MB/s,但应通过 这个流量处理器

以及初始化:

  • 第一项是以B/s为单位的写限制(这里强烈不建议使用1,对于1KB/s,接近1024的最小值)
  • 第二项是以B/S为单位的读取限制(这里强烈不建议使用1,接近1024的最小值表示为1KB/S,或0表示无限制)
  • 第一项是以毫秒为单位的间隔检查(这里1L表示每毫秒,这是强烈不推荐的,对于每1s,接近1000的值是最小的)
您可以看到一个示例(使用Discard示例),尤其是:


您能解释一下
检查间隔的作用吗?我不明白。@Alexander,正如医生所说:
checkInterval
-两次计算通道性能之间的延迟,如果不计算统计数据,则为0。这意味着必须以某种方式不时计算带宽。带宽不是立即知道的,而是最近的过去,最近的是你喜欢的。1毫秒太短,无法获得正确的计算(平均值),1秒通常是一个不错的选择。这是否意味着通过在最大速度和0速度之间交替使用“方”波来应用节流,占空比平均到您设置的油门限制?它不是从0到全速。是的,带宽计算检查发送内容的正确性(根据时间计算字节)。但是精度取决于这个时间间隔。smallet越好,但太小意味着回调太多。事实上,一旦向电线写入数据,就没有真正的方法来阻止数据包快速传输。但可以防止不时发送数据包。因此,带宽更多地与数据包限制有关,在数据包限制中,使用此间隔进行额外的控制,即统计。希望它是清楚的…;-)知道了!谢谢你的解释!