ホームページ > バックエンド開発 > Golang > Go HTTP サーバーが分割された応答を段階的に送信しないのはなぜですか?

Go HTTP サーバーが分割された応答を段階的に送信しないのはなぜですか?

DDD
リリース: 2024-12-09 09:21:09
オリジナル
159 人が閲覧しました

Why Doesn't My Go HTTP Server Send Chunked Responses Progressively?

Go サーバーからの HTTP チャンク応答

このシナリオでは、チャンク化された HTTP 応答を送信する Go HTTP サーバーを作成することを目的としています。 Transfer-Encoding が「chunked」に設定されています。サーバーは 1 秒間隔でチャンクを書き込み、クライアントがオンデマンドでチャンクを受信できるようにする予定です。ただし、現在の実装は課題に直面しています。

  1. クライアントは、意図したとおりに段階的にではなく、すべてのチャンクを一度に受信します。
  2. Content-Length ヘッダーは Go によって自動的に設定されます。 0 にして最後に追加したい。

サーバーコード

提供されるサーバー コードは次のとおりです:

func HandlePost(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Connection", "Keep-Alive")
    w.Header().Set("Transfer-Encoding", "chunked")
    w.Header().Set("X-Content-Type-Options", "nosniff")

    ticker := time.NewTicker(time.Second)
    go func() {
        for t := range ticker.C {
            io.WriteString(w, "Chunk")
            fmt.Println("Tick at", t)
        }
    }()
    time.Sleep(time.Second * 5)
    ticker.Stop()
    fmt.Println("Finished: should return Content-Length: 0 here")
    w.Header().Set("Content-Length", "0")
}
ログイン後にコピー

解決策

問題を解決するには:

  1. http.ResponseWriter によって実装された「Flusher」インターフェイスを使用すると、チャンク送信をトリガーできます。 Flush() 関数を呼び出します。各チャンクの書き込み後にこれを追加することで、クライアントは準備ができたチャンクを受信できるようになります。
  2. Transfer-Encoding ヘッダーは HTTP ライターによって自動的に管理されるため、明示的に設定する必要はありません。

改訂コード

import (
  "fmt"
  "io"
  "log"
  "net/http"
  "time"
)

func main() {
  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    flusher, ok := w.(http.Flusher)
    if !ok {
      panic("expected http.ResponseWriter to be an http.Flusher")
    }
    w.Header().Set("X-Content-Type-Options", "nosniff")
    for i := 1; i <= 10; i++ {
      fmt.Fprintf(w, "Chunk #%d\n", i)
      flusher.Flush() // Trigger "chunked" encoding and send a chunk...
      time.Sleep(500 * time.Millisecond)
    }
  })

  log.Print("Listening on localhost:8080")
  log.Fatal(http.ListenAndServe(":8080", nil))
}
ログイン後にコピー

検証

Telnet を使用してサーバーに接続します:

$ telnet localhost 8080
...
HTTP/1.1 200 OK
Date: ...
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked

9
Chunk #1

9
Chunk #2

...
ログイン後にコピー

各チャンクは次のように段階的に受信されます。サーバーがそれらを送信します。

以上がGo HTTP サーバーが分割された応答を段階的に送信しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート