netty冲突 play sbt_netty4 实现一个断点上传大文件功能

我本来以为文件断点续传功能很简单,不就是提供2个方法:

一个返回已经上传的文件的长度;另外一个负责上传文件呗(请求带上content-range 指明本次上传的内容在整个文件中的位置),然后根据请求提供的位置写呗,太简单了。

但是实际情况还是比较复杂的,关键问题是,上面的描述现在想想只能称作为文件分段上传,而不是断点续传。

断点意味着网络会断,然后断了之后,服务端根本获取不到本次上传的内容,于是下次又只能从头开始传文件。一种解决办法是客户端将文件分成很小的片段(单个片段丢了就整个片段重传),这个方案要求客户端做很多工作,服务端还得根据片段的编号组织文件,总之客户端和服务端都挺麻烦。

于是就想到用netty在写一个服务filestoreApdapterServer,文件上传提交给这个代理服务。这个做法有个前提就是,客户端上传的文件名称保证唯一,并且在请求头里面带着这个名字,以便服务端定位文件。利用的原理是一般长度比较大的消息体,netty会使用chunk传输,我们取得chunk写入临时文件,这样即使网络断了,服务端已经获取的文件内容还是保留在临时文件里面。

流程如下:

1. filestoreApdapterServer将请求的消息体写到临时文件(网络断了也不要紧,读到多少写多少)。

2. 客户端下次传之前先调用getSize获取上传传递的文件长度,我们就在这个getSize方法里面偷偷的将第一步保存的临时文件追加到正式文件里面,然后返回文件长度。

3. 客户端根据获取的服务端文件长度,定位未传的文件位置,读取上传。重复1,2步骤。直到文件上传完成。

看代码:FilestoreAdaptorServerInitializer

public class FilestoreAdaptorServerInitializer extends

ChannelInitializer {

@Override

protected void initChannel(SocketChannel ch) throws Exception {

ChannelPipeline pipeline = ch.pipeline();

pipeline.addLast("decoder", new HttpRequestDecoder());

pipeline.addLast("aggregator", new StreamChunkAggregator(-1));

pipeline.addLast("encoder", new HttpResponseEncoder());

pipeline.addLast("handler", new FileUploadAdaptorHandler());

}

}

StreamChunkAggregator就是获取上传文件,写临时文件的:

public class StreamChunkAggregator extends MessageToMessageDecoder {

private static final Logger log = LoggerFactory.getLogger(StreamChunkAggregator.class);

private volatile FullHttpMessage currentMessage;

private volatile OutputStream out;

private final int maxContentLength;

private volatile File file;

private ChannelHandlerContext ctx;

public static final int DEFAULT_MAX_COMPOSITEBUFFER_COMPONENTS = 1024;

private int maxCumulationBufferComponents = DEFAULT_MAX_COMPOSITEBUFFER_COMPONENTS;

/**

* Creates a new instance.

*/

public StreamChunkAggrega

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值