2013-11-04 64 views
0

聽說here如何在Go中執行HTTP雙工處理程序?

一旦你寫在迴應什麼,請求主體將是 關閉以防止你從它

如果這是真的,我該怎麼寫讀什麼一個合適的雙工處理程序,它能夠從請求主體讀取數據,進行某種轉換,然後以流方式寫入響應主體,就像人們在node.js中一樣?

回答

1

我最終設法用http.Hijacker來做到這一點。

的請求並請求頭進行解析後,我可以從*http.Request.Body閱讀,然後劫持連接和寫入,同時,這樣的:

hj, ok := w.(http.Hijacker) 
if !ok { 
    http.Error(w, "hijacking not supported", 500) 
    return 
} 

conn, bufrw, err := hj.Hijack() 
if err != nil { 
    http.Error(w, err.Error(), 500) 
    return 
} 
defer conn.Close() 

然後conn是一個net.Conn這是底層TCP連接到客戶端,bufrw*bufio.ReadWriter,並寫響應,但不關閉身上所有我需要做的就是

_, err = bufrw.WriteString("HTTP/1.1 200 OK\n\n") 
_, err = bufrw.WriteString("this") 
_, err = bufrw.WriteString("is") 
_, err = bufrw.WriteString("the") 
_, err = bufrw.WriteString("response") 
_, err = bufrw.WriteString("body") 

然後我不知道這一點,但也許有人可以完成的答案,這是沖洗下來

err := bufrw.Flush() 
0

net/http docs你指的是

VAR ErrBodyReadAfterClose = errors.New( 「HTTP:無效讀上關閉 體」)讀取請求或響應 身體的時候

ErrBodyReadAfterClose返回身體關閉後。這通常發生在一個HTTP處理程序調用WriteHeader後或在讀 體寫上其 ResponseWriter

但是我想從你所提到的博客文章鏈接的代碼,它工作正常去下1.1.2,除非我首先寫入超過約4k的數據,在這種情況下r.ParseForm()返回ErrBodyReadAfterClose

所以我認爲答案是否定的,除非答案很短(在4k以下),否則不能在全雙工HTTP中進行。

我會說,做全雙工HTTP請求不太可能是一個很大的好處,雖然大多數客戶端將不會嘗試讀取響應,直到他們完成發送請求,所以最贏得的是客戶端&服務器中TCP緩衝區的大小。死鎖似乎有可能,如果這些緩衝區超出,如

  • 客戶端發送請求
  • 服務器發送響應
  • 服務器緩衝區得到充分發送響應
  • 服務器塊
  • 服務器不再閱讀的客戶端請求
  • 客戶端緩衝區填滿
  • 客戶端塊
  • 死鎖
+0

我不知道大多數客戶在一段時間一次連接緩衝區是一個好主意,但任何Node.js的客戶端可以做到這一點,那就是我來自的地方。如果這將是一個問題,我將不得不更好地處理緩衝區 –