implementing websocket

This commit is contained in:
Roland Osborne 2022-01-14 10:57:19 -08:00
parent 0b486318d4
commit bac890a660
2 changed files with 117 additions and 27 deletions

View File

@ -11,20 +11,44 @@ package databag
import ( import (
"log" "log"
"sync"
"net/http" "net/http"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"databag/internal/store"
) )
type accountRevision struct {
ProfileRevision int64
ContentRevision int64
ViewRevision int64
GroupRevision int64
LabelRevision int64
CardRevision int64
DialogueRevision int64
InsightRevision int64
}
var wsSync sync.Mutex;
var statusListener = make(map[uint][]chan<-accountRevision)
var upgrader = websocket.Upgrader{} var upgrader = websocket.Upgrader{}
func Status(w http.ResponseWriter, r *http.Request) { func Status(w http.ResponseWriter, r *http.Request) {
// accept websocket connection
conn, err := upgrader.Upgrade(w, r, nil) conn, err := upgrader.Upgrade(w, r, nil)
if err != nil { if err != nil {
log.Print("Error during connection upgradation:", err) log.Print("Status: failed upgrade connection", err)
return return
} }
defer conn.Close() defer conn.Close()
log.Println("CONNECTED")
// receive announce message
// open channel for revisions
c := make(chan accountRevision)
AddStatusListener(0, c);
for { for {
messageType, message, err := conn.ReadMessage() messageType, message, err := conn.ReadMessage()
if err != nil { if err != nil {
@ -38,4 +62,70 @@ func Status(w http.ResponseWriter, r *http.Request) {
break break
} }
} }
// close channel
RemoveStatusListener(0, c);
close(c);
} }
func SetStatus(act uint) {
// get revisions for the account
var rev accountRevision;
err := store.DB.Model(&Revision{}).Where("ID = ?", act).First(&rev).Error
if err != nil {
log.Println("SetStatus - failed to retrieve account revisions");
}
// lock access to statusListener
wsSync.Lock()
defer wsSync.Unlock();
// check if we have any listeners
chs, ok := statusListener[act]
if ok {
// notify all listeners
for _, ch := range chs {
ch <- rev
}
}
}
func AddStatusListener(act uint, ch chan<-accountRevision) {
// lock access to statusListener
wsSync.Lock()
defer wsSync.Unlock();
// check if account has listeners
chs, ok := statusListener[act]
if ok {
chs = append(chs, ch);
} else {
statusListener[act] = []chan<-accountRevision{ch}
}
}
func RemoveStatusListener(act uint, ch chan<-accountRevision) {
// lock access to statusListener
wsSync.Lock()
defer wsSync.Unlock();
// remove channel
chs, ok := statusListener[act]
if ok {
for i, c := range chs {
if ch == c {
if len(chs) == 1 {
delete(statusListener, act)
} else {
chs[i] = chs[len(chs)-1]
statusListener[act] = chs[:len(chs)-1]
}
}
}
}
}

View File

@ -56,14 +56,14 @@ type Account struct {
Description string Description string
Location string Location string
Image string Image string
profileRevision uint64 `gorm:"not null"` ProfileRevision int64 `gorm:"not null"`
contentRevision uint64 `gorm:"not null"` ContentRevision int64 `gorm:"not null"`
viewRevision uint64 `gorm:"not null"` ViewRevision int64 `gorm:"not null"`
groupRevision uint64 `gorm:"not null"` GroupRevision int64 `gorm:"not null"`
labelRevision uint64 `gorm:"not null"` LabelRevision int64 `gorm:"not null"`
cardRevision uint64 `gorm:"not null"` CardRevision int64 `gorm:"not null"`
dialogueRevision uint64 `gorm:"not null"` DialogueRevision int64 `gorm:"not null"`
insightRevision uint64 `gorm:"not null"` InsightRevision uint64 `gorm:"not null"`
Created int64 `gorm:"autoCreateTime"` Created int64 `gorm:"autoCreateTime"`
Apps []App Apps []App
} }