mirror of
https://github.com/datarhei/core.git
synced 2025-10-05 07:57:13 +08:00
111 lines
2.4 KiB
Go
111 lines
2.4 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/datarhei/core/v16/http/api"
|
|
"github.com/datarhei/core/v16/log"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
)
|
|
|
|
// The EventsHandler type provides handler functions for retrieving details
|
|
// about the API version and build infos.
|
|
type EventsHandler struct {
|
|
events log.ChannelWriter
|
|
}
|
|
|
|
// NewEvents returns a new About type
|
|
func NewEvents(events log.ChannelWriter) *EventsHandler {
|
|
return &EventsHandler{
|
|
events: events,
|
|
}
|
|
}
|
|
|
|
// Events returns a stream of event
|
|
// @Summary Stream of events
|
|
// @Description Stream of event of whats happening in the core
|
|
// @ID events
|
|
// @Tags v16.?.?
|
|
// @Accept text/event-stream
|
|
// @Accept json-stream
|
|
// @Produce text/event-stream
|
|
// @Produce json-stream
|
|
// @Param filters body []api.EventFilter false "Event filters"
|
|
// @Success 200 {object} api.Event
|
|
// @Security ApiKeyAuth
|
|
// @Router /api/v3/events [post]
|
|
func (h *EventsHandler) Events(c echo.Context) error {
|
|
ticker := time.NewTicker(5 * time.Second)
|
|
defer ticker.Stop()
|
|
|
|
req := c.Request()
|
|
|
|
contentType := "text/event-stream"
|
|
accept := req.Header.Get(echo.HeaderAccept)
|
|
if strings.Contains(accept, "application/x-json-stream") {
|
|
contentType = "application/x-json-stream"
|
|
}
|
|
|
|
res := c.Response()
|
|
|
|
res.Header().Set(echo.HeaderContentType, contentType+"; charset=UTF-8")
|
|
res.Header().Set(echo.HeaderCacheControl, "no-store")
|
|
res.WriteHeader(http.StatusOK)
|
|
|
|
evts, cancel := h.events.Subscribe()
|
|
defer cancel()
|
|
|
|
enc := json.NewEncoder(res)
|
|
enc.SetIndent("", "")
|
|
|
|
done := make(chan struct{})
|
|
|
|
event := api.Event{}
|
|
|
|
if contentType == "text/event-stream" {
|
|
res.Write([]byte(":keepalive\n\n"))
|
|
res.Flush()
|
|
|
|
for {
|
|
select {
|
|
case <-done:
|
|
return nil
|
|
case <-ticker.C:
|
|
res.Write([]byte(":keepalive\n\n"))
|
|
res.Flush()
|
|
case e := <-evts:
|
|
event.Marshal(&e)
|
|
res.Write([]byte("event: " + strings.ToLower(event.Component) + "\ndata: "))
|
|
if err := enc.Encode(event); err != nil {
|
|
close(done)
|
|
}
|
|
res.Write([]byte("\n"))
|
|
res.Flush()
|
|
}
|
|
}
|
|
} else {
|
|
res.Write([]byte("{\"event\": \"keepalive\"}\n"))
|
|
res.Flush()
|
|
|
|
for {
|
|
select {
|
|
case <-done:
|
|
return nil
|
|
case <-ticker.C:
|
|
res.Write([]byte("{\"event\": \"keepalive\"}\n"))
|
|
res.Flush()
|
|
case e := <-evts:
|
|
event.Marshal(&e)
|
|
if err := enc.Encode(event); err != nil {
|
|
close(done)
|
|
}
|
|
res.Flush()
|
|
}
|
|
}
|
|
}
|
|
}
|