ServerSentEventsServer/main.go

95 lines
2.1 KiB
Go

package main
import (
"bufio"
"fmt"
"os"
"time"
"clickandjoin.app/serversenteventsserver/modules/cache"
"clickandjoin.app/serversenteventsserver/modules/config"
"clickandjoin.app/serversenteventsserver/modules/rabbitmq"
"clickandjoin.app/serversenteventsserver/modules/structs"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
"github.com/valyala/fasthttp"
)
func init() {
config.LoadConfig()
if config.Cfg.Debug {
logrus.SetLevel(logrus.DebugLevel)
}
logrus.Println("Debug:", config.Cfg.Debug)
go rabbitmq.Init()
}
func main() {
app := fiber.New()
// wait so that rabbitmq can connect
// TODO: better way to handle this
time.Sleep(500 * time.Millisecond)
if len(os.Args) < 2 {
logrus.Fatalln("Please specify port")
}
// TODO: origin
// CORS for external resources
app.Use(cors.New(cors.Config{
AllowOrigins: "*",
AllowHeaders: "Cache-Control",
AllowCredentials: true,
}))
app.Get("/sse", func(c *fiber.Ctx) error {
c.Set("Content-Type", "text/event-stream")
c.Set("Cache-Control", "no-cache")
c.Set("Connection", "keep-alive")
c.Set("Transfer-Encoding", "chunked")
c.Context().SetBodyStreamWriter(fasthttp.StreamWriter(func(w *bufio.Writer) {
var sseclient structs.SSEClient
sseclient.MessageChan = make(chan structs.SSEClientChanMessage)
clientId := uuid.New()
cache.SSEClients[clientId] = sseclient
logrus.Debugln("NEW CLIENT ID:", clientId)
logrus.Debugln(len(cache.SSEClients), "CLIENTS CONNECTED")
for message := range sseclient.MessageChan {
fmt.Fprintf(w, "data: %s\n\n", message.Message)
err := w.Flush()
if err != nil {
// Refreshing page in web browser will establish a new
// SSE connection, but only (the last) one is alive, so
// dead connections must be closed here.
for id, sseClient := range cache.SSEClients {
if id == message.ClientId {
close(sseClient.MessageChan)
delete(cache.SSEClients, id)
logrus.Debugln("DELETE clientId:", id)
}
}
}
}
}))
return nil
})
app.Listen("127.0.0.1:" + os.Args[1])
}