// WSHandler handles request of creating session channel. // // When a channel closed, releases all resources associated with it. func WSHandler(w http.ResponseWriter, r *http.Request) { sid := r.URL.Query()["sid"][0] conn, _ := websocket.Upgrade(w, r, nil, 1024, 1024) wsChan := util.WSChannel{Sid: sid, Conn: conn, Request: r, Time: time.Now()} ret := map[string]interface{}{"output": "Session initialized", "cmd": "init-session"} err := wsChan.WriteJSON(&ret) if nil != err { return } SessionWS[sid] = &wsChan wSession := WideSessions.Get(sid) if nil == wSession { httpSession, _ := HTTPSession.Get(r, "wide-session") if httpSession.IsNew { return } httpSession.Options.MaxAge = conf.Wide.HTTPSessionMaxAge httpSession.Save(r, w) wSession = WideSessions.new(httpSession, sid) logger.Tracef("Created a wide session [%s] for websocket reconnecting, user [%s]", sid, wSession.Username) } logger.Tracef("Open a new [Session Channel] with session [%s], %d", sid, len(SessionWS)) input := map[string]interface{}{} for { if err := wsChan.ReadJSON(&input); err != nil { logger.Tracef("[Session Channel] of session [%s] disconnected, releases all resources with it, user [%s]", sid, wSession.Username) WideSessions.Remove(sid) return } ret = map[string]interface{}{"output": "", "cmd": "session-output"} if err := wsChan.WriteJSON(&ret); err != nil { logger.Error("Session WS ERROR: " + err.Error()) return } wsChan.Time = time.Now() } }
// WSHandler handles request of creating session channel. // // When a channel closed, releases all resources associated with it. func WSHandler(w http.ResponseWriter, r *http.Request) { sid := r.URL.Query()["sid"][0] conn, _ := websocket.Upgrade(w, r, nil, 1024, 1024) wsChan := util.WSChannel{Sid: sid, Conn: conn, Request: r, Time: time.Now()} ret := map[string]interface{}{"output": "Session initialized", "cmd": "init-session"} err := wsChan.WriteJSON(&ret) if nil != err { return } SessionWS[sid] = &wsChan wSession := WideSessions.Get(sid) if nil == wSession { httpSession, _ := HTTPSession.Get(r, "wide-session") if httpSession.IsNew { return } httpSession.Options.MaxAge = conf.Wide.HTTPSessionMaxAge httpSession.Save(r, w) wSession = WideSessions.new(httpSession, sid) logger.Tracef("Created a wide session [%s] for websocket reconnecting, user [%s]", sid, wSession.Username) } logger.Tracef("Open a new [Session Channel] with session [%s], %d", sid, len(SessionWS)) input := map[string]interface{}{} wsChan.Conn.SetReadDeadline(time.Now().Add(pongWait)) wsChan.Conn.SetPongHandler(func(string) error { wsChan.Conn.SetReadDeadline(time.Now().Add(pongWait)); return nil }) ticker := time.NewTicker(pingPeriod) defer func() { WideSessions.Remove(sid) ticker.Stop() wsChan.Close() }() // send websocket ping message. go func(t *time.Ticker, channel util.WSChannel) { for { select { case <-t.C: if err := channel.Conn.WriteMessage(websocket.PingMessage, []byte{}); err != nil { return } } } }(ticker, wsChan) for { if err := wsChan.ReadJSON(&input); err != nil { logger.Tracef("[Session Channel] of session [%s] disconnected, releases all resources with it, user [%s]", sid, wSession.Username) return } ret = map[string]interface{}{"output": "", "cmd": "session-output"} if err := wsChan.WriteJSON(&ret); err != nil { logger.Error("Session WS ERROR: " + err.Error()) return } wsChan.Time = time.Now() } }
func editorWSHandler(w http.ResponseWriter, r *http.Request) { httpSession, _ := httpSessionStore.Get(r, "coditor-session") userSession := httpSession.Values[user_session] if nil == userSession { http.Error(w, "Forbidden", http.StatusForbidden) return } sid := r.URL.Query()["sid"][0] cSession := coditorSessions.get(sid) if nil == cSession { return } conn, _ := websocket.Upgrade(w, r, nil, 1024, 1024) wsChan := util.WSChannel{Sid: sid, Conn: conn, Request: r, Time: time.Now()} ret := map[string]interface{}{"editor": "Editor initialized", "cmd": "init-editor"} err := wsChan.WriteJSON(&ret) if nil != err { return } editorWS[sid] = &wsChan logger.Tracef("Open a new [Editor] with session [%s], %d", sid, len(editorWS)) input := map[string]interface{}{} userName := coditorSessions.get(sid).Username for { if err := wsChan.ReadJSON(&input); err != nil { return } //logger.Trace(input) docName := input["docName"].(string) docName = filepath.Clean(docName) doc := documentHolder.getDoc(docName) err := doc.setContent(input["content"].(string), userName) if err != nil { // TODO maybe should send error here logger.Errorf("set document error %v", err) continue } for _, cursor := range doc.cursors { if cursor.Sid == sid { // skip the current session itself continue } content := input["content"].(string) ret = map[string]interface{}{"content": content, "cmd": "changes", "docName": docName, "user": input["user"], "cursor": input["cursor"], "color": input["color"]} if err := editorWS[cursor.Sid].WriteJSON(&ret); err != nil { logger.Error("[Editor Channel] ERROR: " + err.Error()) return } } wsChan.Time = time.Now() } }