Transmitting gob encoded data

The encoding/gob package provides us with the functionality to manage streams of gobs, which are binary values exchanged between an encoder and a decoder. You use the encoder to encode a value into gob encoded data and you use the decoder to decode gob encoded data.

With Go on the server side and on the client-side, we have created a Go-specific environment, as shown in Figure 3.18This is an ideal environment to use the encoding/gob package, as a means for data exchange between the client and the server:

Figure 3.18: A Go-specific environment

The data that we will be transmitting consists of the cars slice. The Car struct can be considered isomorphic, since we can use the Car struct on both the client side and the server side.

Notice that in the cars.go source file, we have included the encoding/gob package (shown in bold) in our import groupings:

import (
"bytes"
"encoding/gob"
"html/template"

"github.com/EngineerKamesh/igb/igweb/shared/models"

"honnef.co/go/js/dom"
"honnef.co/go/js/xhr"
)

We encode the cars slice to the gob format using the following code:

  var carsDataBuffer bytes.Buffer
enc := gob.NewEncoder(&carsDataBuffer)
enc.Encode(cars)

Here we have declared a bytes buffer called carsDataBuffer that will contain the gob encoded data. We created a new gob encoder, and specified that we want to store the encoded data into carsDataBuffer. We then called the Encode method on our gob encoder object, and passed in the cars slice. At this point, we have encoded the cars slice into carsDataBuffer.

Now that we have encoded the cars slice into the gob format, we can transmit the gob encoded data to the server over an XHR call using the HTTP POST method:

  xhrResponse, err := xhr.Send("POST", "/cars-data", carsDataBuffer.Bytes())

if err != nil {
println(err)
}

println("xhrResponse: ", string(xhrResponse))

We call the Send function in the xhr package, and specify that we want to use the POST method, and will be sending the data to the /cars-data URL. We call the Bytes method on the carsDataBuffer to get the representation of the buffer as a byte slice. It is this byte slice that we will send off to the server, and it is the gob encoded car slice.

The response from the server will be stored in the xhrResponse variable, and we will print this variable out in the web console.
Now that we've seen the client-side of our program, it's time to take a look at the server-side handler function that services the /cars-data route. Let's examine the CarsDataHandler function defined in the carsdata.go source file found in the handlers directory:

func CarsDataHandler(env *common.Env) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

var cars []models.Car
var carsDataBuffer bytes.Buffer

dec := gob.NewDecoder(&carsDataBuffer)
body, err := ioutil.ReadAll(r.Body)
carsDataBuffer = *bytes.NewBuffer(body)
err = dec.Decode(&cars)

w.Header().Set("Content-Type", "text/plain")

if err != nil {
log.Println(err)
w.Write([]byte("Something went wrong, look into it"))

} else {
fmt.Printf("Cars Data: %#v ", cars)
w.Write([]byte("Thanks, I got the slice of cars you sent me!"))
}

})
}

Inside the CarsDataHandler function, we declare the cars variable, which is a slice of Car objects. Right below this, we have carsDataBuffer, which will contain the gob encoded data that we receive from the XHR call that was sent from the client-side web application.

We create a new gob decoder and we specify that the gob data will be stored in carsDataBuffer. We then use the ReadAll function from the ioutil package to read the request body and to save all the contents to the body variable.

We then create a new bytes buffer and pass in the body variable as the input argument to the NewBuffer function. The carsDataBuffer now contains the gob encoded data that was transmitted over the XHR call. Finally, we make a call to the Decode function of the dec object to convert the gob encoded data back into a slice of the Car objects.

If we didn't receive any errors, we print out the cars slice to standard out:

Cars Data: []models.Car{models.Car{ModelName:"Nano", Color:"Yellow", Manufacturer:"Tata"}, models.Car{ModelName:"Ambassador", Color:"White", Manufacturer:"HM"}, models.Car{ModelName:"Omni", Color:"Red", Manufacturer:"Maruti Suzuki"}}

In addition to printing the cars slice to standard out, we write a response back to the web client indicating that the slice of cars has been received successfully. We can view this message in the web browser console:

Figure 3.19: The server response to the web client
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.82.4