Skip to content

Instantly share code, notes, and snippets.

@ClaesBas
Last active January 25, 2025 08:59
Show Gist options
  • Select an option

  • Save ClaesBas/fda45cff7ab297a3c14b23066cf1b334 to your computer and use it in GitHub Desktop.

Select an option

Save ClaesBas/fda45cff7ab297a3c14b23066cf1b334 to your computer and use it in GitHub Desktop.
Adding an embedded NATS server to https://github.com/anoop9001/datastar-golang-example (you need to download/clone that repo and replace server.go and index.html)
<!doctype html>
<html>
<head>
<title> Datastar </title>
<script
type="module" defer src="https://cdn.jsdelivr.net/gh/starfederation/datastar@develop/bundles/datastar.js">
</script>
</head>
<body style="background-color:#FFFFFF" data-signals-show="true">
<h1> Datastar </h1>
<h2> A live stream of random UUIDs sent from the server (using NATS)</h2>
<br>
<br>
<div>
<p>This button action is entirely client side</p>
<button data-on-click="$show=!$show">Show or Hide Live Stream</button><br>
<br>
<div data-show="$show">
<p>
This feed is almost entirely server side.<br>
If you use the button to hide the feed, its still running in the background.<br>
<br>
And if you have the NATS client installed locally, you can see the messages sent from the server,<br>
with the command: <b><i>nats sub event</i></b>
</p>
<div id="feed_styles" style="font-size:20px;color:#0074D9">
<span id="feed" data-on-load="@get('/feed')"></span>
</div>
</div>
</div>
</body>
</html>
package main
// MARK: Imports
import (
"log"
"net/http"
"time"
"fmt"
"github.com/google/uuid"
"github.com/nats-io/nats-server/v2/server"
"github.com/nats-io/nats.go"
datastar "github.com/starfederation/datastar/sdk/go"
)
// MARK: Globals
var nc *nats.Conn
// MARK: feed()
func feed(w http.ResponseWriter, r *http.Request) {
sse := datastar.NewSSE(w, r)
// Subscribe to the "event" subject
nc.Subscribe(
"event",
func(msg *nats.Msg) {
//log.Printf("Received message: %s", string(msg.Data))
sse.MergeFragments(string(msg.Data))
},
)
// Keep the subscription active until the client closes the connection
select {}
}
// MARK: startFeed()
func startFeed() {
for {
id := uuid.New()
// Publish a message to the "event" subject
msg := fmt.Sprintf(
"<span id='feed'>%s | %s <span>",
id.String(),
time.Now().UTC(),
)
nc.Publish("event", []byte(msg))
time.Sleep(1 * time.Second)
}
}
// MARK: main()
func main() {
// Create an in-process NATS server
srv, err := server.NewServer(&server.Options{
NoLog: false, // Enable logging
Debug: true, // Enable debug logging
Trace: true, // Enable tracing
Host: "127.0.0.1",
Port: 4222,
})
if err != nil {
log.Fatal(err)
}
// Configure NATS server logger
srv.ConfigureLogger()
// Start the NATS server
go srv.Start()
// Wait for the server to be ready
for !srv.ReadyForConnections(1 * time.Second) {
time.Sleep(100 * time.Millisecond)
}
// Create a client connection to the NATS server
nc, err = nats.Connect("", nats.InProcessServer(srv))
if err != nil {
log.Fatal(err)
}
defer nc.Close()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "index.html")
})
http.HandleFunc("/feed", feed)
go startFeed()
// Start the HTTP server
log.Println("Starting HTTP server")
log.Fatal(http.ListenAndServe(":3000", nil))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment