implemented SSE logic
This commit is contained in:
@@ -2,17 +2,17 @@
|
||||
<body>
|
||||
<div class="container-fluid h-100 d-flex flex-column">
|
||||
<div class="row output flex-grow-1">
|
||||
<div class="col-3 left-sidebar" hx-sse="connect:/sse/status" hx-swap="innerHTML">
|
||||
<div class="col-3 left-sidebar" hx-sse="connect:/sse on:status" hx-swap="innerHTML">
|
||||
Status <br>
|
||||
Last Compilation <br>
|
||||
Such Info <br>
|
||||
Much wow
|
||||
</div>
|
||||
<div class="col-9 p-0">
|
||||
<iframe class="pdf-frame" src="servetex.pdf?ts=0" hx-sse="connect:/sse/pdf" hx-swap="outerHTML"></iframe>
|
||||
<iframe class="pdf-frame" src="servetex.pdf?ts=0" hx-sse="connect:/sse on:pdf" hx-swap="outerHTML"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
<div class="command-out" hx-sse="connect:/sse/status" hx-swap="innerHTML">
|
||||
<div class="command-out" hx-sse="connect:/sse on:output" hx-swap="innerHTML">
|
||||
compile start
|
||||
compile file-x
|
||||
compile file-y
|
||||
|
||||
@@ -1,32 +1,91 @@
|
||||
package frontend
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"fmt"
|
||||
"time"
|
||||
"strings"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"git.noctra.dev/noctra/servtex/backend"
|
||||
"git.noctra.dev/noctra/servtex/globals"
|
||||
)
|
||||
|
||||
// Publishes Meta Information relating to last execution
|
||||
// Does not use contained Mutex, ignore warning
|
||||
func SSEStatus(writer http.ResponseWriter, request *http.Request) {
|
||||
writer.Header().Set("Content-Type", "text/event-stream")
|
||||
writer.Header().Set("Cache-Control", "no-cache")
|
||||
writer.Header().Set("Connection", "keep-alive")
|
||||
|
||||
fmt.Fprintf(writer, "data: Execution Time: %s\n", globals.LatexExec.Timestamp)
|
||||
fmt.Fprintf(writer, "data: Execution State: %s\n\n", globals.LatexExec.ExecutionState)
|
||||
|
||||
writer.(http.Flusher).Flush()
|
||||
// Adds necessary Headers for SSE
|
||||
func sseHeadersAdd(writer *http.ResponseWriter) {
|
||||
(*writer).Header().Set("Content-Type", "text/event-stream")
|
||||
(*writer).Header().Set("Cache-Control", "no-cache")
|
||||
(*writer).Header().Set("Connection", "keep-alive")
|
||||
}
|
||||
|
||||
func SSEOutput(writer http.ResponseWriter, request *http.Request) {
|
||||
writer.Header().Set("Content-Type", "text/event-stream")
|
||||
writer.Header().Set("Cache-Control", "no-cache")
|
||||
writer.Header().Set("Connection", "keep-alive")
|
||||
// Sends a Ping to keep the connection alive
|
||||
func ssePing(writer *http.ResponseWriter) {
|
||||
sseHeadersAdd(writer)
|
||||
|
||||
fmt.Fprintf(writer, "data: Execution Time: %s\n", globals.LatexExec.Timestamp)
|
||||
fmt.Fprintf(writer, "data: Execution State: %s\n\n", globals.LatexExec.ExecutionState)
|
||||
fmt.Fprintf((*writer), ": ping\n\n")
|
||||
|
||||
writer.(http.Flusher).Flush()
|
||||
(*writer).(http.Flusher).Flush()
|
||||
}
|
||||
|
||||
// Sends new Event
|
||||
//
|
||||
// Reads globals.LatexExec
|
||||
func sseStatusSend(writer *http.ResponseWriter) {
|
||||
sseHeadersAdd(writer)
|
||||
|
||||
fmt.Fprintf((*writer), "event: status\n")
|
||||
fmt.Fprintf((*writer), "data: Execution Time: %s\n", globals.LatexExec.Timestamp)
|
||||
fmt.Fprintf((*writer), "data: Execution State: %s\n\n", globals.LatexExec.ExecutionState)
|
||||
|
||||
(*writer).(http.Flusher).Flush()
|
||||
}
|
||||
|
||||
// Sends new Event
|
||||
//
|
||||
// Reads globals.LatexExec
|
||||
func ssePDFSend(writer *http.ResponseWriter) {
|
||||
sseHeadersAdd(writer)
|
||||
|
||||
fmt.Fprintf((*writer), "event: pdf\n")
|
||||
iframe := fmt.Sprintf(
|
||||
`<iframe class="pdf-frame" src="servetex.pdf?ts=%s" hx-sse="connect:/sse/pdf" hx-swap="outerHTML"></iframe>`,
|
||||
url.QueryEscape(backend.GetLocalTimeRFC()),
|
||||
)
|
||||
fmt.Fprintf((*writer), "data: %s\n\n", iframe)
|
||||
|
||||
(*writer).(http.Flusher).Flush()
|
||||
}
|
||||
|
||||
// Sends new Event
|
||||
//
|
||||
// Reads globals.LatexExec
|
||||
func sseOutputSend(writer *http.ResponseWriter) {
|
||||
sseHeadersAdd(writer)
|
||||
|
||||
fmt.Fprintf((*writer), "event: output\n")
|
||||
lines := strings.SplitSeq(string(globals.LatexExec.Output), "\n")
|
||||
for line := range lines {
|
||||
fmt.Fprintf((*writer), "data: %s\n", line)
|
||||
}
|
||||
fmt.Fprintf((*writer), "\n")
|
||||
|
||||
(*writer).(http.Flusher).Flush()
|
||||
}
|
||||
|
||||
// Server Side Event Handler
|
||||
//
|
||||
// Sends a Ping instead of actual data when no new data available to save bandwidth
|
||||
func SSEEventSender(writer http.ResponseWriter, request *http.Request) {
|
||||
lastExecution := ""
|
||||
for range time.Tick(time.Second) {
|
||||
if lastExecution == globals.LatexExec.Timestamp {
|
||||
ssePing(&writer)
|
||||
} else {
|
||||
sseStatusSend(&writer)
|
||||
ssePDFSend(&writer)
|
||||
sseOutputSend(&writer)
|
||||
// comment out for testing purposes
|
||||
lastExecution = globals.LatexExec.Timestamp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user