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 global_msg_id uint64 = 0 /* track global message ID */
|
||||||
var message_transport chan ChatMessage /* global message channel */
|
var message_transport chan ChatMessage /* global message channel */
|
||||||
|
var sse_transports []chan string /* SSE output channels */
|
||||||
var bro webview.WebView /* global browser instance handle */
|
var bro webview.WebView /* global browser instance handle */
|
||||||
|
|
||||||
/* escape HTML entities in JS parameters */
|
/* escape HTML entities in JS parameters */
|
||||||
@@ -50,12 +51,20 @@ func appendChatMessages() {
|
|||||||
global_msg_id += 1
|
global_msg_id += 1
|
||||||
msg.Id = global_msg_id
|
msg.Id = global_msg_id
|
||||||
|
|
||||||
/* directly call the append function on the JS side */
|
/* TODO any additional message logging should be done at this point! */
|
||||||
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)
|
|
||||||
|
|
||||||
|
/* 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 */
|
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 */
|
/* entry point */
|
||||||
func main() {
|
func main() {
|
||||||
config_path := "config.json"
|
config_path := "config.json"
|
||||||
@@ -100,6 +143,8 @@ func main() {
|
|||||||
go func() { /* start the server thread */
|
go func() { /* start the server thread */
|
||||||
/* serve the POST /new */
|
/* serve the POST /new */
|
||||||
http.HandleFunc("/new", msgAddHandler)
|
http.HandleFunc("/new", msgAddHandler)
|
||||||
|
/* serve the GET /sse */
|
||||||
|
http.HandleFunc("/sse", sseHandler)
|
||||||
/* serve the webroot directory */
|
/* serve the webroot directory */
|
||||||
fs := http.FileServer(http.Dir("./webroot"))
|
fs := http.FileServer(http.Dir("./webroot"))
|
||||||
http.Handle("/", fs)
|
http.Handle("/", fs)
|
||||||
|
|||||||
@@ -57,3 +57,12 @@ function gooseAppendMessage(id, type, timestamp, username, text, icon) {
|
|||||||
/* autoscroll to the end */
|
/* autoscroll to the end */
|
||||||
window.scrollTo(0, document.body.scrollHeight)
|
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