Using Chunks to Send Data Sequentially from a Go Server
When creating an HTTP server in Go, it may be useful to send a response in chunks, allowing data to be sent gradually as it's retrieved. This enables clients to receive data in a sequential manner.
However, if a client is only receiving chunks at the end of a predetermined duration, or if Go is automatically setting the Content-Length header, it can be frustrating. To rectify this, we need to delve into the nuances of chunked HTTP responses in Go.
Firstly, it's important to remember that the Transfer-Encoding header is implicitly handled by Go's HTTP response writer. Therefore, you don't need to set it explicitly.
The key to achieving sequential chunk delivery lies in using Flusher.Flush(). By calling this method after each chunk is written, we trigger "chunked" encoding and send the data to the client. This ensures that the client receives each chunk as it's ready.
Here's an example of how to implement this technique:
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)) }
By using this approach, you can ensure that your Go HTTP server sends chunks sequentially, allowing clients to receive data in a timely manner. Additionally, it's essential to remember that http.ResponseWriters support concurrent access for use by multiple goroutines. This allows you to send chunks from different threads or goroutines if necessary.
The above is the detailed content of How to Send Data Sequentially in Chunks from a Go HTTP Server?. For more information, please follow other related articles on the PHP Chinese website!