Three weeks ago, I was given a challenge to develop simple web application using Go during weekend. I excitedly accepted it. I mean what could go wrong? I have readskimmed the docs and Go have a somewhat familiar syntax with C#/JavaScript.
As it turned out, I failed spectacularly. I badly overestimate how much I understand Go. So here I am, retracing back the Go path. I managed to borrow this book from NLB, “The Go Programming Language” as my main reference.
The first question that came to my mind is how to get Go installed on this blog server. It’s really easy.
wget https://dl.google.com/go/go1.13.linux-amd64.tar.gz
Then extract the archive to /usr/local:
tar -C /usr/local -xzf go1.13.linux-amd64.tar.gz
Then add the bin folder to $PATH
export PATH=$PATH:/usr/local/go/bin
Make it permanent by adding above line to your bash profile
echo "export PATH=\$PATH:/usr/local/go/bin" >> .bashrc
Reload the bash profile
source ~/.bashrc
Test that Go is running
go version
Now that Go is installed and running properly, I need to find a way to showcase whatever Go is doing in this blog. Luckily, it’s super easy to create a simple web server in Go.
import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/", handler) // each request calls handler log.Fatal(http.ListenAndServe("localhost:21000", nil)) } // handler echoes the Path component of the requested URL. func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path) }
Next, we link this Go webserver with NGINX by adding this lines to NGINX’s sites configuration
location /cgo-bin/ { valid_referers none blocked sodeve.net; if ($invalid_referer){ return 403; } proxy_pass http://127.0.0.1:21000/; proxy_redirect off; }
For any address under /cgo-bin/ 😀, NGINX will relay the request to Go’s server above.
Now we reached the part where we are generating the Lissajous curve. Below code is straight copy-pasted from the reference book above.
package main import ( "errors" "fmt" "image" "image/color" "image/gif" "log" "math" "math/rand" "net/http" ) func main() { http.HandleFunc("/lissajous", handleLissajous) log.Fatal(http.ListenAndServe("localhost:21000", nil)) } func handleLissajous(w http.ResponseWriter, r *http.Request) { var palette = []color.Color{color.White, color.Black} const ( whiteIndex = 0 // first color in palette blackIndex = 1 // next color in palette cycles = 5 // number of complete x oscillator revolutions res = 0.001 // angular resolution size = 100 // image canvas covers [-size .. + size] nframes = 64 // number of animation frames delay = 8 //delay between frames in 10ms units ) freq := rand.Float64() * 3.0 // relative frequency of y oscillator anim := gif.GIF{LoopCount: nframes} phase := 0.0 //phase difference for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) clr := uint8(1) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), clr) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(w, &anim) //ignore error }
The resulting Lissajous curve image is below (if no image shown below, it means my Go server is down 😛 ):
From here, we can play with the color:
And we can even use a user-defined gradient color:
Stay tune for my future adventure in Go!