introduction
client-server architecture is one of the most common methods for building software, but have you ever wondered how they communicate? there are several communication techniques and one such is short polling
how does it work?
imagine this, you are bob and have a very annoying best friend, charlie, who asks for gossip every 2 seconds, if you have one you immediately share it with him and if you don't, you straight away send him back without sharing anything, and this is how short polling works, where you are the server and charlie is the client.
what is polling?
polling is the process where the computer or controlling device waits for an external device to check for its readiness or state.
assuming that this may have helped you to understand or maybe get a vague idea about short polling, but anyway, we will go further and understand short polling more briefly.
short polling.
short polling is a communication technique, where the client sends requests to the server at regular intervals. the server immediately responds either with the data or no data
note that here we can nearly achieve real-time communication without having a persistent connection, isn't that interesting? (it doesn't mean you ruin your friendship with charlie xD)
implementation
now let us take the same example and implement it in golang.
at first, we will create a simple server, that sends random news at random intervals.
server.go
package main
import (
"encoding/json"
"fmt"
"math/rand"
"net/http"
"sync"
"time"
)
var (
gossipMutex sync.Mutex
currentGossip string
)
var news = [...]string{
"Dumbledore dies in Harry Potter and the Half-Blood Prince.",
"Dark Vader is Luke's father.",
"Atreus Becomes A Playable Character in GoW Ragnarok",
"Mufasa Dies in The Lion King",
"Tyler Durden is the narrator in Fight Club",
}
func main() {
http.HandleFunc("/getGossip", getGossipHandler)
go generateRandomGossip()
fmt.Println("Server is listening on port 8080...")
http.ListenAndServe(":8080", nil)
}
func getGossipHandler(w http.ResponseWriter, r *http.Request) {
gossipMutex.Lock()
defer gossipMutex.Unlock()
// If there's no gossip, send an empty response
if currentGossip == "" {
response := map[string]string{"gossip": "no gossip"}
json.NewEncoder(w).Encode(response)
return
}
// Send current gossip to the client
response := map[string]string{"gossip": currentGossip}
json.NewEncoder(w).Encode(response)
// Clear the current gossip after sending
currentGossip = ""
}
func generateRandomGossip() {
for {
// Generate a random time between 1 to 10 seconds
randomTime := time.Duration(rand.Intn(10)+1) * time.Second
time.Sleep(randomTime)
gossipMutex.Lock()
currentGossip = fmt.Sprintf("Did you hear? %s", news[rand.Intn(len(news))])
gossipMutex.Unlock()
}
}
here, we created a handler getGossipHandler
, which generates random gossip using generateRandomGossip()
in which we have used rand.Intn(n int)
to generate random news at random intervals.
now create a client, which sends a request every 2 seconds and prints the received response.
client.go
package main
import (
"encoding/json"
"fmt"
"net/http"
"time"
)
func main() {
for {
// Poll the server for gossip every 2 seconds
getGossip()
time.Sleep(2 * time.Second)
}
}
func getGossip() {
resp, err := http.Get("http://localhost:8080/getGossip")
if err != nil {
fmt.Println("Error fetching gossip:", err)
return
}
defer resp.Body.Close()
var gossipData map[string]string
err = json.NewDecoder(resp.Body).Decode(&gossipData)
if err != nil {
fmt.Println("Error decoding gossip response:", err)
return
}
gossip := gossipData["gossip"]
fmt.Printf("Received Gossip: %s\n", gossip)
}
conclusion
as you might have guessed, there are so many requests fired to the server, which is a waste of resources and time, and also every time we send a request we create a new connection, so the question arises, how can we improve these shortcomings?
hope you find this article helpful, feel free to reach out at dev.riturajsingh@gmail.com
Top comments (0)