This commit is contained in:
parent
711f1943c9
commit
1b3ac8ad66
39
conf/wide.go
39
conf/wide.go
|
@ -17,12 +17,22 @@ import (
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
// 最后一次会话内容结构.
|
||||||
Name string
|
type LatestSessionContent struct {
|
||||||
Password string
|
FileTree []string // 文件树展开的路径集
|
||||||
Workspace string // 指定了该用户的 GOPATH 路径
|
Files []string // 编辑器打开的文件路径集
|
||||||
|
CurrentFile string // 当前编辑器文件路径
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 用户结构.
|
||||||
|
type User struct {
|
||||||
|
Name string
|
||||||
|
Password string
|
||||||
|
Workspace string // 指定了该用户的 GOPATH 路径
|
||||||
|
LatestSessionContent *LatestSessionContent
|
||||||
|
}
|
||||||
|
|
||||||
|
// 配置结构.
|
||||||
type conf struct {
|
type conf struct {
|
||||||
Server string
|
Server string
|
||||||
StaticServer string
|
StaticServer string
|
||||||
|
@ -37,12 +47,16 @@ type conf struct {
|
||||||
Users []*User
|
Users []*User
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 配置.
|
||||||
var Wide conf
|
var Wide conf
|
||||||
|
|
||||||
|
// 维护非变化部分的配置.
|
||||||
|
// 只有 Users 是会运行时变化的,保存回写文件时要使用这个变量.
|
||||||
var rawWide conf
|
var rawWide conf
|
||||||
|
|
||||||
// 定时检查 Wide 运行环境.
|
// 定时检查 Wide 运行环境.
|
||||||
// 如果是特别严重的问题(比如 $GOPATH 不存在)则退出进程,另一些不太严重的问题(比如 gocode 不存在)则放入全局通知队列.
|
// 如果是特别严重的问题(比如 $GOPATH 不存在)则退出进程,另一些不太严重的问题(比如 gocode 不存在)则放入全局通知队列.
|
||||||
func CheckEnv() {
|
func FixedTimeCheckEnv() {
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
if "" == os.Getenv("GOPATH") {
|
if "" == os.Getenv("GOPATH") {
|
||||||
|
@ -73,6 +87,19 @@ func CheckEnv() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 7 分钟进行一次检查环境
|
// TODO: 7 分钟进行一次检查环境
|
||||||
|
time.Sleep(time.Second * 7)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定时(10 分钟)保存配置.
|
||||||
|
// 主要是保存用户会话内容,以备下一次用户打开 Wide 时进行会话还原.
|
||||||
|
func FixedTimeSave() {
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
Save()
|
||||||
|
|
||||||
|
// TODO: 10 分钟进行一次配置保存
|
||||||
time.Sleep(time.Second * 10)
|
time.Sleep(time.Second * 10)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -124,7 +151,7 @@ func getGOBIN() string {
|
||||||
|
|
||||||
// 保存 Wide 配置.
|
// 保存 Wide 配置.
|
||||||
func Save() bool {
|
func Save() bool {
|
||||||
// 只有 Users 是可以通过界面修改的,其他属性只能手工维护 wide.json 配置文件
|
// 只有 Users 是会运行时变化的,其他属性只能手工维护 wide.json 配置文件
|
||||||
rawWide.Users = Wide.Users
|
rawWide.Users = Wide.Users
|
||||||
|
|
||||||
// 原始配置文件内容
|
// 原始配置文件内容
|
||||||
|
|
|
@ -13,7 +13,19 @@
|
||||||
{
|
{
|
||||||
"Name": "admin",
|
"Name": "admin",
|
||||||
"Password": "admin",
|
"Password": "admin",
|
||||||
"Workspace": "{pwd}/data/user_workspaces/admin"
|
"Workspace": "{pwd}/data/user_workspaces/admin",
|
||||||
|
"LatestSessionContent": {
|
||||||
|
"FileTree": [
|
||||||
|
"1/",
|
||||||
|
"2/"
|
||||||
|
],
|
||||||
|
"Files": [
|
||||||
|
"1.go",
|
||||||
|
"2.go",
|
||||||
|
"3.go"
|
||||||
|
],
|
||||||
|
"CurrentFile": "current file"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
6
main.go
6
main.go
|
@ -36,7 +36,10 @@ func init() {
|
||||||
conf.Load()
|
conf.Load()
|
||||||
|
|
||||||
// 定时检查运行环境
|
// 定时检查运行环境
|
||||||
conf.CheckEnv()
|
conf.FixedTimeCheckEnv()
|
||||||
|
|
||||||
|
// 定时保存配置
|
||||||
|
conf.FixedTimeSave()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 登录.
|
// 登录.
|
||||||
|
@ -158,6 +161,7 @@ func main() {
|
||||||
http.HandleFunc("/login", loginHandler)
|
http.HandleFunc("/login", loginHandler)
|
||||||
http.HandleFunc("/", indexHandler)
|
http.HandleFunc("/", indexHandler)
|
||||||
http.HandleFunc("/session/ws", session.WSHandler)
|
http.HandleFunc("/session/ws", session.WSHandler)
|
||||||
|
http.HandleFunc("/session/save", session.SaveContent)
|
||||||
|
|
||||||
// 运行相关
|
// 运行相关
|
||||||
http.HandleFunc("/build", output.BuildHandler)
|
http.HandleFunc("/build", output.BuildHandler)
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package session
|
package session
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -14,6 +15,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/event"
|
"github.com/b3log/wide/event"
|
||||||
"github.com/b3log/wide/util"
|
"github.com/b3log/wide/util"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
@ -42,13 +44,15 @@ var HTTPSession = sessions.NewCookieStore([]byte("BEYOND"))
|
||||||
|
|
||||||
// Wide 会话,对应一个浏览器 tab.
|
// Wide 会话,对应一个浏览器 tab.
|
||||||
type WideSession struct {
|
type WideSession struct {
|
||||||
Id string // 唯一标识
|
Id string // 唯一标识
|
||||||
HTTPSession *sessions.Session // 关联的 HTTP 会话
|
Username string // 用户名
|
||||||
Processes []*os.Process // 关联的进程集
|
HTTPSession *sessions.Session // 关联的 HTTP 会话
|
||||||
EventQueue *event.UserEventQueue // 关联的事件队列
|
Processes []*os.Process // 关联的进程集
|
||||||
State int // 状态
|
EventQueue *event.UserEventQueue // 关联的事件队列
|
||||||
Created time.Time // 创建时间
|
State int // 状态
|
||||||
Updated time.Time // 最近一次使用时间
|
Content *conf.LatestSessionContent // 最近一次会话内容
|
||||||
|
Created time.Time // 创建时间
|
||||||
|
Updated time.Time // 最近一次使用时间
|
||||||
}
|
}
|
||||||
|
|
||||||
type Sessions []*WideSession
|
type Sessions []*WideSession
|
||||||
|
@ -133,6 +137,56 @@ func WSHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 会话内容保存.
|
||||||
|
func SaveContent(w http.ResponseWriter, r *http.Request) {
|
||||||
|
data := map[string]interface{}{"succ": true}
|
||||||
|
defer util.RetJSON(w, r, data)
|
||||||
|
|
||||||
|
var args map[string]interface{}
|
||||||
|
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&args); err != nil {
|
||||||
|
glog.Error(err)
|
||||||
|
data["succ"] = false
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sid := args["sid"].(string)
|
||||||
|
|
||||||
|
wSession := WideSessions.Get(sid)
|
||||||
|
if nil == wSession {
|
||||||
|
data["succ"] = false
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
wSession.Content.CurrentFile = args["currentFile"].(string)
|
||||||
|
// TODO: Ugly
|
||||||
|
fileTree := args["fileTree"].([]interface{})
|
||||||
|
ft := []string{}
|
||||||
|
for _, v := range fileTree {
|
||||||
|
ft = append(ft, v.(string))
|
||||||
|
}
|
||||||
|
wSession.Content.FileTree = ft
|
||||||
|
|
||||||
|
files := args["files"].([]interface{})
|
||||||
|
fs := []string{}
|
||||||
|
for _, v := range files {
|
||||||
|
fs = append(fs, v.(string))
|
||||||
|
}
|
||||||
|
wSession.Content.Files = fs
|
||||||
|
|
||||||
|
for _, user := range conf.Wide.Users {
|
||||||
|
if user.Name == wSession.Username {
|
||||||
|
user.LatestSessionContent = wSession.Content
|
||||||
|
|
||||||
|
// 定时任务会负责持久化
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 设置会话关联的进程集.
|
// 设置会话关联的进程集.
|
||||||
func (s *WideSession) SetProcesses(ps []*os.Process) {
|
func (s *WideSession) SetProcesses(ps []*os.Process) {
|
||||||
s.Processes = ps
|
s.Processes = ps
|
||||||
|
@ -160,9 +214,11 @@ func (sessions *Sessions) New(httpSession *sessions.Session) *WideSession {
|
||||||
|
|
||||||
ret := &WideSession{
|
ret := &WideSession{
|
||||||
Id: id,
|
Id: id,
|
||||||
|
Username: httpSession.Values["username"].(string),
|
||||||
HTTPSession: httpSession,
|
HTTPSession: httpSession,
|
||||||
EventQueue: userEventQueue,
|
EventQueue: userEventQueue,
|
||||||
State: SessionStateActive,
|
State: SessionStateActive,
|
||||||
|
Content: &conf.LatestSessionContent{},
|
||||||
Created: now,
|
Created: now,
|
||||||
Updated: now,
|
Updated: now,
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,3 +17,21 @@ sessionWS.onerror = function (e) {
|
||||||
console.log('[session onerror] ' + JSON.parse(e));
|
console.log('[session onerror] ' + JSON.parse(e));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 定时(30 秒)保存会话内容.
|
||||||
|
setTimeout(function () {
|
||||||
|
var request = newWideRequest();
|
||||||
|
|
||||||
|
// TODO: 会话状态保存
|
||||||
|
request.currentFile = "current file"; // 当前编辑器
|
||||||
|
request.fileTree = ["1/", "2/"]; // 文件树展开状态
|
||||||
|
request.files = ["1.go", "2.go", "3.go"]; // 编辑器打开状态
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: '/session/save',
|
||||||
|
data: JSON.stringify(request),
|
||||||
|
dataType: "json",
|
||||||
|
success: function (data) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 30000);
|
||||||
|
|
Loading…
Reference in New Issue