Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,32 @@ docker compose up --build
docker compose run auth-cli /app/auth-cli-bin -action create -username demo-user
```

### Access Grafana dashboard: localhost:3002/d/realtime-metrics-dashboard
### Connect to the services to start playing

Using websocat for the example but you can use any other tool of your preference
```
websocat ws://localhost:3000/publish -H "Authorization: Bearer {JTW_TOKEN}"

websocat ws://localhost:3001/subscribe -H "Authorization: Bearer {JTW_TOKEN}"
```

### To access metrics dashboard click in the following link: [Metrics Dashboard](http://localhost:3002/d/realtime-metrics-dashboard)

### Demo

Build and run the project:
```
docker compose up --build
```

##### Obtain a JWT token and run demo container

Linux:
```
JWT_TOKEN=$(docker compose run --rm auth-cli /app/auth-cli-bin -action create -username demo-user | grep "generated JWT" | awk -F': ' '{print $2}') && docker compose run --rm -e JWT_TOKEN="$JWT_TOKEN" demo /app/demo-bin
```

Windows Powershell:
```
$JWT_TOKEN = (docker compose run --rm auth-cli /app/auth-cli-bin -action create -username demo-user | Select-String "generated JWT" | ForEach-Object { $_.Line -replace ".*: ", "" }); docker compose run --rm -e JWT_TOKEN=$JWT_TOKEN demo /app/demo-bin
```
101 changes: 101 additions & 0 deletions demo/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package main

import (
"fmt"
"log"
"net/http"
"os"
"sync"
"time"

"github.com/gorilla/websocket"
)

const (
publisherURL = "ws://publisher:3000/publish"
subscribeURL = "ws://subscriber:3001/subscribe"
messageInterval = 1 * time.Second
maxMessages = 10
)

func main() {
jwtToken := os.Getenv("JWT_TOKEN")
if jwtToken == "" {
log.Fatalf("JWT_TOKEN environment variable not set")
}

var wg sync.WaitGroup

// wait for subscriber to connect and to be ready
wg.Add(1)
go startSubscriber(jwtToken, &wg)
wg.Wait()

publishMessages(jwtToken, &wg)

// wait for all messages to be received
wg.Wait()

log.Println("Demo completed: all 10 messages sent and received")
}

func connectWebSocket(url, jwtToken string) (*websocket.Conn, error) {
dialer := websocket.Dialer{}
header := http.Header{}
header.Set("Authorization", fmt.Sprintf("Bearer %s", jwtToken))

conn, _, err := dialer.Dial(url, header)
if err != nil {
return nil, fmt.Errorf("failed to connect to WebSocket endpoint %s: %v", url, err)
}
return conn, nil
}

func startSubscriber(jwtToken string, wg *sync.WaitGroup) {
conn, err := connectWebSocket(subscribeURL, jwtToken)
if err != nil {
log.Fatalf("failed to connect to subscribe endpoint: %v", err)
}
defer conn.Close()

log.Println("connected to subscribe ws, waiting for messages...")
wg.Done()

count := 0
for {
_, message, err := conn.ReadMessage()
if err != nil {
log.Printf("ws read error: %v", err)
break
}
fmt.Printf("received message from subscribe: %s\n", string(message))
count++
if count == maxMessages {
wg.Done()
break
}
}
}

func publishMessages(jwtToken string, wg *sync.WaitGroup) {
conn, err := connectWebSocket(publisherURL, jwtToken)
if err != nil {
log.Fatalf("failed to connect to publish ws: %v", err)
}
defer conn.Close()

wg.Add(1)
for i := range [maxMessages]int{} {
message := fmt.Sprintf("demo message #%d", i)
fmt.Printf("sending message: %s\n", message)

err := conn.WriteMessage(websocket.TextMessage, []byte(message))
if err != nil {
log.Printf("failed to send message via publish WebSocket: %v", err)
} else {
log.Println("message published successfully")
}

time.Sleep(messageInterval)
}
}
7 changes: 7 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,10 @@ services:
build:
context: .
dockerfile: docker/auth-cli/Dockerfile
demo:
build:
context: .
dockerfile: docker/demo/Dockerfile
depends_on:
- publisher
- subscriber
10 changes: 10 additions & 0 deletions docker/demo/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM golang:1.24.2-alpine

WORKDIR /app

COPY demo/ ./demo
COPY go.mod go.sum ./

RUN go mod download

RUN CGO_ENABLED=0 GOOS=linux go build -o demo-bin -ldflags "-s -w" ./demo/