2016-03-25 6 views
0

私はGoに新しく、複数のURLをプログレスバーとともにダウンロードできるクロスブラウザアプリケーションを作成しようとしています。 Grabパッケージは下の例のようにうまく機能します。今、私は自己完結型/ポータブル/単一実行可能なウェブUIを持っていて、下のコードからのダウンロードの進捗状況をWebブラウザで表示できますか?溶液のGolangとローカルWebインターフェイスのダウンロードが進んでいますか?

package main 

import (
    "fmt" 
    "github.com/cavaliercoder/grab" 
    "os" 
    "time" 
) 

func main() { 
    // get URL to download from command args 
    if len(os.Args) < 2 { 
     fmt.Fprintf(os.Stderr, "usage: %s url [url]...\n", os.Args[0]) 
     os.Exit(1) 
    } 

    urls := os.Args[1:] 

    // start file downloads, 3 at a time 
    fmt.Printf("Downloading %d files...\n", len(urls)) 
    respch, err := grab.GetBatch(3, ".", urls...) 
    if err != nil { 
     fmt.Fprintf(os.Stderr, "%v\n", err) 
     os.Exit(1) 
    } 

    // start a ticker to update progress every 200ms 
    t := time.NewTicker(200 * time.Millisecond) 

    // monitor downloads 
    completed := 0 
    inProgress := 0 
    responses := make([]*grab.Response, 0) 
    for completed < len(urls) { 
     select { 
     case resp := <-respch: 
      // a new response has been received and has started downloading 
      // (nil is received once, when the channel is closed by grab) 
      if resp != nil { 
       responses = append(responses, resp) 
      } 

     case <-t.C: 
      // clear lines 
      if inProgress > 0 { 
       fmt.Printf("\033[%dA\033[K", inProgress) 
      } 

      // update completed downloads 
      for i, resp := range responses { 
       if resp != nil && resp.IsComplete() { 
        // print final result 
        if resp.Error != nil { 
         fmt.Fprintf(os.Stderr, "Error downloading %s: %v\n", resp.Request.URL(), resp.Error) 
        } else { 
         fmt.Printf("Finished %s %d/%d bytes (%d%%)\n", resp.Filename, resp.BytesTransferred(), resp.Size, int(100*resp.Progress())) 
        } 

        // mark completed 
        responses[i] = nil 
        completed++ 
       } 
      } 

      // update downloads in progress 
      inProgress = 0 
      for _, resp := range responses { 
       if resp != nil { 
        inProgress++ 
        fmt.Printf("Downloading %s %d/%d bytes (%d%%)\033[K\n", resp.Filename, resp.BytesTransferred(), resp.Size, int(100*resp.Progress())) 
       } 
      } 
     } 
    } 

    t.Stop() 

    fmt.Printf("%d files successfully downloaded.\n", len(urls)) 
} 
+0

あなたはUIのプログレスバーが必要です、またはあなたが望むにダウンロードの進行状況を表示しますか? –

+0

このコードからダウンロード進行状況を表示する必要があります。fmt.Printf( "%s%d /%dバイト(%d %%)をダウンロード中です。\ 033 [K \ n "、resp.Filename、resp.BytesTransferred()、resp.Size、int(100 * resp.Progress()))'を実行します。 – iLearn2016

+0

次に、この場合にはwebsocketを使用する必要があると思います。 –

答えて

0

一種は、クライアント・サーバ間の通信を意味し、それは一つだけにブラウザとサーバとの間で必要なハンドシェイクの数を減らすヘッダの特別な種類を使用して接続を確立するため、のWebSocketを使用することであろうブロックされません。

この接続は有効期間中有効です。従来のTCPソケットの場合と同様に、この接続からJavaScriptを使用してデータを書き込みまたは読み取ることができます。あなたは、あなたが websocket.JSON.Sendと、この文字列を送信することができますjson文字列としてgrabパッケージで構成結果の情報をエンコードすることができ、実装の問題として

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

そして、クライアント部分の上にあなたが望むように、後であなたが使用することを目的と(キャンバス、DOMなど)が好ま技術に応じて、解析し、使用することができる合成JSONオブジェクトを取得することができます。

以下

は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") 
    } 
} 

値がハードコーディングされているとあなたが転送速度を変更したい場合は、タイマーの目盛りを使用することができます。

、外出先で書かれクライアント側:あなたはのWebSocketに接続してデータを受信することができ、JavaScriptで

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) 
    } 
} 

<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> 
関連する問題