【问题标题】:Golang FileServer check progressGolang FileServer 检查进度
【发布时间】:2022-02-02 06:17:16
【问题描述】:

我已经使用 GoLang 创建了一个简单的 FileServer

package main

import (
    "log"
    "net/http"
)

func loggingHandler(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println(r.Method, r.RemoteAddr,r.URL.Path)
        h.ServeHTTP(w, r)
    })
}

func main() {
    http.ListenAndServe(":8080", loggingHandler(http.FileServer(http.Dir("/directory/subdir/"))))
}

现在我正在寻找一种方法来检查主机是否正确下载了文件,或者监控已经下载了多少字节。 不幸的是,我无法在互联网上找到任何提示,甚至无法找到。 有没有人遇到过类似的问题?是否可以验证从服务器下载文件的正确性?

【问题讨论】:

  • 你问的是如何在客户端或服务器上监控进度?
  • 我想监控服务器上的进度

标签: http go fileserver


【解决方案1】:

您可以为FileSystem 的实现提供FileServer 的进度计数器。

例子:

package main

import (
    "net/http"
)

type fileWithProgress struct {
    http.File
    size         int64
    downloaded   int64
    lastReported int64
    name         string
    client       string
}

func (f *fileWithProgress) Read(p []byte) (n int, err error) {
    n, err = f.File.Read(p)
    f.downloaded += int64(n)
    f.lastReported += int64(n)
    if f.lastReported > 1_000_000 { // report every 1e6 bytes
        println("client:", f.client, "file:", f.name, "downloaded:", f.downloaded*100/f.size, "%")
        f.lastReported = 0
    }
    return n, err
}

func (f *fileWithProgress) Seek(offset int64, whence int) (int64, error) {
    f.downloaded = 0 // reset content detection read if no content-type specified
    return f.File.Seek(offset, whence)
}

func (f *fileWithProgress) Close() error {
    println("client:", f.client, "file:", f.name, "done", f.downloaded, "of", f.size, "bytes")
    return f.File.Close()
}

type dirWithProgress struct {
    http.FileSystem
    client string
}

func (d *dirWithProgress) Open(name string) (http.File, error) {
    println("open:", name, "for the client:", d.client)
    f, err := d.FileSystem.Open(name)
    if err != nil {
        return nil, err
    }
    st, err := f.Stat()
    if err != nil {
        return nil, err
    }
    return &fileWithProgress{File: f, size: st.Size(), name: st.Name(), client: d.client}, nil
}

func fileServer(fs http.FileSystem) http.Handler {
    f := func(w http.ResponseWriter, r *http.Request) {
        progressDir := dirWithProgress{FileSystem: fs, client: r.RemoteAddr}
        http.FileServer(&progressDir).ServeHTTP(w, r)
    }
    return http.HandlerFunc(f)
}

func main() {
    dir := http.Dir(".")
    fs := fileServer(dir)
    http.Handle("/", fs)
    http.ListenAndServe("127.0.0.1:8080", nil)
}

【讨论】:

  • 主要问题是这样的实现几乎没有用,因为 HTTP 服务器(通常)能够并行服务许多客户端,而且我看不到将传入请求与打开的文件相关联的明显方法。你知道吗?
  • @kostix,是文件服务器上的中间件,用于捕获用户信息。
  • 问题不是如何捕获用户信息,而是如何将其与正在服务的文件(以及正在跟踪的服务进度)关联起来。
  • 更新报告每个客户的进度
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-15
  • 1970-01-01
  • 2015-11-24
  • 1970-01-01
  • 1970-01-01
  • 2018-03-30
  • 2014-08-27
相关资源
最近更新 更多