diff options
Diffstat (limited to 'src/helsinki.at/rhrdtime')
-rw-r--r-- | src/helsinki.at/rhrdtime/rhrdtime.go | 84 |
1 files changed, 72 insertions, 12 deletions
diff --git a/src/helsinki.at/rhrdtime/rhrdtime.go b/src/helsinki.at/rhrdtime/rhrdtime.go index 58ba896..806e64e 100644 --- a/src/helsinki.at/rhrdtime/rhrdtime.go +++ b/src/helsinki.at/rhrdtime/rhrdtime.go @@ -37,13 +37,7 @@ import ( "github.com/tuxychandru/pubsub" ) -type timeUpdate struct { - Timestamp int64 `json:"timestamp"` - TZOffset int `json:"tz_offset"` - Week uint8 `json:"week"` -} - -func getTimeUpdate() []byte { +func getRDWeekAndOffset(t time.Time) (uint8, int) { // // This computes the current Rivendell Week based on the number // of weeks since epoch. @@ -64,15 +58,25 @@ func getTimeUpdate() []byte { loc, err := time.LoadLocation("Europe/Vienna") if err != nil { fmt.Println(err) - return []byte{'{', '}'} + return 0, 0 } - now := time.Now().In(loc) - _, offset := now.Zone() + t = t.In(loc) + _, offset := t.Zone() + + sEpoch := t.Unix() + int64(offset) + return uint8(math.Floor(math.Mod((((float64(sEpoch)+259200)/604800)+2), 4)) + 1), offset +} - sEpoch := now.Unix() + int64(offset) - week := uint8(math.Floor(math.Mod((((float64(sEpoch)+259200)/604800)+2), 4)) + 1) +type timeUpdate struct { + Timestamp int64 `json:"timestamp"` + TZOffset int `json:"tz_offset"` + Week uint8 `json:"week"` +} +func getTimeUpdate() []byte { + now := time.Now() + week, offset := getRDWeekAndOffset(now) update := timeUpdate{(now.Unix() * 1000) + int64(now.Nanosecond()/1000000), offset, week} update_json, err := json.Marshal(update) if err != nil { @@ -118,11 +122,67 @@ func handleTimeUpdateClient(w http.ResponseWriter, r *http.Request, ps *pubsub.P } } +type ntpMessage struct { + T1 int64 `json:"t1"` + T2 int64 `json:"t2"` + T3 int64 `json:"t3"` + T4 int64 `json:"t4"` + TZOffset int `json:"tz_offset"` + Week uint8 `json:"week"` +} + +func handleNTPClient(w http.ResponseWriter, r *http.Request, ps *pubsub.PubSub) { + ws, err := websocket.Upgrade(w, r, nil, 1024, 1024) + if _, ok := err.(websocket.HandshakeError); ok { + http.Error(w, "Not a websocket handshake", 400) + return + } else if err != nil { + fmt.Println(err) + return + } + fmt.Println("Client connected", ws.RemoteAddr()) + + for { + msgtype, msg, err := ws.ReadMessage() + if err != nil { + fmt.Println("Client connected", ws.RemoteAddr()) + return + } + now_t2 := time.Now() + if msgtype == websocket.TextMessage { + + var n ntpMessage + if err := json.Unmarshal(msg, &n); err != nil { + fmt.Println("mallformed NTP message", err) + continue + } + + n.T2 = (now_t2.Unix() * 1000) + int64(now_t2.Nanosecond()/1000000) + n.Week, n.TZOffset = getRDWeekAndOffset(now_t2) + + now_t3 := time.Now() + n.T3 = (now_t3.Unix() * 1000) + int64(now_t3.Nanosecond()/1000000) + + ntp_json, err := json.Marshal(n) + if err != nil { + fmt.Println(err) + continue + } + if err := ws.WriteMessage(websocket.TextMessage, ntp_json); err != nil { + return + } + } + } +} + func RunMartini(ps *pubsub.PubSub, addr string) { m := martini.Classic() m.Get("/time", func(w http.ResponseWriter, r *http.Request) { handleTimeUpdateClient(w, r, ps) }) + // m.Get("/ntp", func(w http.ResponseWriter, r *http.Request) { + // handleTimeUpdateClient(w, r, ps) + // }) m.RunOnAddr(addr) } |