now a single websocket is opened from the webui to converge.

The browser sends a hello message anytime the user switches to the
sessions page, upon which the server sends the current state back.
THis also improves the timeout handling of broken connecions.
This commit is contained in:
Erik Brakkee 2024-08-12 23:44:07 +02:00
parent 8ef0785165
commit df9409fc75
3 changed files with 31 additions and 8 deletions

View File

@ -59,9 +59,23 @@ func (sessions *WebSessions) NewSession(wsConnection net.Conn, ctx context.Conte
conn: wsConnection, conn: wsConnection,
ctx: ctx, ctx: ctx,
} }
go func() {
for {
// the web app opens one websocket connection and sends a hello
// message asking for the latest state when a page is loaded that requires this.
// Minor issue at this time is that a notification is sent twice to the client.
p := make([]byte, 1024)
_, err := wsConnection.Read(p)
if err == nil {
session.notifications <- sessions.lastNotification
} else {
log.Printf("Got error reading %v", err)
return
}
}
}()
sessions.sessions[session] = true sessions.sessions[session] = true
sessions.logSessions() sessions.logSessions()
session.notifications <- sessions.lastNotification
return session return session
} }
@ -70,7 +84,6 @@ func GetUserLocation(r *http.Request) (*time.Location, error) {
if tzName == "" { if tzName == "" {
tzName = r.Header.Get("X-Timezone") tzName = r.Header.Get("X-Timezone")
} }
//log.Println("GetUserLocation: timezone ", tzName)
if tzName == "" { if tzName == "" {
tzName = "UTC" tzName = "UTC"
} }
@ -89,10 +102,7 @@ func (session *WebSession) WriteNotifications(location *time.Location, cancel co
log.Println("channel closed") log.Println("channel closed")
return return
} }
//log.Println("Got notification: ", notification) if session.writeNotificationToClient(location, notification) {
err := templates.State(notification, location).Render(context.Background(), session.conn)
if err != nil {
log.Printf("WS connection closed: %v", err)
return return
} }
case <-timer.C: case <-timer.C:
@ -105,6 +115,15 @@ func (session *WebSession) WriteNotifications(location *time.Location, cancel co
} }
} }
func (session *WebSession) writeNotificationToClient(location *time.Location, notification *models.State) bool {
err := templates.State(notification, location).Render(context.Background(), session.conn)
if err != nil {
log.Printf("WS connection closed: %v", err)
return true
}
return false
}
func (sessions *WebSessions) SessionClosed(session *WebSession) { func (sessions *WebSessions) SessionClosed(session *WebSession) {
sessions.mutex.Lock() sessions.mutex.Lock()
defer sessions.mutex.Unlock() defer sessions.mutex.Unlock()

View File

@ -30,7 +30,7 @@ templ BasePage(tab int) {
<title>Converge</title> <title>Converge</title>
</head> </head>
<body hx-boost="true"> <body hx-boost="true" hx-ext="ws" ws-connect="../ws/sessions">
<div id="banner"> <div id="banner">
<img src="../static/images/wamblee_logo.png" /> <img src="../static/images/wamblee_logo.png" />
<span class="title fs-4"> <span class="title fs-4">

View File

@ -8,7 +8,11 @@ import (
templ Sessions(state *models.State, loc *time.Location) { templ Sessions(state *models.State, loc *time.Location) {
<div hx-ext="ws" ws-connect="../ws/sessions"> <div>
<div ws-send
hx-trigger="load"
hx-vals='{"message": "Hello, server! Page loaded."}'>
</div>
<h1>sessions</h1> <h1>sessions</h1>
<div id="status"> <div id="status">