I want to read full response from the server, but I don't know precise size of it.
I would expect this to work:
message, err := ioutil.ReadAll(conn)
But server is not sending EOF, so this statement just hangs.
I know its a JSON response, so I could read data until the last }, but that seems not the best way how it could be done.
What is the best practice to read full response?
update:
after some while I found out that it's possible this way:
var m map[string]interface{}
d := json.NewDecoder(conn)
d.Decode(&m)
for key, value := range m {
fmt.Print(key)
fmt.Print(" : ")
fmt.Print(value)
fmt.Print("
")
switch vv := value.(type) {
case map[string]interface{}:
for k, v := range vv {
fmt.Print(k)
fmt.Print(" : ")
fmt.Print(v)
fmt.Print("
")
}
}
}
Use a json.Decoder. Here's how to read multiple messages:
d := json.NewDecoder(conn)
for {
var m message // <-- use whatever type is appropriate for your app
err := d.Decode(&m)
if err == io.EOF {
break
} else if err != nil {
// handle error
}
// do something with m
}
Remove the loop if you expect exactly one message.
You want a json.Decoder
. The decoder is meant to read a stream of JSON objects. It reads from the stream until it receives a complete object, and then unmarshals it onto the provided object pointer.
Example:
package main
import (
"encoding/json"
"fmt"
"io"
)
func main() {
pr, pw := io.Pipe()
go pw.Write([]byte(`{"foo":"bar"}`))
var data map[string]string
json.NewDecoder(pr).Decode(&data)
fmt.Printf("Data: %v
", data)
}
https://play.golang.org/p/JQMXGzrDAH-
Which outputs:
Data: map[foo:bar]