前段时间对项目中的一些功能进行了优化,其中涉及到上传文件的一个功能。之前的文件上传是基于AFNetWorking实现,当时并没有做断点续传的支持,现在有了一点时间,前后端一起进行了优化,文件上传支持了断点续传。
具体到上传的文件是一些业务上的数据,优化之前是由客户端主动发起上传任务。基于实际运营中一些问题和经验,这次改进为由服务器下发通知,客户端接到上传通知后自动发起上传任务,原来的客户端主动发起上传功能也继续保留。
总之,无论收到用户的上传消息还是服务器的上传消息,都开始上传任务,优化重点是上传任务支持断点续传,提高用户体验,一定程度上优化服务器压力。
然后梳理了一下整个上传的流程,大致上可以分为以下七步:
1,准备文件
2,准备请求路径
3,创建请求
4,开始上传
5,监听上传
6,上传完成
7,暂停任务,恢复任务
下面是进一步详细的流程:
1;获取上传文件的fileToken
2,先把要上传的文件加密压缩(zip)
3,判断本地是否有这个文件
4,设置上传模式为分片上传
5,创建并设置设置请求对象NSURLRequest
- 5.1,获取文件的分片数据
5.1.1,获取上传文件的路径并交给fileHandle
5.1.2,fileHandle设置本次分片上传的数据开头位置(实际上也就是已经上传的数据量)
5.1.3,fileHandle根据分片大小读取到数据转换为NSData格式
5.1.4,NSData数据格式进行Base64加密 - 5.2,设置请求字段
rangeTo = MIN(fileUploadedSize + fileSliceSize, fileTotalSize);
file:加密后的NSData
fileName:文件名字
rangeFrom:本次上传的数据开始位置(fileUploadedSize)
rangeTo:本次上传数据的截止位置
rangeSize:跟服务器协商规定的每次上传数据大小(<=分片数据大小)
uploadtoken:fileToken(通过另外接口获得) - 5.3,设置请求头
Content-range:bytes 本次开始位置(fileUploadedSize)- 本次结束位置(fileUploadedSize + rangeSize)/本次上传数据大小
Content-Type:application/json
Content-Length:上传的分片大小
设置BodyStream
设置请求方式POST
6,使用NSURLSessionUploadTask开启上传任务
7,在NSURLSessionUploadTask代理方法 didSendBodyData:里面可以观察到上传的进度,可以回调给上传页面。
判断当 fileUploadedSize >= fileTotalSize时,说明文件全部上传完成,否则继续上传
8,代理方法里面解析返回的数据
9,处理分片任务上传失败;判断是否是上传文件开始位置错误,这种情况向服务器请求获取正确的fileUploadSize
10,适当时候检查本地是否有未上传完成的任务,然后重新开启上传任务
#######总结:整个断点续传功能本身并不难,需要注意的是流程的严谨性,整个上传任务的设计合理性,容错处理,加密安全问题,这些东西总结之后加深理解。
网友评论