When using WebSockets, a program must act as a server.

But there can be many other programs as clients. In this article, we will create a server and a client

WebSocket Server

The code of the server is very simple. Because we don’t want to reinvent the wheel, we will use the gobwas module

Below is the code of the WebSocket server running on port 8080

package main

import (
"fmt"
"github.com/gobwas/ws"
"github.com/gobwas/ws/wsutil"
"math/rand"
"net/http"
"strconv"
)

func main() {
fmt.Println("Server started, waiting for connection from client")
http.ListenAndServe(":8080", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("Client connected")
conn, _, _, err := ws.UpgradeHTTP(r, w)
if err != nil {
fmt.Println("Error starting socket server: "+ err.Error())
}
go func() {
defer conn.Close()
for {
msg, op, err := wsutil.ReadClientData(conn)
if err != nil {
fmt.Println("Error receiving data: "+ err.Error())
fmt.Println("Client disconnected")
return
}
fmt.Println("Client message received with random number: "+ string(msg))
randomNumber := strconv.Itoa(rand.Intn(100))
err = wsutil.WriteServerMessage(conn, op, []byte(randomNumber))
if err != nil {
fmt.Println("Error sending data: "+ err.Error())
fmt.Println("Client disconnected")
return
}
fmt.Println("Server message send with random number "+ randomNumber)
}
}()
}))
}

The server does nothing but waits for the connection, prints the received data and finally sends a message (random integer)

If the client disconnects (or someone stops the program), it will print information about this disconnect

WebSocket Client

The client code is similar. Similarly, we will use the gobwas module

The client is connecting to localhost on port 8080

package main

import (
"context"
"fmt"
"github.com/gobwas/ws"
"github.com/gobwas/ws/wsutil"
"math/rand"
"os"
"strconv"
"time"
)

func main() {
fmt.Println("Client started")
for {
conn, _, _, err := ws.DefaultDialer.Dial(context.Background(), "ws://127.0.0.1:8080/")
if err != nil {
fmt.Println("Cannot connect: "+ err.Error())
time.Sleep(time.Duration(5) * time.Second)
continue
}
fmt.Println("Connected to server")
for i := 0; i <10; i++ {
randomNumber := strconv.Itoa(rand.Intn(100))
msg := []byte(randomNumber)
err = wsutil.WriteClientMessage(conn, ws.OpText, msg)
if err != nil {
fmt.Println("Cannot send: "+ err.Error())
continue
}
fmt.Println("Client message send with random number "+ randomNumber)
msg, _, err := wsutil.ReadServerData(conn)
if err != nil {
fmt.Println("Cannot receive data: "+ err.Error())
continue
}
fmt.Println("Server message received with random number: "+ string(msg))
time.Sleep(time.Duration(5) * time.Second)
}
err = conn.Close()
if err != nil {
fmt.Println("Cannot close the connection: "+ err.Error())
os.Exit(1)
}
fmt.Println("Disconnected from server")
}
}

This client has nothing special other than connecting, sending a message (random integer) and printing whatever it sends back

test

On the left, server results
On the right, client results

image.png

The client sends a random number to the server every 5 seconds. The server replies with another random number

If you stop the server, you will see on the client that the server is disconnected. If you start the server again, the client will connect again.

You can expect the same behavior in another way. If the client is stopped, the server will print a message indicating that the client has been disconnected. If you run the client again... well, it connects again

Because Go is often used for services and/or microservices, it makes sense to communicate between these services

Likes(2)

Comment list count 0 Comments

No Comments