switched to SSE transport, seems to work
This commit is contained in:
+50
-5
@@ -29,6 +29,7 @@ type ChatMessage struct {
|
||||
|
||||
var global_msg_id uint64 = 0 /* track global message ID */
|
||||
var message_transport chan ChatMessage /* global message channel */
|
||||
var sse_transports []chan string /* SSE output channels */
|
||||
var bro webview.WebView /* global browser instance handle */
|
||||
|
||||
/* escape HTML entities in JS parameters */
|
||||
@@ -50,12 +51,20 @@ func appendChatMessages() {
|
||||
global_msg_id += 1
|
||||
msg.Id = global_msg_id
|
||||
|
||||
/* directly call the append function on the JS side */
|
||||
fmt_str := "gooseAppendMessage('%d', '%s', '%s', '%s', '%s', '%s');"
|
||||
js := fmt.Sprintf(fmt_str, msg.Id, esc(msg.Type), esc(msg.Timestamp), esc(msg.Username), esc(msg.Text), esc(msg.Icon))
|
||||
log.Printf("Evaluating JS: %s", js)
|
||||
bro.Eval(js)
|
||||
/* TODO any additional message logging should be done at this point! */
|
||||
|
||||
/* serialize the message and send it to the SSE channel */
|
||||
json_msg, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
log.Println("Error serializing the message:", err)
|
||||
}
|
||||
|
||||
/* broadcast the message across the clients */
|
||||
for _, transport := range sse_transports {
|
||||
if transport != nil {
|
||||
transport <- string(json_msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +82,40 @@ func msgAddHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("{\"status\": 1}")) /* respond with a status */
|
||||
}
|
||||
|
||||
/* GET /sse handler */
|
||||
func sseHandler(w http.ResponseWriter, r *http.Request) {
|
||||
/* prepare the headers */
|
||||
w.Header().Set("Content-Type", "text/event-stream")
|
||||
w.Header().Set("Cache-Control", "no-cache")
|
||||
w.Header().Set("Connection", "keep-alive")
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
|
||||
/* create the channel */
|
||||
transport := make(chan string)
|
||||
/* append it to the broadcast list */
|
||||
sse_transports = append(sse_transports, transport)
|
||||
|
||||
/* close the channel after exiting the function */
|
||||
defer func() {
|
||||
close(transport)
|
||||
transport = nil
|
||||
}()
|
||||
|
||||
/* use HTTP response flusher */
|
||||
flusher, _ := w.(http.Flusher)
|
||||
|
||||
/* message loop */
|
||||
for {
|
||||
select {
|
||||
case message := <-transport:
|
||||
fmt.Fprintf(w, "data: %s\n\n", message)
|
||||
flusher.Flush()
|
||||
case <-r.Context().Done(): /* handle disconnects */
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* entry point */
|
||||
func main() {
|
||||
config_path := "config.json"
|
||||
@@ -100,6 +143,8 @@ func main() {
|
||||
go func() { /* start the server thread */
|
||||
/* serve the POST /new */
|
||||
http.HandleFunc("/new", msgAddHandler)
|
||||
/* serve the GET /sse */
|
||||
http.HandleFunc("/sse", sseHandler)
|
||||
/* serve the webroot directory */
|
||||
fs := http.FileServer(http.Dir("./webroot"))
|
||||
http.Handle("/", fs)
|
||||
|
||||
@@ -57,3 +57,12 @@ function gooseAppendMessage(id, type, timestamp, username, text, icon) {
|
||||
/* autoscroll to the end */
|
||||
window.scrollTo(0, document.body.scrollHeight)
|
||||
}
|
||||
|
||||
/* entry point, set up an event source */
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
var msgSource = new EventSource('/sse')
|
||||
msgSource.onmessage = e => {
|
||||
var msg = JSON.parse(e.data)
|
||||
gooseAppendMessage(msg.id, msg.type, msg.timestamp, msg.username, msg.text, msg.icon)
|
||||
}
|
||||
}, false)
|
||||
|
||||
Reference in New Issue
Block a user