前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >netty案例,netty4.1中级拓展篇十一《Netty基于ChunkedStream数据流切块传输》

netty案例,netty4.1中级拓展篇十一《Netty基于ChunkedStream数据流切块传输》

作者头像
小傅哥
发布于 2020-07-14 06:58:47
发布于 2020-07-14 06:58:47
1.1K00
代码可运行
举报
运行总次数:0
代码可运行

作者:付政委

前言介绍

在Netty这种异步NIO框架的结构下,服务端与客户端通信过程中,高效、频繁、大量的写入大块数据时,因网络传输饱和的可能性就会造成数据处理拥堵、GC频繁、用户掉线的可能性。那么由于写操作是非阻塞的,所以即使没有写出所有的数据,写操作也会在完成时返回并通知ChannelFuture。当这种情况发生时,如果仍然不停地写入,就有内存耗尽的风险。所以在写大块数据时,需要对大块数据进行切割发送处理。

https://netty.io/4.0/api/io/netty/handler/stream/ChunkedStream.html ChunkedInput 的实现 ChunkedFile 从文件中逐块获取数据,当你的平台不支持零拷贝或者你需要转换数据时使用 ChunkedNioFile 和ChunkedFile 类似,只是它使用了FileChannel ChunkedStream 从InputStream 中逐块传输内容 ChunkedNioStream 从ReadableByteChannel 中逐块传输内容

开发环境

1、jdk1.8【jdk1.7以下只能部分支持netty】 2、Netty4.1.36.Final【netty3.x 4.x 5每次的变化较大,接口类名也随着变化】 3、NetAssist 网络调试助手[获取:关注公众号:bugstack虫洞栈 | 回复;NetAssist+邮箱]

代码示例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
itstack-demo-netty-2-11
└── src
    ├── main
    │   └── java
    │       └── org.itstack.demo.netty.server
    │           ├── MyChannelInitializer.java
    │           ├── MyServerChunkHandler.java
    │           ├── MyServerHandler.java
    │           └── NettyServer.java
    └── test
         └── java
             └── org.itstack.demo.test
                 └── ApiTest.java

重点代码块讲解,完整代码,关注公众号:bugstack虫洞栈 | 回复Netty源码,获取

MyChannelInitializer.java | 添加流量分块功能

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel channel) {
        // 基于换行符号
        channel.pipeline().addLast(new LineBasedFrameDecoder(1024));
        // 流量分块
        channel.pipeline().addLast(new ChunkedWriteHandler());
        channel.pipeline().addLast(new MyServerChunkHandler());
        // 解码转String,注意调整自己的编码格式GBK、UTF-8
        channel.pipeline().addLast(new StringDecoder(Charset.forName("GBK")));
        // 解码转String,注意调整自己的编码格式GBK、UTF-8
        channel.pipeline().addLast(new StringEncoder(Charset.forName("GBK")));
        // 在管道中添加我们自己的接收数据实现方法
        channel.pipeline().addLast(new MyServerHandler());
    }

}

MyServerChunkHandler.java | 流量分块实现ChunkedStream(in, 10)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

public class MyServerChunkHandler extends ChannelOutboundHandlerAdapter {

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        //内容验证
        if (!(msg instanceof ByteBuf)) {
            super.write(ctx, msg, promise);
            return;
        }
        //获取Byte
        ByteBuf buf = (ByteBuf) msg;
        byte[] data = this.getData(buf);
        //写入流中
        ByteInputStream in = new ByteInputStream();
        in.setBuf(data);
        //消息分块;10个字节,测试过程中可以调整
        ChunkedStream stream = new ChunkedStream(in, 10);
        //管道消息传输承诺
        ChannelProgressivePromise progressivePromise = ctx.channel().newProgressivePromise();
        progressivePromise.addListener(new ChannelProgressiveFutureListener() {
            @Override
            public void operationProgressed(ChannelProgressiveFuture future, long progress, long total) throws Exception {
            }
            @Override
            public void operationComplete(ChannelProgressiveFuture future) throws Exception {
                if (future.isSuccess()) {
                    System.out.println("消息发送成功 success");
                    promise.setSuccess();
                } else {
                    System.out.println("消息发送失败 failure:" + future.cause());
                    promise.setFailure(future.cause());
                }
            }
        });
        ReferenceCountUtil.release(msg);
        ctx.write(stream, progressivePromise);
    }

    //获取Byte
    private byte[] getData(ByteBuf buf) {
        if (buf.hasArray()) {
            return buf.array().clone();
        }
        byte[] data = new byte[buf.readableBytes() - 1];
        buf.readBytes(data);
        return data;
    }

}

