为了账号安全,请及时绑定邮箱和手机立即绑定

用于下载进度的 Golang 和本地 Web 界面?

用于下载进度的 Golang 和本地 Web 界面?

Go
缥缈止盈 2021-12-27 16:09:09
我是新手Go并试图制作一个跨浏览器的应用程序,它可以下载多个带有进度条的 url。该Grab包很好地完成了这项工作,如下面的示例所示。现在,我想要一个独立的/可移植的/单一可执行的 Web-UI,它可以在 Web 浏览器中显示来自以下代码的下载进度?
查看完整描述

1 回答

?
函数式编程

TA贡献1807条经验 获得超9个赞

一种解决方案是使用 websocket,因为要建立连接,它使用一种特殊的标头,将浏览器和服务器之间所需的握手次数减少到只有一次,这意味着客户端服务器通信不会阻塞。


此连接将在其整个生命周期内保持活动状态,您可以使用 JavaScript 从此连接写入或读取数据,就像在传统 TCP 套接字的情况下一样。


作为实现问题,您可以将grab包组成的结果信息编码为json字符串,然后您可以使用 websocket.JSON.Send.


func (cd Codec) Send(ws *Conn, v interface{}) (err error)

在客户端,您可以获得组合的 json 对象,稍后您可以根据您的使用目的和首选技术(画布、DOM 等)解析和使用该对象。


以下是 websocket服务器端的片段:


package main


import (

    "fmt"

    "golang.org/x/net/websocket"

    "net/http"

)


type FileInformation struct {

    BytesTransferred int

    Size             string

    Filename         string

    Progress         int

}


func Echo(ws *websocket.Conn) {

    info := FileInformation{

        BytesTransferred: 70,

        Size:             "1.7MB",

        Filename:         "test.txt",

        Progress:         60,

    }


    for {

        if err := websocket.JSON.Send(ws, info); err != nil {

            fmt.Println("Error sending message")

            break

        }

        // if BytesTransferred == 100 break

    }

}


func main() {

    http.Handle("/", websocket.Handler(Echo))


    if err := http.ListenAndServe(":1234", nil); err != nil {

        fmt.Println("Cannot iniatiate a websocket connection")

    }

}

当然,这些值是硬编码的,如果您想改变传输速度,可以使用计时器滴答。


该客户端写在走:


package main


import (

    "fmt"

    "golang.org/x/net/websocket"

    "io"

    "os"

)


func main() {

    type FileInformation struct {

        BytesTransferred int

        Size             string

        Filename         string

        Progress         int

    }


    if len(os.Args) > 1 && (os.Args[1] == "--help" || os.Args[1] == "-h") {

        fmt.Println("Usage : " + os.Args[0] + " ws://localhost:port")

        os.Exit(1)

    }


    conn, err := websocket.Dial(os.Args[1], "", "http://127.0.0.1")

    checkError(err)

    var info FileInformation


    for {

        err := websocket.JSON.Receive(conn, &info)

        if err != nil {

            if err == io.EOF {

                break

            }

            fmt.Println("Couldn't receive msg " + err.Error())

            break

        }

        fmt.Printf("%s", info)


        if err := websocket.JSON.Send(conn, info); err != nil {

            checkError(err)

        }

    }

}


func checkError(err error) {

    if err != nil {

        fmt.Println("Fatal error: " + err.Error())

        os.Exit(1)

    }

}

在 javascript 中,您可以连接到 websocket 并以以下方式接收数据:


<script type="text/javascript">

    var sock = null;

    var wsuri = "ws://127.0.0.1:1234";


    window.onload = function() {


        console.log("onload");


        sock = new WebSocket(wsuri);


        sock.onopen = function() {

            console.log("connected to " + wsuri);

        }


        sock.onclose = function(e) {

            console.log("connection closed (" + e.code + ")");

        }


        sock.onmessage = function(e) {

            console.log("message received: " + e.data);

            // deserialize json data

            var json = JSON.parse(e.data);

        }

    };


    function send() {

        var msg = document.getElementById('message').value;

        sock.send(msg);

    };

</script>


查看完整回答
反对 回复 2021-12-27
  • 1 回答
  • 0 关注
  • 152 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信