J'essaie d'envoyer un message JSON avec Go. Voici le code du serveur :
func (network *Network) Join(
w http.ResponseWriter,
r *http.Request) {
//the request is not interesting
//the response will be a message with just the clientId value set
log.Println("client wants to join")
message := Message{-1, -1, -1, ClientId(len(network.Clients)), -1, -1}
var buffer bytes.Buffer
enc := json.NewEncoder(&buffer)
err := enc.Encode(message)
if err != nil {
fmt.Println("error encoding the response to a join request")
log.Fatal(err)
}
fmt.Printf("the json: %s\n", buffer.Bytes())
fmt.Fprint(w, buffer.Bytes())
}
Le réseau est une structure personnalisée. Dans la fonction principale, je crée un objet réseau et j'enregistre ses méthodes en tant que callbacks de http.HandleFunc(...).
func main() {
runtime.GOMAXPROCS(2)
var network = new(Network)
var clients = make([]Client, 0, 10)
network.Clients = clients
log.Println("starting the server")
http.HandleFunc("/request", network.Request)
http.HandleFunc("/update", network.GetNews)
http.HandleFunc("/join", network.Join)
log.Fatal(http.ListenAndServe("localhost:5000", nil))
}
Le message est aussi une structure. Il possède six champs, tous d'un type alias int. Lorsqu'un client envoie une requête http GET à l'url "localhost:5000/join", voici ce qui devrait se passer
- La méthode Join sur l'objet réseau est appelée
- Un nouvel objet Message avec un Id pour le client est créé.
- Ce message est codé en JSON
- Pour vérifier si l'encodage est correct, le message encodé est imprimé sur l'écran cmd
- Le message est écrit dans le ResponseWriter.
Le client est assez simple. Il a exactement le même code pour la structure Message. Dans la fonction principale, il envoie simplement une requête GET à "localhost:5000/join" et essaie de décoder la réponse. Voici le code
func main() {
// try to join
var clientId ClientId
start := time.Now()
var message Message
resp, err := http.Get("http://localhost:5000/join")
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
dec := json.NewDecoder(resp.Body)
err = dec.Decode(&message)
if err != nil {
fmt.Println("error decoding the response to the join request")
log.Fatal(err)
}
fmt.Println(message)
duration := time.Since(start)
fmt.Println("connected after: ", duration)
fmt.Println("with clientId", message.ClientId)
}
J'ai démarré le serveur, j'ai attendu quelques secondes puis j'ai lancé le client. Voici le résultat
- Le serveur imprime "le client veut se joindre"
- Le serveur imprime "the json : {"What":-1, "Tag":-1, "Id":-1, "ClientId":0, "X":-1, "Y":-1}".
- Le client imprime "200 OK"
- Le client se plante "erreur de décodage de la réponse à la demande de jointure".
- L'erreur est "caractère invalide "3" après un élément de tableau".
Ce message d'erreur m'a vraiment dérouté. Après tout, nulle part dans mon json, il n'y a le chiffre 3. J'ai donc importé io/ioutil sur le client et j'ai simplement imprimé la réponse avec ce code
b, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("the json: %s\n", b)
Veuillez noter que la déclaration d'impression est la même que sur le serveur. Je m'attendais à voir mon JSON encodé. Au lieu de cela, j'ai obtenu ceci
- "200 OK"
- "le json : [123 34 87 104 97 116 ....]" la liste a continué pendant un long moment
Je suis nouveau sur Go et je ne sais pas si je l'ai fait correctement. Mais il semble que le code ci-dessus ait juste imprimé la tranche d'octets. Bizarre, sur le serveur la sortie a été convertie en une chaîne de caractères.
Je suppose que je lis les mauvaises données ou que le message a été corrompu lors de son passage entre le serveur et le client. Mais honnêtement, ce ne sont que des suppositions.