converge/pkg/server/converge/websessions.go
Erik Brakkee f0dd810541 many small changes
* removed the Async utility
* now using Ping message to webclient for keep alive instaed of actual content
* added remote shell to AgentInfo
* retry of connections to the agent
* better logging for SynchronizeStreams
2024-07-31 19:30:38 +02:00

99 lines
2.1 KiB
Go

package converge
import (
"converge/pkg/models"
"log"
"net"
"sync"
"time"
)
type WebSessions struct {
mutex sync.Mutex
sessions map[*WebSession]bool
lastNotification *models.State
}
type WebSession struct {
notifications chan *models.State
conn net.Conn
}
func NewWebSessions(notifications chan *models.State) *WebSessions {
websessions := &WebSessions{
sessions: make(map[*WebSession]bool),
}
go func() {
for {
notification := <-notifications
websessions.notifyWebSessions(notification)
}
}()
return websessions
}
func (sessions *WebSessions) notifyWebSessions(notification *models.State) {
sessions.mutex.Lock()
defer sessions.mutex.Unlock()
sessions.lastNotification = notification
for session, _ := range sessions.sessions {
session.notifications <- notification
}
}
func (sessions *WebSessions) NewSession(wsConnection net.Conn) *WebSession {
sessions.mutex.Lock()
defer sessions.mutex.Unlock()
session := &WebSession{
notifications: make(chan *models.State, 10),
conn: wsConnection,
}
sessions.sessions[session] = true
sessions.logSessions()
session.notifications <- sessions.lastNotification
return session
}
func (session *WebSession) WriteNotifications() {
timer := time.NewTicker(10 * time.Second)
defer timer.Stop()
for {
select {
case notification, ok := <-session.notifications:
if !ok {
log.Println("channel closed")
}
log.Println("Got notification: ", notification.Ascii)
msg := `
<div id="mycontent">
<p>V1 ascii-art to be improved </p>
<pre>` + notification.Ascii + `</pre>
</div>`
_, err := session.conn.Write([]byte(msg))
if err != nil {
log.Printf("WS connection closed: %v", err)
return
}
case <-timer.C:
_, err := session.conn.Write(make([]byte, 0, 0))
if err != nil {
log.Printf("WS connection closed: %v", err)
return
}
}
}
}
func (sessions *WebSessions) SessionClosed(session *WebSession) {
sessions.mutex.Lock()
defer sessions.mutex.Unlock()
delete(sessions.sessions, session)
sessions.logSessions()
}
func (sessions *WebSessions) logSessions() {
log.Printf("Web session count %d", len(sessions.sessions))
}