1
0
Fork 0
forked from boyska/circolog
circolog/http.go
boyska 66f32d1c05 refactor: now Hub keeps everything
before this there was some hidden race condition because raceCondition
is not concurrent-safe, and there was some concurrent reading and
writing.
Now everything is handled safely by the Hub.

Client now have "options" which are understood by the Hub to handle
them differently.
2018-08-23 01:04:31 +02:00

81 lines
1.7 KiB
Go

package main
import (
"net/http"
"time"
"github.com/gorilla/websocket"
"gopkg.in/mcuadros/go-syslog.v2/format"
)
func setupHttp(hub Hub) {
http.HandleFunc("/", getHTTPHandler(hub))
http.HandleFunc("/ws", getWSHandler(hub))
}
func getHTTPHandler(hub Hub) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
client := Client{
Messages: make(chan format.LogParts),
Nofollow: true}
hub.Register <- client
for x := range client.Messages {
logmsg := x
if logmsg["message"] == nil {
continue
}
c := logmsg["message"].(string)
w.Write([]byte(c))
w.Write([]byte("\n"))
}
}
}
func getWSHandler(hub Hub) http.HandlerFunc {
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
return func(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return
}
client := Client{Messages: make(chan format.LogParts)}
hub.Register <- client
// Allow collection of memory referenced by the caller by doing all work in
// new goroutines.
go func(conn *websocket.Conn, c Client) {
defer func() {
hub.Unregister <- c
conn.Close()
}()
for {
select {
case message, ok := <-c.Messages:
conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
if !ok {
// The hub closed the channel.
conn.WriteMessage(websocket.CloseMessage, []byte{})
return
}
w, err := conn.NextWriter(websocket.TextMessage)
if err != nil {
return
}
if msg, ok := message["message"]; ok {
w.Write([]byte(msg.(string)))
}
if err := w.Close(); err != nil {
return
}
// TODO: ticker/ping
}
}
}(conn, client)
}
}