Handling streaming HTTP responses

王林
Release: 2024-02-09 15:00:11
forward
493 people have browsed it

处理流式 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)

    }
}
Copy after login

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
}
Copy after login

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)
Copy after login

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

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!