由于项目业务需要,我需要处理一些大文件的上传(比如说几百MB的视频)

然后在网上搜了一通之后是,发现都是一些零散的实现

但是我感觉这种东西一定是有人造过轮子的,于是我就到 GitHub 上搜索相关的包

image-20221111215420536

然后就发现了 tus 这个项目

image-20221111215604945

打开官网,我发现这是一个基于 HTTP 的开源协议(有 在线 Demo ,感觉挺不错的),还有官方的 Go 实现 tusd ,简直不要太爽

来看在 Go 项目中如何使用 tusd 包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package main

import (
"fmt"
"net/http"

"github.com/tus/tusd/pkg/filestore"
tusd "github.com/tus/tusd/pkg/handler"
)

func main() {
// Create a new FileStore instance which is responsible for
// storing the uploaded file on disk in the specified directory.
// This path _must_ exist before tusd will store uploads in it.
// If you want to save them on a different medium, for example
// a remote FTP server, you can implement your own storage backend
// by implementing the tusd.DataStore interface.
store := filestore.FileStore{
Path: "./uploads",
}

// A storage backend for tusd may consist of multiple different parts which
// handle upload creation, locking, termination and so on. The composer is a
// place where all those separated pieces are joined together. In this example
// we only use the file store but you may plug in multiple.
composer := tusd.NewStoreComposer()
store.UseIn(composer)

// Create a new HTTP handler for the tusd server by providing a configuration.
// The StoreComposer property must be set to allow the handler to function.
handler, err := tusd.NewHandler(tusd.Config{
BasePath: "/files/",
StoreComposer: composer,
NotifyCompleteUploads: true,
})
if err != nil {
panic(fmt.Errorf("Unable to create handler: %s", err))
}

// Start another goroutine for receiving events from the handler whenever
// an upload is completed. The event will contains details about the upload
// itself and the relevant HTTP request.
go func() {
for {
event := <-handler.CompleteUploads
fmt.Printf("Upload %s finished\n", event.Upload.ID)
}
}()

// Right now, nothing has happened since we need to start the HTTP server on
// our own. In the end, tusd will start listening on and accept request at
// http://localhost:8080/files
http.Handle("/files/", http.StripPrefix("/files/", handler))
err = http.ListenAndServe(":8080", nil)
if err != nil {
panic(fmt.Errorf("Unable to listen: %s", err))
}
}

感觉也不复杂,但是在我把这个后端准备好之后,找不到一个前端实现

然后谷歌了一下,找到了一个:http://fpcloud.ricorean.net/plugin/tus-js-client-master/demo/

下面是效果演示

并且这东西支持断点续传,可随意暂停,刷新网页后可同步进度接着上传

但是官方貌似更倾向于把它作为一个独立的服务,而不是嵌入在项目中,然后使用钩子与项目沟通

而且我也无法将 tusd 嵌入在 go-zero 中,因为 go-zero 已经预设好每个路由的方法了,而 tusd 是同时在一个路由使用多种方法的

另外一个不足之处就是我遇到了无法上传的问题,而在访客模式中可以正常工作,最后我发现这种情况需要清一下浏览器的缓存

image-20221112103155367