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
Freigeben: 2024-12-09 09:21:09
Original
159 Leute haben es durchsucht

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")
}
Nach dem Login kopieren

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))
}
Nach dem Login kopieren

Ü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

...
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage