我需要向服务器发出请求,该服务器会在不同时间返回不同的响应。我的意思是,服务器生成不同的响应,这些响应需要不同的执行时间,因此服务器会在响应可用时立即返回响应。
我希望在服务器返回后立即在屏幕上打印(此刻,我已经解决了)这些响应。
直到现在我所能做的就是打印响应,但仅在服务器返回所有响应时。因此,如果第一个响应需要1秒,而最后一个响应需要10秒,我的代码需要等待10秒才能打印所有消息。
编辑:添加我的代码:
//Config is gotten from yml file
RestConfig = Config["rest"].(map[string]interface{})
ServerConfig = Config["server"].(map[string]interface{})
RequestUrl := ServerConfig["url"]
RequestReader := bytes.NewReader(body)
Request, _ := http.NewRequest("POST", RequestUrl.(string), RequestReader)
//AppendHeaders append the needing headers to the request
client.AppendHeaders(Request, RestConfig["headers"])
//the type of client.HttpClient is *http.Client
Response, _ := client.HttpClient.Do(Request)
//And to print in the screen
defer Response.Body.Close()
fmt.Println( "-> Receiving response:\n---\n" )
fmt.Println( Response , "\n---\n-> Response body:\n---\n")
body_resp, _ := ioutil.ReadAll(Response.Body)
fmt.Println( string(body_resp) )
fmt.Println( "\n--\n")
有办法吗?
非常感谢。
答案 0 :(得分:4)
最后我的代码是这样的:
package main
import (
"fmt"
"log"
"bytes"
"strings"
"bufio"
"net/http"
)
func main() {
var body = "The body"
RequestReader := bytes.NewReader([]byte(body))
req, err := http.NewRequest("POST", "the_url", RequestReader)
if err != nil {
log.Fatal(err)
}
req.Header.Add("Accept", "application/xml")
req.Header.Add("Content-Type", "application/xml")
req.Header.Add("AG-Authorization", "key")
req.Header.Add("AG-Forwarded-Hosts", "*")
resp, err := (&http.Client{}).Do(req)
if err != nil {
log.Fatal(err)
}
reader := bufio.NewReader(resp.Body)
message := ""
for {
line, err := reader.ReadBytes('\n')
if err != nil {
log.Fatal(err)
}
message = message + string(line)
if strings.Contains(message, "<!-- End mark for each message -->"){
fmt.Println(message)
message = ""
}
}
}
谢谢大家。
答案 1 :(得分:1)
context包是您正在寻找的。
context
包负责进程和服务器请求的信号取消和操作截止时间。这有两种公开方法:WithCancel
和WithTimeout
。与请求处理程序返回时通常会取消与传入请求关联的Context
。
对于您的具体情况,您可以使用WithTimeout
方法设置对后端服务器的请求的截止日期。
// WithTimeout returns a copy of parent whose Done channel is closed as soon as
// parent.Done is closed, cancel is called, or timeout elapses. The new
// Context's Deadline is the sooner of now+timeout and the parent's deadline, if
// any. If the timer is still running, the cancel function releases its
// resources.
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
以下是摘自https://blog.golang.org/context/server/server.go
的摘录timeout, err := time.ParseDuration(req.FormValue("timeout")) // set a time limit in your post
if err == nil {
// The request has a timeout, so create a context that is
// canceled automatically when the timeout expires.
ctx, cancel = context.WithTimeout(context.Background(), timeout)
} else {
ctx, cancel = context.WithCancel(context.Background())
}
defer cancel() // Cancel ctx as soon as handleSearch returns.
如需进一步阅读,请查看本文: https://blog.golang.org/context