diff --git a/main.go b/main.go
index 1782cc6..5a2880e 100644
--- a/main.go
+++ b/main.go
@@ -19,13 +19,11 @@ import (
"flag"
"html/template"
"io"
- "math/rand"
"mime"
"net/http"
_ "net/http/pprof"
"os"
"runtime"
- "strconv"
"strings"
"time"
@@ -222,11 +220,6 @@ func indexHandler(w http.ResponseWriter, r *http.Request) {
}
httpSession.Save(r, w)
- // create a Wide session
- rand.Seed(time.Now().UnixNano())
- sid := strconv.Itoa(rand.Int())
- wideSession := session.WideSessions.New(httpSession, sid)
-
user := conf.GetUser(username)
if nil == user {
logger.Warnf("Not found user [%s]", username)
@@ -241,7 +234,7 @@ func indexHandler(w http.ResponseWriter, r *http.Request) {
wideSessions := session.WideSessions.GetByUsername(username)
model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(locale), "locale": locale,
- "session": wideSession, "latestSessionContent": user.LatestSessionContent,
+ "username": username, "sid": session.WideSessions.GenId(), "latestSessionContent": user.LatestSessionContent,
"pathSeparator": conf.PathSeparator, "codeMirrorVer": conf.CodeMirrorVer,
"user": user, "editorThemes": conf.GetEditorThemes(), "crossPlatforms": util.Go.GetCrossPlatforms()}
diff --git a/playground/playgrounds.go b/playground/playgrounds.go
index cd0af41..c2d4f53 100644
--- a/playground/playgrounds.go
+++ b/playground/playgrounds.go
@@ -54,11 +54,6 @@ func IndexHandler(w http.ResponseWriter, r *http.Request) {
username := httpSession.Values["username"].(string)
- // create a wide session
- rand.Seed(time.Now().UnixNano())
- sid := strconv.Itoa(rand.Int())
- wideSession := session.WideSessions.New(httpSession, sid)
-
locale := conf.Wide.Locale
// try to load file
@@ -92,8 +87,9 @@ func IndexHandler(w http.ResponseWriter, r *http.Request) {
}
model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(locale), "locale": locale,
- "session": wideSession, "pathSeparator": conf.PathSeparator, "codeMirrorVer": conf.CodeMirrorVer,
- "code": template.HTML(code), "ver": conf.WideVersion, "year": time.Now().Year(),
+ "sid": session.WideSessions.GenId(), "pathSeparator": conf.PathSeparator,
+ "codeMirrorVer": conf.CodeMirrorVer,
+ "code": template.HTML(code), "ver": conf.WideVersion, "year": time.Now().Year(),
"embed": embed, "disqus": disqus, "fileName": fileName}
wideSessions := session.WideSessions.GetByUsername(username)
diff --git a/session/sessions.go b/session/sessions.go
index f5132ce..3043723 100644
--- a/session/sessions.go
+++ b/session/sessions.go
@@ -25,6 +25,7 @@ package session
import (
"bytes"
"encoding/json"
+ "math/rand"
"net/http"
"os"
"path/filepath"
@@ -193,21 +194,6 @@ func (f userReports) Less(i, j int) bool { return f[i].processCnt > f[j].process
// When a channel closed, releases all resources associated with it.
func WSHandler(w http.ResponseWriter, r *http.Request) {
sid := r.URL.Query()["sid"][0]
- 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)
- }
conn, _ := websocket.Upgrade(w, r, nil, 1024, 1024)
wsChan := util.WSChannel{Sid: sid, Conn: conn, Request: r, Time: time.Now()}
@@ -220,6 +206,22 @@ func WSHandler(w http.ResponseWriter, r *http.Request) {
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{}{}
@@ -297,114 +299,11 @@ func (s *WideSession) Refresh() {
s.Updated = time.Now()
}
-// New creates a wide session.
-func (sessions *wSessions) New(httpSession *sessions.Session, sid string) *WideSession {
- mutex.Lock()
- defer mutex.Unlock()
+// GenId generates a wide session id.
+func (sessions *wSessions) GenId() string {
+ rand.Seed(time.Now().UnixNano())
- username := httpSession.Values["username"].(string)
- now := time.Now()
-
- ret := &WideSession{
- ID: sid,
- Username: username,
- HTTPSession: httpSession,
- EventQueue: nil,
- State: sessionStateActive,
- Content: &conf.LatestSessionContent{},
- Created: now,
- Updated: now,
- }
-
- *sessions = append(*sessions, ret)
-
- if "playground" == username {
- return ret
- }
-
- // create user event queue
- ret.EventQueue = event.UserEventQueues.New(sid)
-
- // add a filesystem watcher to notify front-end after the files changed
- watcher, err := fsnotify.NewWatcher()
- if err != nil {
- logger.Error(err)
-
- return ret
- }
-
- go func() {
- defer util.Recover()
-
- for {
- ch := SessionWS[sid]
- if nil == ch {
- return // release this gorutine
- }
-
- select {
- case event := <-watcher.Events:
- path := event.Name
- dir := filepath.Dir(path)
-
- ch = SessionWS[sid]
- if nil == ch {
- return // release this gorutine
- }
-
- logger.Debug(event)
-
- if event.Op&fsnotify.Create == fsnotify.Create {
- if err = watcher.Add(path); nil != err {
- logger.Warn(err, path)
- }
-
- logger.Tracef("File watcher added a file [%s]", path)
-
- cmd := map[string]interface{}{"path": path, "dir": dir, "cmd": "create-file"}
- ch.WriteJSON(&cmd)
- } else if event.Op&fsnotify.Remove == fsnotify.Remove {
- cmd := map[string]interface{}{"path": path, "dir": dir, "cmd": "remove-file"}
- ch.WriteJSON(&cmd)
-
- } else if event.Op&fsnotify.Rename == fsnotify.Rename {
- cmd := map[string]interface{}{"path": path, "dir": dir, "cmd": "rename-file"}
- ch.WriteJSON(&cmd)
- }
- case err := <-watcher.Errors:
- if nil != err {
- logger.Error("File watcher ERROR: ", err)
- }
- }
- }
- }()
-
- go func() {
- defer util.Recover()
-
- workspaces := filepath.SplitList(conf.GetUserWorkspace(username))
- for _, workspace := range workspaces {
- filepath.Walk(filepath.Join(workspace, "src"), func(dirPath string, f os.FileInfo, err error) error {
- if ".git" == f.Name() { // XXX: discard other unconcered dirs
- return filepath.SkipDir
- }
-
- if f.IsDir() {
- if err = watcher.Add(dirPath); nil != err {
- logger.Error(err, dirPath)
- }
-
- logger.Tracef("File watcher added a dir [%s]", dirPath)
- }
-
- return nil
- })
- }
-
- ret.FileWatcher = watcher
- }()
-
- return ret
+ return strconv.Itoa(rand.Int())
}
// Get gets a wide session with the specified session id.
@@ -505,3 +404,111 @@ func (sessions *wSessions) GetByUsername(username string) []*WideSession {
return ret
}
+
+// new creates a wide session.
+func (sessions *wSessions) new(httpSession *sessions.Session, sid string) *WideSession {
+ mutex.Lock()
+ defer mutex.Unlock()
+
+ username := httpSession.Values["username"].(string)
+ now := time.Now()
+
+ ret := &WideSession{
+ ID: sid,
+ Username: username,
+ HTTPSession: httpSession,
+ EventQueue: nil,
+ State: sessionStateActive,
+ Content: &conf.LatestSessionContent{},
+ Created: now,
+ Updated: now,
+ }
+
+ *sessions = append(*sessions, ret)
+
+ if "playground" == username {
+ return ret
+ }
+
+ // create user event queue
+ ret.EventQueue = event.UserEventQueues.New(sid)
+
+ // add a filesystem watcher to notify front-end after the files changed
+ watcher, err := fsnotify.NewWatcher()
+ if err != nil {
+ logger.Error(err)
+
+ return ret
+ }
+
+ go func() {
+ defer util.Recover()
+
+ for {
+ ch := SessionWS[sid]
+ if nil == ch {
+ return // release this gorutine
+ }
+
+ select {
+ case event := <-watcher.Events:
+ path := event.Name
+ dir := filepath.Dir(path)
+
+ ch = SessionWS[sid]
+ if nil == ch {
+ return // release this gorutine
+ }
+
+ logger.Trace(event)
+
+ if event.Op&fsnotify.Create == fsnotify.Create {
+ if err = watcher.Add(path); nil != err {
+ logger.Warn(err, path)
+ }
+
+ cmd := map[string]interface{}{"path": path, "dir": dir, "cmd": "create-file"}
+ ch.WriteJSON(&cmd)
+ } else if event.Op&fsnotify.Remove == fsnotify.Remove {
+ cmd := map[string]interface{}{"path": path, "dir": dir, "cmd": "remove-file"}
+ ch.WriteJSON(&cmd)
+
+ } else if event.Op&fsnotify.Rename == fsnotify.Rename {
+ cmd := map[string]interface{}{"path": path, "dir": dir, "cmd": "rename-file"}
+ ch.WriteJSON(&cmd)
+ }
+ case err := <-watcher.Errors:
+ if nil != err {
+ logger.Error("File watcher ERROR: ", err)
+ }
+ }
+ }
+ }()
+
+ go func() {
+ defer util.Recover()
+
+ workspaces := filepath.SplitList(conf.GetUserWorkspace(username))
+ for _, workspace := range workspaces {
+ filepath.Walk(filepath.Join(workspace, "src"), func(dirPath string, f os.FileInfo, err error) error {
+ if ".git" == f.Name() { // XXX: discard other unconcered dirs
+ return filepath.SkipDir
+ }
+
+ if f.IsDir() {
+ if err = watcher.Add(dirPath); nil != err {
+ logger.Error(err, dirPath)
+ }
+
+ logger.Tracef("File watcher added a dir [%s]", dirPath)
+ }
+
+ return nil
+ })
+ }
+
+ ret.FileWatcher = watcher
+ }()
+
+ return ret
+}
diff --git a/shell/shells.go b/shell/shells.go
index 5938152..b1d8dd8 100644
--- a/shell/shells.go
+++ b/shell/shells.go
@@ -17,12 +17,10 @@ package shell
import (
"html/template"
- "math/rand"
"net/http"
"os"
"os/exec"
"runtime"
- "strconv"
"strings"
"time"
@@ -57,16 +55,11 @@ func IndexHandler(w http.ResponseWriter, r *http.Request) {
}
httpSession.Save(r, w)
- // create a wide session
- rand.Seed(time.Now().UnixNano())
- sid := strconv.Itoa(rand.Int())
- wideSession := session.WideSessions.New(httpSession, sid)
-
username := httpSession.Values["username"].(string)
locale := conf.GetUser(username).Locale
model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(locale), "locale": locale,
- "session": wideSession}
+ "sid": session.WideSessions.GenId()}
wideSessions := session.WideSessions.GetByUsername(username)
diff --git a/static/js/notification.js b/static/js/notification.js
index df5fc43..e595fd8 100644
--- a/static/js/notification.js
+++ b/static/js/notification.js
@@ -55,7 +55,7 @@ var notification = {
};
notificationWS.onerror = function (e) {
- console.log('[notification onerror] ' + JSON.parse(e));
+ console.log('[notification onerror]');
};
}
};
\ No newline at end of file
diff --git a/static/js/session.js b/static/js/session.js
index 5e08678..5720554 100644
--- a/static/js/session.js
+++ b/static/js/session.js
@@ -186,7 +186,7 @@ var session = {
$(".notification-count").show();
};
sessionWS.onerror = function (e) {
- console.log('[session onerror] ' + JSON.parse(e));
+ console.log('[session onerror]');
};
}
};
\ No newline at end of file
diff --git a/static/js/wide.js b/static/js/wide.js
index ed1bbd4..48249d1 100644
--- a/static/js/wide.js
+++ b/static/js/wide.js
@@ -540,7 +540,7 @@ var wide = {
console.log('[output onclose] disconnected (' + e.code + ')');
};
outputWS.onerror = function (e) {
- console.log('[output onerror] ' + e);
+ console.log('[output onerror]');
};
},
_initFooter: function () {
@@ -812,8 +812,8 @@ $(document).ready(function () {
tree.init();
menu.init();
hotkeys.init();
- notification.init();
session.init();
+ notification.init();
editors.init();
windows.init();
bottomGroup.init();
diff --git a/views/index.html b/views/index.html
index 4b9aed2..ed449da 100644
--- a/views/index.html
+++ b/views/index.html
@@ -30,7 +30,7 @@
-
+
@@ -613,7 +613,7 @@
"pathSeparator": '{{.pathSeparator}}',
"label": {{.i18n}},
"channel": {{.conf.Channel}},
- "wideSessionId": '{{.session.ID}}',
+ "wideSessionId": '{{.sid}}',
"editorTheme": '{{.user.Editor.Theme}}',
"latestSessionContent": {{.latestSessionContent}},
"editorTabSize": '{{.user.Editor.TabSize}}',
diff --git a/views/playground/index.html b/views/playground/index.html
index f0301e1..b22a86d 100644
--- a/views/playground/index.html
+++ b/views/playground/index.html
@@ -100,7 +100,7 @@
"server": "{{.conf.Server}}",
"staticServer": "{{.conf.StaticServer}}",
"channel": "{{.conf.Channel}}",
- "wideSessionId": "{{.session.ID}}",
+ "wideSessionId": "{{.sid}}",
"label": {{.i18n}},
"autocomplete": {{.conf.Autocomplete}},
"embed": {{.embed}},
diff --git a/views/shell.html b/views/shell.html
index 6d9a3d1..3fd5a77 100644
--- a/views/shell.html
+++ b/views/shell.html
@@ -24,7 +24,7 @@
channel: {
shell: '{{.conf.ShellChannel}}'
},
- wideSessionId: {{.session.ID}}
+ wideSessionId: {{.sid}}
};