1
BlackBerry999 2020-01-19 09:11:34 +08:00
协程+channel ? 或者 socket ?
|
2
Leigg 2020-01-19 09:44:27 +08:00 via Android
为何不让前端直接调用三方接口,减少故障点,是有什么经过后台的必要性?如果有,最好先缓存后台,缓存完成后再传前端,这样成功率更大些,大文件更甚。
|
3
airplayxcom OP @Leigg 是的 必须走后端授权,缓存大文件不吃内存吗,几个人同时下载发文件怎么办。
|
4
puyo 2020-01-19 10:33:50 +08:00
先 head 拿到 contentLength,返回头信息,然后并发去第三方下载,按顺序 flush。
|
5
Leigg 2020-01-19 14:23:28 +08:00 via Android
@airplayxcom 缓存并不一定就是存内存。后台整一段磁盘空间用来缓存下载文件,只做临时缓存,下完就删,或者保留一段时间。
|
6
index90 2020-01-19 17:04:23 +08:00
http.HandleFunc("", func(writer http.ResponseWriter, request *http.Request) {
file, err := os.Open("") if err != nil { writer.WriteHeader(404) return } defer file.Close() if _, err := io.Copy(writer, file); err != nil { writer.WriteHeader(500) return } writer.Header().Set("content-type", "text/plain") writer.WriteHeader(200) }) |
7
index90 2020-01-19 17:10:37 +08:00
如果你不是读取本地文件,而是从别人的请求中转发数据,你留意一下 http.Response 的 body 是已经实现了 reader interface,只需要从 reader copy 数据到 writer 就可以了。
面向接口编程,你需要什么接口,去找对应的实现就可以了。 |
8
index90 2020-01-19 17:26:23 +08:00 1
#6 的代码不对,send header 应该在 send body 之前。
http.HandleFunc("", func(writer http.ResponseWriter, request *http.Request) { var reader io.Reader //{ // file, err := os.Open("") // if err != nil { // writer.WriteHeader( http.StatusNotFound) // return // } // reader = file // defer file.Close() //} { resp, err := http.Client{}.Get("") if err != nil { writer.WriteHeader( http.StatusNotFound) return } reader = resp.Body } writer.Header().Set("content-type", "text/plain") _, _ = io.Copy(writer, reader) return }) |
9
airplayxcom OP @index90 有心了
|
10
ihciah 2020-01-20 02:12:22 +08:00
不一定非要先全拼出来,可以流式处理,具体实现可以按照楼上的直接用 Reader 接口。自己实现 Reader 接口的话,在 read 的时候现场拼接下一块返回就行了。
|