亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Golang 中沒有緩沖 http.ResponseWritter

在 Golang 中沒有緩沖 http.ResponseWritter

Go
嚕嚕噠 2021-06-30 10:15:26
我正在用 Go 編寫一個簡單的網絡應用程序,我希望我的響應被流式傳輸到客戶端(即,一旦請求被完全處理,就不會緩沖并以塊的形式發送):func handle(res http.ResponseWriter, req *http.Request) {  fmt.Fprintf(res, "sending first line of data")  sleep(10) //not real code  fmt.Fprintf(res, "sending second line of data")}從客戶端的角度來看,兩條線路會同時發送。任何建議表示贊賞:)在@dystroy 回答后編輯我個人每次寫完后都可以刷新,但在我的用例中這還不夠:cmd := exec.Command("a long command that outputs lots of lines")cmd.Stdout = res //where res is a http.ResponseWrittercmd.Stderr = reserr := cmd.Run()我希望我的輸出cmd也被刷新。無論如何要“自動刷新” ResponseWritter ?解決方案我在 golang 的郵件列表上找到了幫助。有兩種方法可以實現這一點:使用劫持程序來接管 HTTP 的底層 TCP 連接,或者在將寫入和刷新的 go 例程中傳輸命令的 stdout 和 stderr:pipeReader, pipeWriter := io.Pipe()cmd.Stdout = pipeWritercmd.Stderr = pipeWritergo writeCmdOutput(res, pipeReader)err := cmd.Run()pipeWriter.Close()//---------------------func writeCmdOutput(res http.ResponseWriter, pipeReader *io.PipeReader) {  buffer := make([]byte, BUF_LEN)  for {    n, err := pipeReader.Read(buffer)    if err != nil {      pipeReader.Close()      break    }    data := buffer[0:n]    res.Write(data)    if f, ok := res.(http.Flusher); ok {      f.Flush()    }    //reset buffer    for i := 0; i < n; i++ {      buffer[i] = 0    }  } }最后更新更好:http : //play.golang.org/p/PpbPyXbtEs
查看完整描述

2 回答

?
catspeake

TA貢獻1111條經驗 獲得超0個贊

正如文檔中暗示的那樣,有些人ResponseWriter可能會實現該Flusher接口。


這意味著您可以執行以下操作:


func handle(res http.ResponseWriter, req *http.Request) {

  fmt.Fprintf(res, "sending first line of data")

  if f, ok := res.(http.Flusher); ok {

     f.Flush()

  } else {

     log.Println("Damn, no flush");

  }

  sleep(10) //not real code

  fmt.Fprintf(res, "sending second line of data")

}

請注意緩沖可能發生在網絡或客戶端的許多其他地方。


查看完整回答
反對 回復 2021-07-05
?
梵蒂岡之花

TA貢獻1900條經驗 獲得超5個贊

如果我誤解了您的問題,但是下面的內容可以解決問題嗎?


package main


import (

    "bytes"

    "fmt"

    "net/http"

)


func handler(w http.ResponseWriter, r *http.Request) {

    body := make([]byte, int(r.ContentLength))

    b := bytes.NewBuffer(body)

    if _, err := b.ReadFrom(r.Body); err != nil {

        fmt.Fprintf(w, "%s", err)

    }

    if _, err := b.WriteTo(w); err != nil {

        fmt.Fprintf(w, "%s", err)

    }

}


func main() {

    http.HandleFunc("/", handler)

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

        panic(err)

    }

}

$ curl --data "param1=value1&param2=value2" http://localhost:8080


返回:


參數1=值1&參數2=值2


您可以隨時附加任何您想要的數據body,或者在再次將其全部寫出之前從其他地方將更多字節讀入緩沖區。


查看完整回答
反對 回復 2021-07-05
  • 2 回答
  • 0 關注
  • 304 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號