Home  >  Article  >  Backend Development  >  How to set read callback for net/http GET request like using go-curl?

How to set read callback for net/http GET request like using go-curl?

WBOY
WBOYforward
2024-02-11 09:24:08308browse

如何像使用 go-curl 一样为 net/http GET 请求设置读取回调?

php editor Xigua will introduce you how to set read callbacks for net/http GET requests to achieve functions similar to go-curl. When using the net/http library to initiate a GET request, we can use the related methods of the http.Client and http.Request structures to set the read callback function. By setting the value of http.Response.Body to a custom structure that implements the io.Reader interface, we can perform callback operations while reading the response content. In this way, we can achieve more flexible and customized operations in the process of processing HTTP requests, improving the maintainability and scalability of the code.

Question content

We have a working golang program that can get snapshots/images from Dahua cameras. We would like to enhance this by adding a read callback function for the following URI - http://192.168.x.x/cgi-bin/eventManager.cgi?action=attach&codes=[VideoMotion]. This URI keeps the socket open from the camera side, through which the camera continuously sends events.

We tried to use go-curl because it supports registering read callbacks. However, this package does not support the MIPS architecture. Therefore, we cannot use it. Any advice/help would be helpful. Here is the working code for snapshot retrieval.

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/icholy/digest"
)

const (
    username = "xxxxx"
    password = "xxxxx"
    uri = "http://192.168.x.x/cgi-bin/snapshot.cgi"
)

func main() {
    client := &http.Client{
        Transport: &digest.Transport{
            Username: username,
            Password: password,
        },
    }

    resp, err := client.Get(uri)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        log.Fatalf("Error: Status code %d", resp.StatusCode)
    } else {
        fmt.Println("Snapshot fetched")
    }

    // Perform next steps
}

Workaround

It was my misunderstanding that the client.Get(uri) call was blocked. The following comment by @kotix made me rethink my code. After adding printing below client.Get(uri), confirm to continue execution.

This is the complete code to print an event when it arrives.

package main

import (
    "log"
    "net/http"
    "io"
    "github.com/icholy/digest"
)

const (
    username = "xxxx"
    password = "xxxx"
    uri = "http://192.168.x.xxx/cgi-bin/eventManager.cgi?action=attach&codes=[VideoMotion]"
)

func main() {
    client := &http.Client{
        Transport: &digest.Transport{
            Username: username,
            Password: password,
        },
    }

    resp, err := client.Get(uri)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    log.Print("Coming here");
    if resp.StatusCode != http.StatusOK {
        log.Fatalf("Error: Status code %d", resp.StatusCode)
    } else {
        buffer := make([]byte, 4096) // Adjust the buffer size as needed

        for {
            n, err := resp.Body.Read(buffer)
            if err != nil && err != io.EOF {
                log.Fatal(err)
            }

            if n > 0 {
                // Process the chunk of data
                bodyString := string(buffer[:n])
                log.Print(bodyString)
            }

            if err == io.EOF {
                break
            }
        }
    }
}

The above is the detailed content of How to set read callback for net/http GET request like using go-curl?. 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