Fix #50
This commit is contained in:
parent
24c75e8125
commit
a4ce0583b7
|
@ -44,7 +44,6 @@ var rawWide conf
|
|||
func CheckEnv() {
|
||||
go func() {
|
||||
for {
|
||||
|
||||
if "" == os.Getenv("GOPATH") {
|
||||
glog.Fatal("Not found $GOPATH")
|
||||
os.Exit(-1)
|
||||
|
@ -60,7 +59,7 @@ func CheckEnv() {
|
|||
cmd := exec.Command(gocode, "close")
|
||||
_, err := cmd.Output()
|
||||
if nil != err {
|
||||
event.EventQueue <- event.EvtGocodeNotFount
|
||||
event.EventQueue <- event.EvtCodeGocodeNotFound
|
||||
glog.Warningf("Not found gocode [%s]", gocode)
|
||||
}
|
||||
|
||||
|
@ -68,11 +67,12 @@ func CheckEnv() {
|
|||
cmd = exec.Command(ide_stub, "version")
|
||||
_, err = cmd.Output()
|
||||
if nil != err {
|
||||
event.EventQueue <- event.EvtIDEStubNotFound
|
||||
event.EventQueue <- event.EvtCodeIDEStubNotFound
|
||||
glog.Warningf("Not found ide_stub [%s]", ide_stub)
|
||||
}
|
||||
|
||||
time.Sleep(time.Second * 2)
|
||||
// 7 分钟进行一次检查
|
||||
time.Sleep(time.Minute * 7)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
|
|
@ -4,23 +4,31 @@ package event
|
|||
import "github.com/golang/glog"
|
||||
|
||||
const (
|
||||
EvtGOPATHNotFound = iota // 事件:找不到环境变量 $GOPATH
|
||||
EvtGOROOTNotFound // 事件:找不到环境变量 $GOROOT
|
||||
EvtGocodeNotFount // 事件:找不到 gocode
|
||||
EvtIDEStubNotFound // 事件:找不到 IDE stub
|
||||
|
||||
EvtCodeGOPATHNotFound = iota // 事件代码:找不到环境变量 $GOPATH
|
||||
EvtCodeGOROOTNotFound // 事件代码:找不到环境变量 $GOROOT
|
||||
EvtCodeGocodeNotFound // 事件代码:找不到 gocode
|
||||
EvtCodeIDEStubNotFound // 事件代码:找不到 IDE stub
|
||||
)
|
||||
|
||||
// 事件队列最大长度.
|
||||
const MaxQueueLength = 10
|
||||
|
||||
// 事件结构.
|
||||
type Event struct {
|
||||
Code int `json:"code"` // 事件代码
|
||||
Sid string `json:"sid"` // 用户会话 id
|
||||
}
|
||||
|
||||
// 全局事件队列.
|
||||
// 入队的事件将分发到每个用户的通知队列.
|
||||
var EventQueue = make(chan int, MaxQueueLength)
|
||||
|
||||
// 用户事件队列.
|
||||
// 入队的事件将翻译为通知,并通过通知通道推送到前端.
|
||||
var UserEventQueues = map[string]chan int{}
|
||||
|
||||
// 用户事件处理器集.
|
||||
var UserEventHandlers = map[string]*Handlers{}
|
||||
|
||||
// 加载事件处理.
|
||||
func Load() {
|
||||
go func() {
|
||||
|
@ -35,21 +43,51 @@ func Load() {
|
|||
}()
|
||||
}
|
||||
|
||||
// 添加一个用户事件队列.
|
||||
func InitUserQueue(sid string) {
|
||||
// 初始化一个用户事件队列.
|
||||
func InitUserQueue(sid string, handlers ...Handler) {
|
||||
// FIXME: 会话过期后需要销毁对应的用户事件队列
|
||||
|
||||
q := UserEventQueues[sid]
|
||||
if nil != q {
|
||||
close(q)
|
||||
return
|
||||
}
|
||||
|
||||
q = make(chan int, MaxQueueLength)
|
||||
UserEventQueues[sid] = q
|
||||
|
||||
if nil == UserEventHandlers[sid] {
|
||||
UserEventHandlers[sid] = new(Handlers)
|
||||
}
|
||||
|
||||
for _, handler := range handlers {
|
||||
UserEventHandlers[sid].add(handler)
|
||||
}
|
||||
|
||||
go func() {
|
||||
for event := range q {
|
||||
glog.Infof("Session [%s] received a event [%d]", sid, event)
|
||||
for evtCode := range q {
|
||||
glog.V(5).Infof("Session [%s] received a event [%d]", sid, evtCode)
|
||||
|
||||
// 将事件交给事件处理器进行处理
|
||||
for _, handler := range *UserEventHandlers[sid] {
|
||||
e := Event{Code: evtCode, Sid: sid}
|
||||
handler.Handle(&e)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
type Handler interface {
|
||||
Handle(event *Event)
|
||||
}
|
||||
|
||||
type HandleFunc func(event *Event)
|
||||
|
||||
func (fn HandleFunc) Handle(event *Event) {
|
||||
fn(event)
|
||||
}
|
||||
|
||||
type Handlers []Handler
|
||||
|
||||
func (handlers *Handlers) add(handler Handler) {
|
||||
*handlers = append(*handlers, handler)
|
||||
}
|
||||
|
|
|
@ -272,7 +272,7 @@ func listFiles(dirname string) []string {
|
|||
|
||||
func getIconSkin(filenameExtension string) string {
|
||||
switch filenameExtension {
|
||||
case ".gitignore", "", ".exe", ".s":
|
||||
case ".gitignore", "", ".exe", ".s", ".tar", ".zip", ".rar", ".gz": // 不支持显示图标的文件
|
||||
return "ico-ztree-other "
|
||||
case ".json", ".js":
|
||||
return "ico-ztree-js "
|
||||
|
|
|
@ -21,5 +21,7 @@
|
|||
"goget": "go get",
|
||||
"goinstall": "go install",
|
||||
"build_n_run": "构建 & 运行",
|
||||
"full_screen": "全屏"
|
||||
"full_screen": "全屏",
|
||||
"notification_2": "没有检查到 gocode,这将会导致 [自动完成] 失效",
|
||||
"notification_3": "没有检查到 ide_stub,这将会导致 [跳转到声明]、[查找使用] 失效"
|
||||
}
|
|
@ -8,52 +8,83 @@ import (
|
|||
"runtime"
|
||||
"time"
|
||||
|
||||
"strconv"
|
||||
"github.com/b3log/wide/conf"
|
||||
"github.com/b3log/wide/event"
|
||||
"github.com/b3log/wide/i18n"
|
||||
"github.com/b3log/wide/user"
|
||||
"github.com/golang/glog"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
const (
|
||||
Error = "ERROR" // 通知.严重程度:ERROR
|
||||
Warn = "WARN" // 通知.严重程度:WARN
|
||||
Info = "INFO" // 通知.严重程度:INFO
|
||||
|
||||
Setup = "Setup" // 通知.类型:安装
|
||||
)
|
||||
|
||||
// 通知结构.
|
||||
type Notification struct {
|
||||
Event int
|
||||
Type string
|
||||
Severity string // ERROR/WARN/INFO
|
||||
Message string
|
||||
event *event.Event
|
||||
Type string `json:"type"`
|
||||
Severity string `json:"severity"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// 一个用户会话的 WebSocket 通道结构.
|
||||
type WSChannel struct {
|
||||
Conn *websocket.Conn // WebSocket 连接
|
||||
Time time.Time // 该通道最近一次使用时间
|
||||
Conn *websocket.Conn // WebSocket 连接
|
||||
Request *http.Request // 关联的 HTTP 请求
|
||||
Time time.Time // 该通道最近一次使用时间
|
||||
}
|
||||
|
||||
// 通知通道.
|
||||
// <username, {<sid1, WSChannel1>, <sid2, WSChannel2>}>
|
||||
var notificationWSs = map[string]map[string]WSChannel{}
|
||||
// <sid, WSChannel>
|
||||
var notificationWSs = map[string]*WSChannel{}
|
||||
|
||||
func event2Notification(e *event.Event) {
|
||||
if nil == notificationWSs[e.Sid] {
|
||||
return
|
||||
}
|
||||
|
||||
wsChannel := notificationWSs[e.Sid]
|
||||
|
||||
var notification Notification
|
||||
|
||||
switch e.Code {
|
||||
case event.EvtCodeGocodeNotFound:
|
||||
notification = Notification{event: e, Type: Setup, Severity: Error}
|
||||
case event.EvtCodeIDEStubNotFound:
|
||||
notification = Notification{event: e, Type: Setup, Severity: Error}
|
||||
default:
|
||||
glog.Warningf("Can't handle event[code=%d]", e.Code)
|
||||
return
|
||||
}
|
||||
|
||||
msgs := i18n.GetLangs(wsChannel.Request)
|
||||
notification.Message = msgs["notification_"+strconv.Itoa(e.Code)].(string)
|
||||
|
||||
wsChannel.Conn.WriteJSON(¬ification)
|
||||
}
|
||||
|
||||
func WSHandler(w http.ResponseWriter, r *http.Request) {
|
||||
session, _ := user.Session.Get(r, "wide-session")
|
||||
username := session.Values["username"].(string)
|
||||
sid := session.Values["id"].(string)
|
||||
|
||||
conn, _ := websocket.Upgrade(w, r, nil, 1024, 1024)
|
||||
wsChan := WSChannel{Conn: conn, Time: time.Now()}
|
||||
wsChan := WSChannel{Conn: conn, Request: r, Time: time.Now()}
|
||||
|
||||
wsChans := notificationWSs[username]
|
||||
if nil == wsChans {
|
||||
wsChans = map[string]WSChannel{}
|
||||
}
|
||||
|
||||
wsChans[sid] = wsChan
|
||||
notificationWSs[sid] = &wsChan
|
||||
|
||||
ret := map[string]interface{}{"output": "Notification initialized", "cmd": "init-notification"}
|
||||
wsChan.Conn.WriteJSON(&ret)
|
||||
|
||||
glog.Infof("Open a new [Notification] with session [%s], %d", sid, len(wsChans))
|
||||
glog.Infof("Open a new [Notification] with session [%s], %d", sid, len(notificationWSs))
|
||||
|
||||
event.InitUserQueue(sid)
|
||||
// 初始化用户事件队列
|
||||
event.InitUserQueue(sid, event.HandleFunc(event2Notification))
|
||||
|
||||
input := map[string]interface{}{}
|
||||
|
||||
|
|
Loading…
Reference in New Issue