forked from NollGo/Noll
-
Notifications
You must be signed in to change notification settings - Fork 0
/
debug.go
140 lines (115 loc) · 2.79 KB
/
debug.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package main
import (
"fmt"
"net/http"
"os"
"path/filepath"
"github.com/fsnotify/fsnotify"
"github.com/lxzan/gws"
)
var upgrader = func(event gws.Event) *gws.Upgrader {
return gws.NewUpgrader(event, &gws.ServerOption{
CompressEnabled: true,
CheckUtf8Enabled: true,
ReadMaxPayloadSize: 32 * 1024 * 1024,
WriteMaxPayloadSize: 32 * 1024 * 1024,
})
}
func debugWs(config Config, _render func() error) http.Handler {
websocket := &DebugWs{}
// watch file change config.ThemeDir
dirList := collDir(config.ThemeDir)
pathChan, err := watch(_render, websocket)
if err != nil {
panic(err)
}
for i := range dirList {
pathChan <- dirList[i]
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
socket, err := upgrader(websocket).Accept(w, r)
if err != nil {
return
}
websocket.socket = socket
go socket.Listen()
})
}
func watch(_render func() error, websocket *DebugWs) (chan string, error) {
watcher, err := fsnotify.NewWatcher()
if err != nil {
return nil, err
}
go func() {
for {
select {
case event := <-watcher.Events:
if event.Has(fsnotify.Write) {
if err := _render(); err != nil {
fmt.Println("error:", err)
}
if websocket.socket != nil {
_ = websocket.socket.WriteString("reload")
}
}
case err := <-watcher.Errors:
fmt.Println("error:", err)
}
}
}()
pathChan := make(chan string)
go func() {
for {
select {
case path := <-pathChan:
if err := watcher.Add(path); err == nil {
fmt.Println("Start watch file change", path)
} else {
panic(err)
}
}
}
}()
return pathChan, nil
}
// collect all dir
func collDir(path string) []string {
if path == "" {
return []string{}
}
var dirs []string
if err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
dirs = append(dirs, path)
}
return nil
}); err != nil {
return []string{}
}
return dirs
}
// DebugWs is 调试 websocket event
type DebugWs struct {
socket *gws.Conn
}
// OnOpen is websocket 建立连接事件
func (d DebugWs) OnOpen(socket *gws.Conn) {
}
// OnError is websocket 错误事件
// IO错误, 协议错误, 压缩解压错误...
func (d DebugWs) OnError(socket *gws.Conn, err error) {
}
// OnClose is websocket 关闭事件
// 另一端发送了关闭帧
func (d DebugWs) OnClose(socket *gws.Conn, code uint16, reason []byte) {
}
// OnPing is websocket 心跳探测事件
func (d DebugWs) OnPing(socket *gws.Conn, payload []byte) {
}
// OnPong is websocket 心跳响应事件
func (d DebugWs) OnPong(socket *gws.Conn, payload []byte) {
}
// OnMessage is websocket 消息事件
// 如果开启了AsyncReadEnabled, 可以在一个连接里面并行处理多个请求
func (d DebugWs) OnMessage(socket *gws.Conn, message *gws.Message) {
}