Home  >  Article  >  Backend Development  >  Handling streaming HTTP responses

Handling streaming HTTP responses

王林
王林forward
2024-02-09 15:00:11474browse

处理流式 HTTP 响应

php editor Zimo introduces you to the method of processing streaming HTTP responses. When developing web applications, we often need to deal with the downloading of large files or the transmission of real-time streaming media. The traditional method of loading the entire response content at once will cause excessive memory usage and affect performance. To solve this problem, we can use streaming HTTP responses. Streaming HTTP responses can transmit response content in chunks, reducing memory usage and improving user experience. In PHP, we can use some libraries or custom methods to implement streaming HTTP responses to optimize our web applications.

Question content

I have the following example, which connects to an HTTP service that streams the response back in chunks to create a JSON structure. For each block, my code appends a byte rb array and the individual lines. However, my problem is trying to resolve when rb is complete so that I can decode it.

Am I missing something obvious here?

package main

import (
    "bufio"
    "bytes"
    "fmt"
    "io"
    "net/http"
)

func main() {

    body := []byte("test")

    resp, err := http.Post("http://localhost:8281/tap", "application/json", bytes.NewReader(body))
    if err != nil {
        fmt.Printf("%v\n", err)
        return
    }
    defer resp.Body.Close()
    fmt.Printf("Status: [%s]\n", resp.Status)
    fmt.Println()
    //var rb []byte
    reader := bufio.NewReader(resp.Body)
    var rb []byte

    for {

        line, err := reader.ReadBytes('\n')
        if err != nil {
            if err == io.EOF {
                break
            }
            fmt.Printf("Error reading streamed bytes %v", err)
        }
        rb = append(rb, line...)

        fmt.Println(rb)

    }
}

Solution

Ignore the bug in the program, rbComplete after the loop is interrupted.

This program does have errors:

  • The program only breaks out of the loop when EOF occurs. If any other kind of error occurs, the program will spin forever.
  • The program does not handle the situation where ReadBytes returns data and errors. An example of where this might happen is if the response does not end with a delimiter.

Looks like your goal is to absorb the entire response to rb. Use io.ReadAll to do this:

resp, err := http.Post("http://localhost:8281/tap", "application/json", bytes.NewReader(body))
if err != nil {
    fmt.Printf("%v\n", err)
    return
}
defer resp.Body.Close()
rb, err := io.ReadAll(resp.Body)
if err != nil {
    // handle error
}
var data SomeType
err = json.Unmarshal(rb, &data)
if err != nil {
     // handle error
}

If you want to decode the response body to JSON, then a better way is to let the JSON decoder read the response body:

resp, err := http.Post("http://localhost:8281/tap", "application/json", bytes.NewReader(body))
if err != nil {
    fmt.Printf("%v\n", err)
    return
}
defer resp.Body.Close()
var data SomeType
err := json.NewDecoder(resp.Body).Decode(&data)

The above is the detailed content of Handling streaming HTTP responses. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete