分块上传和断点续传

分块上传和断点续传,第1张

分块上传和断点续传

分块上传和断点续传

两个概念

分块上传:文件切成多块,独立传输,上传完成后合并

断点续传:传输暂停或异常中断后,可基于原来进度重传

几点说明:

1、小文件不建议分块上传

2、可以并行上传,并且可以无序传输

3、分块上传可以极大提高传输效率,不过要注意分块上传文件的数量

4、减少传输失败后重试的流量及时间

流程:

1、云端初始化上传文件的信息

2、客户端执行上传分块—>上传取消,查询上传信息

3、客户端通知云端上传完成

服务架构:

redis缓存用于云端与客户端文件信息交互

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5PJcYLvX-1641174946216)(E:学习笔记Go笔记截图屏幕截图 2022-01-02 095031.png)]

分块上传通用接口

1、初始化分块信息

2、上传分块

3、通知上传完成

4、取消上传分块

5、查看分块上传的整体状态

前期准备

在src下创建cache,在cache目录下再创建Redis,在Redis目录下创建conn.go

import(
	"fmt"
	"github.com/garyburd/redigo/redis"
	"time"
)

var(
	pool*redis.Pool//redis连接池用于客户端与redis交互数据
	redisHost="127.0.0.1:6379"//redis的IP
	redisPass="testupload"//redis登录密码
)

func newRedisPool()*redis.Pool{//初始化redis
	return&redis.Pool{
		MaxIdle:50,//最大存储文件信息数
		MaxActive:30,//最多实际存储文件信息数
		IdleTimeout:300*time.Second,//超过该时间断开与redis的连接
		Dial:func()(redis.Conn,error){
			//1.打开连接
			c,err:=redis.Dial("tcp",redisHost)
			if err!=nil{
				fmt.Println(err)
				return nil,err
			}
			//2.访问认证
			if _,err=c.Do("AUTH",redisPass);err!=nil{
				c.Close()
				return nil,err
			}
			return c,nil
		},
		//定时检查redis的健康状况,若出问题则在客户端关闭redis的连接
		TestOnBorrow:func(conn redis.Conn,t time.Time)error{
			if time.Since(t) 

1、初始化分块信息

import (
	"fmt"
	"math"
	"net/http"
	"rgo/src/util"
	"strconv"
	rPool"rgo/cache/redis"
	"time"
)
//初始化信息
type MultipartUploadInfo struct{
	FileHash string
	FileSize int
	UploadID string      //唯一标识
	ChunkSize int       //分块大小
	ChunkCount int      //分块个数
}
func InitialMultipartUpload(w http.ResponseWriter,r*http.Request){
	r.ParseForm()
	username:=r.Form.Get("username")
	filehash:=r.Form.Get("filehash")
	filesize,err:=strconv.Atoi(r.form.Get("filesize"))
	if err!=nil{
		w.Write(util.NewRespMsg(-1,"params invalid",nil).JSONBytes())
		return
	}
	//2。获得redis的一个连接
    rConn:=rPool.RedisPool().Get()
    defer rConn.Close()
    //3.生成分块上传的初始化信息
    upInfo:=MultipartUploadInfo{
    	FileHash:filehash,
    	FileSize:filesize,
    	UploadID:username+fmt.Sprintf("%x",time.Now().UnixNano()),
    	ChunkSize:5*1024*1024,//5MB
    	ChunkCount:int(math.Ceil(float64(filesize)/(5*1024*1024))),
	}
	//4.将初始化信息写入到redis缓存
     rConn.Do("HEST","MP_"+upInfo.UploadID,"chunkcount",upInfo.ChunkCount)
	 rConn.Do("HEST","MP_"+upInfo.UploadID,"filehash",upInfo.FileHash)
	 rConn.Do("HEST","MP_"+upInfo.UploadID,"filesize",upInfo.FileSize)
	//5.将响应初始化数据返回到客户端
	w.Write(util.NewRespMsg(0,"OK",upInfo).JSONBytes())
}

2.上传文件分块

//上传文件分块
func UploadPartHandler(w http.ResponseWriter,r*http.Request){
	//1.解析用户请求参数
	r.ParseForm()
	username:=r.Form.Get("username")
	uploadID:=r.Form.Get("uploadid")
	chunkIndex:=r.Form.Get("index")
	//2.获得redis连接池中的一个连接
	rConn:=rPool.RedisPool().Get()
	defer rConn.Close()
	//3.获得文件句柄,用于存储分块内容
	fpath:="/data/"+uploadID+"/"+chunkIndex
	os.MkdirAll(path.Dir(fpath),0744)
	if err!=nil{
		w.Write(util.NewrESPmSG(-1,"Upload part failed",nil).JSONBytes())
		return
	}
	defer fd.Close()
	buf:=make([]byte,1024*1024)
	for{
		n,err:=r.Body.Read(buf)
		fd.Write(buf[:n])
		if err!=nil{
			break
		}
	}
	//4.更新redis缓存状态
	rConn.Do("HEST","MP_"+uploadID,"chkid_"+chunkIndex,1)
	//5.返回处理结果到客户端
	w.Write(util.NewrESPmSG(0,"OK",nil).JSONBytes())
}

3.合并

//通知上传合并接口
func CompleteUploadHandler(w http.ResponseWriter,r*http.Request){
	//1.解析请求参数
	r.ParseForm()
	upid:=r.Form.Get("uploadid")
	username:=r.Form.Get("username")
	filehash:=r.Form.Get("filehash")
	filesize:=r.Form.Get("filesize")
	filename:=r.Form.Get("filename")
	//2.获得redis连接池中的一个连接
     rConn:=rPool.RedisPool().Get()
     defer rConn.Close()
	//3.通过uploadid查询redis并判断是否所有分块上传完成
     data,err:=redis.Values(rConn.Do("HGETALL","MP_"+upid))
     if err!=nil{
     	w.Write(util.NewRespMsg(-1,"complete upload failed",nil).JSONBytes())
     	return
	 }
     totalCount:=0
     chunkCount:=0
     for i:=0;i 

i(filesize)
dblayer.onFileUploadFinished(filehash,filename,int(fsize),"")
dblayer.onUserFileUploadFinished(username,filehash,filename,int64(fsize))
//6.响应处理结果
w.Write(util.NewRespMsg(0,“OK”,nil).JSonBytes())
}

					
										


					

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5695577.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存