package events import ( "errors" "net/http" "time" "git.quimbo.fr/odwrtw/canape/backend/auth" "git.quimbo.fr/odwrtw/canape/backend/users" "git.quimbo.fr/odwrtw/canape/backend/web" "github.com/gorilla/websocket" ) const ( // Ping every 30 seconds, must be less than pongWait pingWait = 30 * time.Second // Time allowed to read the next pong message from the client pongWait = 35 * time.Second // Time allowed to write to the client writeWait = 30 * time.Second ) // WsHandler handles the websockets messages func WsHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error { // Get the user v := auth.GetCurrentUser(r, env.Log) user, ok := v.(*users.User) if !ok { return env.RenderError(w, errors.New("invalid user type")) } upgrader := websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, } // Upgrade the request for websockets ws, err := upgrader.Upgrade(w, r, nil) if err != nil { env.Log.Warnf("got error upgrading request: %+v", err) if _, ok := err.(websocket.HandshakeError); !ok { env.Log.Warn("handshake error") } return err } defer ws.Close() // The pong handler only postpone the read deadline ws.SetPongHandler(func(string) error { ws.SetReadDeadline(time.Now().Add(pongWait)) return nil }) // Channel where the eventers will write events to serverEventStream := make(chan ServerEvent) // Channel where the eventers will write errors to serverErrorStream := make(chan ServerError) events := map[string]Eventer{ "torrents": &TorrentNotifier{ Notifier: NewNotifier(serverEventStream, serverErrorStream), user: user, log: env.Log, }, } c := channel{ serverEventStream: serverEventStream, serverErrorStream: serverErrorStream, done: make(chan struct{}, 1), conn: ws, log: env.Log, events: events, } // Launch the go routine responsible for writing events in the websocket go c.writer() // Launch the reader responsible for reading events from the websocket c.reader() return nil }