Heim >Backend-Entwicklung >Golang >Warum sendet mein Go-HTTP-Server nicht nach und nach gebündelte Antworten?

Warum sendet mein Go-HTTP-Server nicht nach und nach gebündelte Antworten?

DDD
DDDOriginal
2024-12-09 09:21:09202Durchsuche

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

HTTP-Chunks-Antwort von einem Go-Server

In diesem Szenario möchten wir einen Go-HTTP-Server erstellen, der eine Chunk-HTTP-Antwort mit sendet Transfer-Encoding ist auf „Chunked“ eingestellt. Der Server beabsichtigt, Chunks in Intervallen von einer Sekunde zu schreiben, sodass der Client sie bei Bedarf empfangen kann. Die aktuelle Implementierung steht jedoch vor Herausforderungen:

  1. Der Client empfängt alle Chunks auf einmal und nicht schrittweise wie beabsichtigt.
  2. Der Content-Length-Header wird automatisch von Go festgelegt, was wir tun möchte 0 sein und am Ende hinzugefügt werden.

Servercode

Der bereitgestellte Der Servercode lautet wie folgt:

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

Lösung

Um die Probleme zu beheben:

  1. Die von http implementierte „Flusher“-Schnittstelle .ResponseWriter ermöglicht es uns, das Senden von Blöcken auszulösen, indem wir die Funktion Flush() aufrufen. Indem dies hinzugefügt wird, nachdem jeder Block geschrieben wurde, kann der Client Blöcke empfangen, sobald sie bereit sind.
  2. Der Transfer-Encoding-Header wird automatisch vom HTTP-Writer verwaltet, sodass eine explizite Festlegung nicht erforderlich ist.

Überarbeitet Code

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

Überprüfung

Verwenden Sie Telnet, um eine Verbindung zum Server herzustellen:

$ 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

...

Jeder Block wird nach und nach empfangen als Der Server sendet sie.

Das obige ist der detaillierte Inhalt vonWarum sendet mein Go-HTTP-Server nicht nach und nach gebündelte Antworten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn