This commit is contained in:
Liang Ding 2014-09-17 14:35:48 +08:00
parent 4e5b2f5895
commit 3393aad6af
9 changed files with 161 additions and 148 deletions

View File

@ -91,36 +91,33 @@ func (*conf) GetUserWorkspace(username string) string {
// 获取 gocode 路径.
func (*conf) GetGocode() string {
binDir := os.Getenv("GOBIN")
if "" != binDir {
return binDir + string(os.PathSeparator) + "gocode"
}
binDir = os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
runtime.GOOS + "_" + os.Getenv("GOARCH")
if isExist(binDir) {
return binDir + string(os.PathSeparator) + "gocode"
} else {
return os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
"gocode"
}
return getGOBIN() + "gocode"
}
// 获取 ide_stub 路径.
func (*conf) GetIDEStub() string {
binDir := os.Getenv("GOBIN")
if "" != binDir {
return binDir + string(os.PathSeparator) + "ide_stub"
return getGOBIN() + "ide_stub"
}
func getGOBIN() string {
ret := os.Getenv("GOBIN")
if "" != ret {
return ret + string(os.PathSeparator)
}
binDir = os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
runtime.GOOS + "_" + os.Getenv("GOARCH")
if isExist(binDir) {
return binDir + string(os.PathSeparator) + "ide_stub"
} else {
return os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
"ide_stub"
ret = os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
os.Getenv("GOOS") + "_" + os.Getenv("GOARCH")
if isExist(ret) {
return ret + string(os.PathSeparator)
}
ret = os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
runtime.GOOS + "_" + runtime.GOARCH
if isExist(ret) {
return ret + string(os.PathSeparator)
}
return os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator)
}
// 保存 Wide 配置.

View File

@ -12,7 +12,7 @@ import (
"strings"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/user"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
"github.com/golang/glog"
"github.com/gorilla/websocket"
@ -30,7 +30,7 @@ type snippet struct {
// 建立编辑器通道.
func WSHandler(w http.ResponseWriter, r *http.Request) {
session, _ := user.HTTPSession.Get(r, "wide-session")
session, _ := session.HTTPSession.Get(r, "wide-session")
sid := session.Values["id"].(string)
editorWS[sid], _ = websocket.Upgrade(w, r, nil, 1024, 1024)
@ -99,7 +99,7 @@ func AutocompleteHandler(w http.ResponseWriter, r *http.Request) {
return
}
session, _ := user.HTTPSession.Get(r, "wide-session")
session, _ := session.HTTPSession.Get(r, "wide-session")
username := session.Values["username"].(string)
path := args["path"].(string)
@ -174,7 +174,7 @@ func FindDeclarationHandler(w http.ResponseWriter, r *http.Request) {
data := map[string]interface{}{"succ": true}
defer util.RetJSON(w, r, data)
session, _ := user.HTTPSession.Get(r, "wide-session")
session, _ := session.HTTPSession.Get(r, "wide-session")
username := session.Values["username"].(string)
decoder := json.NewDecoder(r.Body)
@ -255,7 +255,7 @@ func FindUsagesHandler(w http.ResponseWriter, r *http.Request) {
data := map[string]interface{}{"succ": true}
defer util.RetJSON(w, r, data)
session, _ := user.HTTPSession.Get(r, "wide-session")
session, _ := session.HTTPSession.Get(r, "wide-session")
username := session.Values["username"].(string)
decoder := json.NewDecoder(r.Body)

View File

@ -12,7 +12,7 @@ import (
"strings"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/user"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
"github.com/golang/glog"
)
@ -23,7 +23,7 @@ func GetFiles(w http.ResponseWriter, r *http.Request) {
data := map[string]interface{}{"succ": true}
defer util.RetJSON(w, r, data)
session, _ := user.HTTPSession.Get(r, "wide-session")
session, _ := session.HTTPSession.Get(r, "wide-session")
username := session.Values["username"].(string)
userSrc := conf.Wide.GetUserWorkspace(username) + string(os.PathSeparator) + "src"

27
main.go
View File

@ -15,8 +15,8 @@ import (
"github.com/b3log/wide/i18n"
"github.com/b3log/wide/notification"
"github.com/b3log/wide/output"
"github.com/b3log/wide/session"
"github.com/b3log/wide/shell"
"github.com/b3log/wide/user"
"github.com/golang/glog"
)
@ -39,24 +39,16 @@ func init() {
// Wide 首页.
func indexHandler(w http.ResponseWriter, r *http.Request) {
// 创建一个 Wide 会话
wideSession := user.WideSessions.New()
i18n.Load()
model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(r), "locale": i18n.GetLocale(r),
"session": wideSession}
httpSession, _ := session.HTTPSession.Get(r, "wide-session")
httpSession, _ := user.HTTPSession.Get(r, "wide-session")
httpSessionId := httpSession.Values["id"].(string)
// TODO: 写死以 admin 作为用户登录
username := conf.Wide.Users[0].Name
if httpSession.IsNew {
httpSession.Values["username"] = username
httpSessionId = strconv.Itoa(rand.Int())
httpSession.Values["id"] = httpSessionId
httpSession.Values["id"] = strconv.Itoa(rand.Int())
// 一天过期
httpSession.Options.MaxAge = 60 * 60 * 24
@ -65,10 +57,13 @@ func indexHandler(w http.ResponseWriter, r *http.Request) {
httpSession.Save(r, w)
// Wide 会话关联 HTTP 会话
wideSession.HTTPSessionId = httpSession.Values["id"].(string)
// 创建一个 Wide 会话
wideSession := session.WideSessions.New(httpSession)
wideSessions := user.WideSessions.GetByHTTPSid(httpSessionId)
model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(r), "locale": i18n.GetLocale(r),
"session": wideSession}
wideSessions := session.WideSessions.GetByHTTPSession(httpSession)
glog.V(3).Infof("User [%s] has [%d] sessions", username, len(wideSessions))
t, err := template.ParseFiles("view/index.html")
@ -135,8 +130,8 @@ func main() {
http.HandleFunc("/notification/ws", notification.WSHandler)
// 用户
http.HandleFunc("/user/new", user.AddUser)
http.HandleFunc("/user/repos/init", user.InitGitRepos)
http.HandleFunc("/user/new", session.AddUser)
http.HandleFunc("/user/repos/init", session.InitGitRepos)
// 文档
http.Handle("/doc/", http.StripPrefix("/doc/", http.FileServer(http.Dir("doc"))))

View File

@ -14,7 +14,7 @@ import (
"time"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/user"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
"github.com/golang/glog"
"github.com/gorilla/websocket"
@ -150,7 +150,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
data := map[string]interface{}{"succ": true}
defer util.RetJSON(w, r, data)
httpSession, _ := user.HTTPSession.Get(r, "wide-session")
httpSession, _ := session.HTTPSession.Get(r, "wide-session")
username := httpSession.Values["username"].(string)
decoder := json.NewDecoder(r.Body)
@ -316,7 +316,7 @@ func GoInstallHandler(w http.ResponseWriter, r *http.Request) {
data := map[string]interface{}{"succ": true}
defer util.RetJSON(w, r, data)
httpSession, _ := user.HTTPSession.Get(r, "wide-session")
httpSession, _ := session.HTTPSession.Get(r, "wide-session")
username := httpSession.Values["username"].(string)
decoder := json.NewDecoder(r.Body)
@ -443,7 +443,7 @@ func GoGetHandler(w http.ResponseWriter, r *http.Request) {
data := map[string]interface{}{"succ": true}
defer util.RetJSON(w, r, data)
httpSession, _ := user.HTTPSession.Get(r, "wide-session")
httpSession, _ := session.HTTPSession.Get(r, "wide-session")
username := httpSession.Values["username"].(string)
decoder := json.NewDecoder(r.Body)

108
session/sessions.go Normal file
View File

@ -0,0 +1,108 @@
// 会话操作.
// Wide 服务器端需要维护两种会话:
// 1. HTTP 会话:主要用于验证登录
// 2. Wide 会话:浏览器 tab 打开/刷新会创建一个,并和 HTTP 会话进行关联
//
// TODO: 当 HTTP 会话失效时,关联的 Wide 会话也会做失效处理:释放所有和该会话相关的资源,例如运行中的程序进程、事件队列等
package session
import (
"math/rand"
"strconv"
"sync"
"time"
"github.com/golang/glog"
"github.com/gorilla/sessions"
)
const (
SessionStateActive = iota // 会话状态:活的
)
// 用户 HTTP 会话,用于验证登录.
var HTTPSession = sessions.NewCookieStore([]byte("BEYOND"))
// Wide 会话,对应一个浏览器 tab.
type WideSession struct {
Id string // 唯一标识
HTTPSession *sessions.Session // 关联的 HTTP 会话
State int // 状态
Created time.Time // 创建时间
Updated time.Time // 最近一次使用时间
}
type Sessions []*WideSession
// 所有 Wide 会话集.
var WideSessions Sessions
// 排它锁,防止并发问题.
var mutex sync.Mutex
// 创建一个 Wide 会话.
func (sessions *Sessions) New(httpSession *sessions.Session) *WideSession {
mutex.Lock()
defer mutex.Unlock()
rand.Seed(time.Now().UnixNano())
id := strconv.Itoa(rand.Int())
now := time.Now()
ret := &WideSession{
Id: id,
HTTPSession: httpSession,
State: SessionStateActive,
Created: now,
Updated: now,
}
*sessions = append(*sessions, ret)
return ret
}
// 移除 Wide 会话.
func (sessions *Sessions) Remove(sid string) {
mutex.Lock()
defer mutex.Unlock()
for i, s := range *sessions {
if s.Id == sid {
*sessions = append((*sessions)[:i], (*sessions)[i+1:]...)
glog.V(3).Infof("Has [%d] wide sessions currently", len(*sessions))
}
}
}
// 获取 HTTP 会话关联的所有 Wide 会话.
func (sessions *Sessions) GetByHTTPSession(httpSession *sessions.Session) []*WideSession {
mutex.Lock()
defer mutex.Unlock()
ret := []*WideSession{}
for _, s := range *sessions {
if s.HTTPSession.ID == httpSession.ID {
ret = append(ret, s)
}
}
return ret
}
// 移除 HTTP 会话关联的所有 Wide 会话.
func (sessions *Sessions) RemoveByHTTPSession(httpSession *sessions.Session) {
mutex.Lock()
defer mutex.Unlock()
for i, s := range *sessions {
if s.HTTPSession.ID == httpSession.ID {
*sessions = append((*sessions)[:i], (*sessions)[i+1:]...)
glog.V(3).Infof("Has [%d] wide sessions currently", len(*sessions))
}
}
}

View File

@ -1,5 +1,6 @@
// 用户操作.
package user
package session
// TODO: 这个包目前没有使用,只是开了个头 :p
import (
"encoding/json"

View File

@ -14,7 +14,7 @@ import (
"github.com/b3log/wide/conf"
"github.com/b3log/wide/i18n"
"github.com/b3log/wide/user"
"github.com/b3log/wide/session"
"github.com/b3log/wide/util"
"github.com/golang/glog"
"github.com/gorilla/websocket"
@ -26,15 +26,9 @@ var shellWS = map[string]*util.WSChannel{}
// Shell 首页.
func IndexHandler(w http.ResponseWriter, r *http.Request) {
// 创建一个 Wide 会话
wideSession := user.WideSessions.New()
i18n.Load()
model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(r), "locale": i18n.GetLocale(r),
"session": wideSession}
httpSession, _ := user.HTTPSession.Get(r, "wide-session")
httpSession, _ := session.HTTPSession.Get(r, "wide-session")
if httpSession.IsNew {
// TODO: 写死以 admin 作为用户登录
@ -50,8 +44,11 @@ func IndexHandler(w http.ResponseWriter, r *http.Request) {
httpSession.Save(r, w)
// Wide 会话关联 HTTP 会话
wideSession.HTTPSessionId = httpSession.Values["id"].(string)
// 创建一个 Wide 会话
wideSession := session.WideSessions.New(httpSession)
model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(r), "locale": i18n.GetLocale(r),
"session": wideSession}
t, err := template.ParseFiles("view/shell.html")
@ -67,7 +64,7 @@ func IndexHandler(w http.ResponseWriter, r *http.Request) {
// 建立 Shell 通道.
func WSHandler(w http.ResponseWriter, r *http.Request) {
httpSession, _ := user.HTTPSession.Get(r, "wide-session")
httpSession, _ := session.HTTPSession.Get(r, "wide-session")
username := httpSession.Values["username"].(string)
// TODO: 会话校验

View File

@ -1,85 +0,0 @@
package user
import (
"math/rand"
"strconv"
"time"
"github.com/golang/glog"
"github.com/gorilla/sessions"
)
const (
SessionStateActive = iota // 会话状态:活的
)
// 用户 HTTP 会话,用于验证登录.
var HTTPSession = sessions.NewCookieStore([]byte("BEYOND"))
// Wide 会话,对应一个浏览器 tab.
type WideSession struct {
Id string // 唯一标识
HTTPSessionId string // HTTP 会话 id
State int // 状态
Created time.Time // 创建时间
Updated time.Time // 最近一次使用时间
}
type Sessions []*WideSession
// 所有 Wide 会话集.
var WideSessions Sessions
// 创建一个 Wide 会话.
func (sessions *Sessions) New() *WideSession {
rand.Seed(time.Now().UnixNano())
id := strconv.Itoa(rand.Int())
now := time.Now()
ret := &WideSession{
Id: id,
State: SessionStateActive,
Created: now,
Updated: now,
}
*sessions = append(*sessions, ret)
return ret
}
// 移除 Wide 会话.
func (sessions *Sessions) Remove(sid string) {
for i, s := range *sessions {
if s.Id == sid {
*sessions = append((*sessions)[:i], (*sessions)[i+1:]...)
glog.V(3).Infof("Has [%d] wide sessions currently", len(*sessions))
}
}
}
// 获取 HTTP 会话关联的所有 Wide 会话.
func (sessions *Sessions) GetByHTTPSid(httpSessionId string) []*WideSession {
ret := []*WideSession{}
for _, s := range *sessions {
if s.HTTPSessionId == httpSessionId {
ret = append(ret, s)
}
}
return ret
}
// 移除 HTTP 会话关联的所有 Wide 会话.
func (sessions *Sessions) RemoveByHTTPSid(httpSessionId string) {
for i, s := range *sessions {
if s.HTTPSessionId == httpSessionId {
*sessions = append((*sessions)[:i], (*sessions)[i+1:]...)
glog.V(3).Infof("Has [%d] wide sessions currently", len(*sessions))
}
}
}