You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
caddy-hugo2/deltas.go

106 lines
1.8 KiB

package caddyhugo
import (
"fmt"
"net/http"
"time"
"git.stephensearles.com/stephen/acedoc"
"github.com/gorilla/websocket"
)
const (
IdleWebsocketTimeout = 10 * time.Minute
WebsocketFileTicker = 1 * time.Second
)
func (ch *CaddyHugo) ObserveLTime(ltime uint64) uint64 {
ch.mtx.Lock()
if ch.ltime < ltime {
ch.ltime = ltime
}
ch.mtx.Unlock()
return ch.LTime()
}
func (ch *CaddyHugo) LTime() uint64 {
ch.mtx.Lock()
defer ch.mtx.Unlock()
ch.ltime++
return ch.ltime
}
func (ch *CaddyHugo) DeltaWebsocket(w http.ResponseWriter, r *http.Request) (int, error) {
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
fmt.Println(err)
return http.StatusBadRequest, err
}
doc, err := ch.doc(r)
if err != nil {
fmt.Println(err)
return http.StatusBadRequest, err
}
const idlePing = 15 * time.Second
const idlePingShort = 1 * time.Millisecond
var timer *time.Timer
timer = time.AfterFunc(idlePing, func() {
conn.WriteJSON(Message{
Deltas: []acedoc.Delta{},
LTime: ch.LTime(),
})
timer.Reset(idlePing)
})
client := doc.doc.Client(acedoc.DeltaHandlerFunc(func(ds []acedoc.Delta) error {
timer.Reset(idlePing)
err := conn.WriteJSON(Message{
Deltas: ds,
LTime: ch.LTime(),
})
return err
}))
ch.mtx.Lock()
doc.clients++
ch.mtx.Unlock()
defer func() {
ch.mtx.Lock()
client.Close()
doc.clients--
ch.mtx.Unlock()
}()
for {
var message Message
err := conn.ReadJSON(&message)
if err != nil {
return http.StatusBadRequest, err
}
ch.ObserveLTime(message.LTime)
timer.Reset(idlePingShort)
err = client.PushDeltas(message.Deltas...)
if err != nil {
return http.StatusBadRequest, err
}
}
}
type Message struct {
Deltas []acedoc.Delta `json:"deltas"`
LTime uint64 `json:"ltime"`
}