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.
107 lines
1.8 KiB
107 lines
1.8 KiB
7 years ago
|
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"`
|
||
|
}
|