测试结果

启动服务端NettyServer

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
itstack-demo-netty server start done. {关注公众号:bugstack虫洞栈,获取源码}
链接报告开始
链接报告信息:有一客户端链接到本服务端
链接报告IP:127.0.0.1
链接报告Port:7397
链接报告完毕
消息发送成功 success
2019-09-15 16:36:04 接收到消息:hi 微信公众号:bugstack虫洞栈 | 欢迎关注并获取专题文章和源码
消息发送成功 success
2019-09-15 16:36:04 接收到消息:
消息发送成功 success

Process finished with exit code -1

启动NetAssist网络调试助手 | 发送测试消息[结尾加换行]

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
hi 微信公众号:bugstack虫洞栈 | 欢迎关注并获取专题文章和源码
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 bugstack虫洞栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
netty案例,netty4.1基础入门篇五《NettyServer字符串编码器》
netty通信就像一个流水channel管道,我们可以在管道的中间插入一些‘挡板’为我们服务。比如字符串的编码解码,在前面我们使用new StringDecoder(Charset.forName("GBK"))进行字符串解码,这样我们在收取数据就不需要手动处理字节码。那么本章节我们使用与之对应的new StringEncoder(Charset.forName("GBK"))进行进行字符串编码,用以实现服务端在发送数据的时候只需要传输字符串内容即可。
小傅哥
2020/07/14
7930
netty案例,netty4.1基础入门篇五《NettyServer字符串编码器》
netty案例,netty4.1基础入门篇二《NettyServer接收数据》
繁事都需要一个简单的入门的点,尤其学习程序员行业的知识最快的方式是先运行期helloworld,往往这样一个简单能运行的例子,就能解除你当前遇到的所有疑惑。切记,对于一个初学者,不建议上来就研究理论,实操往往更重要。本章节介绍使用netty端写一个能接收数据的socketServer服务端,通过实现通道适配器ChannelInboundHandlerAdapter.channelRead获取并并解析接收数据。
小傅哥
2020/01/20
5970
netty案例,netty4.1基础入门篇二《NettyServer接收数据》
netty案例,netty4.1中级拓展篇三《Netty传输Java对象》
Netty在实际应用级开发中,有时候某些特定场景下会需要使用Java对象类型进行传输,但是如果使用Java本身序列化进行传输,那么对性能的损耗比较大。为此我们需要借助protostuff-core的工具包将对象以二进制形式传输并做编码解码处理。与直接使用protobuf二进制传输方式不同,这里不需要定义proto文件,而是需要实现对象类型编码解码器,用以传输自定义Java对象。
小傅哥
2020/07/14
6150
netty案例,netty4.1中级拓展篇三《Netty传输Java对象》
netty案例,netty4.1基础入门篇九《自定义编码解码器》
在实际应用场景里,只要是支持sokcet通信的都可以和Netty交互,比如中继器、下位机、PLC等。这些场景下就非常需要自定义编码解码器,来处理字节码传输,并控制半包、粘包以及安全问题。那么本章节我们通过实现ByteToMessageDecoder、MessageToByteEncoder来实现我们的需求。
小傅哥
2020/07/14
5380
netty案例,netty4.1基础入门篇九《自定义编码解码器》
netty案例,netty4.1中级拓展篇二《Netty使用Protobuf传输数据》
在netty数据传输过程中可以有很多选择,比如;字符串、json、xml、java对象,但为了保证传输的数据具备;良好的通用性、方便的操作性和传输的高性能,我们可以选择protobuf作为我们的数据传输格式。目前protobuf可以支持;C++、C#、Dart、Go、Java、Python等,也可以在JS里使用。知识点;ProtobufDecoder、ProtobufEncoder、ProtobufVarint32FrameDecoder、ProtobufVarint32LengthFieldPrepender。
小傅哥
2020/07/14
6820
netty案例,netty4.1中级拓展篇二《Netty使用Protobuf传输数据》
netty案例,netty4.1基础入门篇九《自定义编码解码器,处理半包、粘包数据》
在实际应用场景里,只要是支持sokcet通信的都可以和Netty交互,比如中继器、下位机、PLC等。这些场景下就非常需要自定义编码解码器,来处理字节码传输,并控制半包、粘包以及安全问题。那么本章节我们通过实现ByteToMessageDecoder、MessageToByteEncoder来实现我们的需求。
小傅哥
2020/02/11
1.3K0
netty案例,netty4.1基础入门篇九《自定义编码解码器,处理半包、粘包数据》
netty案例,netty4.1中级拓展篇三《Netty传输Java对象》
Netty在实际应用级开发中,有时候某些特定场景下会需要使用Java对象类型进行传输,但是如果使用Java本身序列化进行传输,那么对性能的损耗比较大。为此我们需要借助protostuff-core的工具包将对象以二进制形式传输并做编码解码处理。与直接使用protobuf二进制传输方式不同,这里不需要定义proto文件,而是需要实现对象类型编码解码器,用以传输自定义Java对象。
小傅哥
2020/02/13
1.3K0
netty案例,netty4.1中级拓展篇三《Netty传输Java对象》
netty案例,netty4.1中级拓展篇二《Netty使用Protobuf传输数据》
在netty数据传输过程中可以有很多选择,比如;字符串、json、xml、java对象,但为了保证传输的数据具备;良好的通用性、方便的操作性和传输的高性能,我们可以选择protobuf作为我们的数据传输格式。目前protobuf可以支持;C++、C#、Dart、Go、Java、Python等,也可以在JS里使用。知识点;ProtobufDecoder、ProtobufEncoder、ProtobufVarint32FrameDecoder、ProtobufVarint32LengthFieldPrepender。
小傅哥
2020/02/13
1.3K0
netty案例,netty4.1中级拓展篇二《Netty使用Protobuf传输数据》
netty案例,netty4.1基础入门篇十《关于ChannelOutboundHandlerAdapter简单使用》
ChannelOutboundHandlerAdapter与ChannelInboundHandlerAdapter都是继承于ChannelHandler,并实现自己的ChannelXxxHandler。用于在消息管道中不同时机下处理处理消息。
小傅哥
2020/02/12
3.8K0
netty案例,netty4.1基础入门篇十《关于ChannelOutboundHandlerAdapter简单使用》
netty案例,netty4.1基础入门篇三《NettyServer字符串解码器》
在实际开发中,server端接收数据后我们希望他是一个字符串或者是一个对象类型,而不是字节码,那么;
小傅哥
2020/01/20
8470
netty案例,netty4.1基础入门篇三《NettyServer字符串解码器》
netty案例,netty4.1基础入门篇六《NettyServer群发消息》
在微信或者QQ的聊天中我们经常会用到一些群聊,把你的信息发送给所有用户。那么为了实现群发消息,在netty中我们可以使用ChannelGroup方式进行群发消息。如果为了扩展验证比如你实际聊天有不同的群,那么可以定义ConcurrentHashMap结构来存放ChannelGroup。ChannelGroup中提供了一些基础的方法;添加、异常、查找、清空、发放消息、关闭等。
小傅哥
2020/07/14
8560
netty案例,netty4.1基础入门篇六《NettyServer群发消息》
netty案例,netty4.1基础入门篇九《自定义编码解码器,处理半包、粘包数据》
在实际应用场景里,只要是支持sokcet通信的都可以和Netty交互,比如中继器、下位机、PLC等。这些场景下就非常需要自定义编码解码器,来处理字节码传输,并控制半包、粘包以及安全问题。那么本章节我们通过实现ByteToMessageDecoder、MessageToByteEncoder来实现我们的需求。
小傅哥
2020/07/14
4870
netty案例,netty4.1基础入门篇九《自定义编码解码器,处理半包、粘包数据》
netty案例,netty4.1基础入门篇四《NettyServer收发数据》
本章节主要介绍服务端在收到数据后,通过writeAndFlush发送ByteBuf字节码向客户端传输信息。因为我们使用客户端模拟器的编码是GBK格式,所以代码中也需要将字节码转换为GBK,否则会乱码。
小傅哥
2020/01/20
5970
netty案例,netty4.1基础入门篇四《NettyServer收发数据》
netty案例,netty4.1基础入门篇十《关于ChannelOutboundHandlerAdapter简单使用》
ChannelOutboundHandlerAdapter与ChannelInboundHandlerAdapter都是继承于ChannelHandler,并实现自己的ChannelXxxHandler。用于在消息管道中不同时机下处理处理消息。
小傅哥
2020/07/14
1.8K0
netty案例,netty4.1基础入门篇十《关于ChannelOutboundHandlerAdapter简单使用》
netty案例,netty4.1基础入门篇十一《netty udp通信方式案例Demo》
在Netty通信中UDP的实现方式也非常简单,只要注意部分代码区别于TCP即可。本章节需要注意的知识点 ;NioDatagramChannel、ChannelOption.SO_BROADCAST
小傅哥
2020/02/12
5.7K0
netty案例,netty4.1基础入门篇十一《netty udp通信方式案例Demo》
netty案例,netty4.1基础入门篇十一《netty udp通信方式案例Demo》
在Netty通信中UDP的实现方式也非常简单,只要注意部分代码区别于TCP即可。本章节需要注意的知识点 ;NioDatagramChannel、ChannelOption.SO_BROADCAST
小傅哥
2020/07/14
7120
netty案例,netty4.1基础入门篇十一《netty udp通信方式案例Demo》
netty案例,netty4.1中级拓展篇十三《Netty基于SSL实现信息传输过程中双向加密验证》
在实际通信过程中,如果不使用SSL那么信息就是明文传输,从而给非法分子一些可乘之机;
小傅哥
2020/07/14
3.1K0
netty案例,netty4.1中级拓展篇十三《Netty基于SSL实现信息传输过程中双向加密验证》
netty案例,netty4.1中级拓展篇十二《Netty流量整形数据流速率控制分析与实战》
你是否使用过某盘,在前几年我们使用的时候速度飞快,上传下载嗖嗖嗖。但是近年来只要不办会员,速度慢的像蜗牛,当然人家也得赚钱我们能理解。那么这样的限速是怎么实现的呢,我们这个案例使用Netty的流量整形进行限速传输,测试过程中当你把流量整形功能去掉后你就是年费VIP。
小傅哥
2020/07/14
1.5K0
netty案例,netty4.1中级拓展篇十二《Netty流量整形数据流速率控制分析与实战》
netty案例,netty4.1基础入门篇八《NettyClient半包粘包处理、编码解码处理、收发数据方式》
Netty开发中,客户端与服务端需要保持同样的;半包粘包处理,编码解码处理、收发数据方式,这样才能保证数据通信正常。在前面NettyServer的章节中我们也同样处理了;半包粘包、编码解码等,为此在本章节我们可以把这些知识模块开发到NettyClient中。本章节涉及到的知识点有;LineBasedFrameDecoder、StringDecoder、StringEncoder、ChannelInboundHandlerAdapter等。
小傅哥
2020/07/14
4370
netty案例,netty4.1基础入门篇八《NettyClient半包粘包处理、编码解码处理、收发数据方式》
netty案例,netty4.1基础入门篇十二《简单实现一个基于Netty搭建的Http服务》
Netty不仅可以搭建Socket服务,也可以搭建Http、Https服务。本章节我们通过一个简单的入门案例,来了解Netty搭建的Http服务,在我们后续的Netty网关服务中会使用到这样的功能点。
小傅哥
2020/07/14
6230
netty案例,netty4.1基础入门篇十二《简单实现一个基于Netty搭建的Http服务》
推荐阅读
netty案例,netty4.1基础入门篇五《NettyServer字符串编码器》
7930
netty案例,netty4.1基础入门篇二《NettyServer接收数据》
5970
netty案例,netty4.1中级拓展篇三《Netty传输Java对象》
6150
netty案例,netty4.1基础入门篇九《自定义编码解码器》
5380
netty案例,netty4.1中级拓展篇二《Netty使用Protobuf传输数据》
6820
netty案例,netty4.1基础入门篇九《自定义编码解码器,处理半包、粘包数据》
1.3K0
netty案例,netty4.1中级拓展篇三《Netty传输Java对象》
1.3K0
netty案例,netty4.1中级拓展篇二《Netty使用Protobuf传输数据》
1.3K0
netty案例,netty4.1基础入门篇十《关于ChannelOutboundHandlerAdapter简单使用》
3.8K0
netty案例,netty4.1基础入门篇三《NettyServer字符串解码器》
8470
netty案例,netty4.1基础入门篇六《NettyServer群发消息》
8560
netty案例,netty4.1基础入门篇九《自定义编码解码器,处理半包、粘包数据》
4870
netty案例,netty4.1基础入门篇四《NettyServer收发数据》
5970
netty案例,netty4.1基础入门篇十《关于ChannelOutboundHandlerAdapter简单使用》
1.8K0
netty案例,netty4.1基础入门篇十一《netty udp通信方式案例Demo》
5.7K0
netty案例,netty4.1基础入门篇十一《netty udp通信方式案例Demo》
7120
netty案例,netty4.1中级拓展篇十三《Netty基于SSL实现信息传输过程中双向加密验证》
3.1K0
netty案例,netty4.1中级拓展篇十二《Netty流量整形数据流速率控制分析与实战》
1.5K0
netty案例,netty4.1基础入门篇八《NettyClient半包粘包处理、编码解码处理、收发数据方式》
4370
netty案例,netty4.1基础入门篇十二《简单实现一个基于Netty搭建的Http服务》
6230
相关推荐
netty案例,netty4.1基础入门篇五《NettyServer字符串编码器》
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文