-
Notifications
You must be signed in to change notification settings - Fork 21
/
server.go
180 lines (161 loc) · 5.24 KB
/
server.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// web服务相关
package main
import (
"context"
"fmt"
"net/http"
"time"
"github.com/gorilla/mux"
"github.com/rs/cors"
)
// web服务帮助信息
const webHelp = `/listlive :列出正在直播的主播
/listrecord :列出正在下载的直播视频
/listdanmu:列出正在下载的直播弹幕
/liststreamer:列出设置了开播提醒或自动下载直播的主播
/startcoolq:使用酷Q发送直播通知到指定QQ或QQ群,需要事先设置并启动酷Q
/addnotify/uid :订阅指定主播的开播提醒,uid在主播的网页版个人主页查看
/delnotify/uid :取消订阅指定主播的开播提醒
/addrecord/uid :自动下载指定主播的直播视频
/delrecord/uid :取消自动下载指定主播的直播视频
/adddanmu/uid :自动下载指定主播的直播弹幕
/deldanmu/uid :取消自动下载指定主播的直播弹幕
/getdlurl/uid :查看指定主播是否在直播,如在直播输出其直播源地址
/addqq/uid/QQ号:设置将指定主播的开播提醒发送到指定QQ号
/delqq/uid:取消设置将指定主播的开播提醒发送到QQ
/addqqgroup/uid/QQ群号:设置将指定主播的开播提醒发送到指定QQ群号
/delqqgroup/uid:取消设置将指定主播的开播提醒发送到QQ群号
/startrecord/uid :临时下载指定主播的直播视频,如果没有设置自动下载该主播的直播视频,这次为一次性的下载
/stoprecord/uid :正在下载指定主播的直播视频时取消下载
/startdanmu/uid:临时下载指定主播的直播弹幕,如果没有设置自动下载该主播的直播弹幕,这次为一次性的下载
/stopdanmu/uid:正在下载指定主播的直播弹幕时取消下载
/startrecdan/uid:临时下载指定主播的直播视频和弹幕,如果没有设置自动下载该主播的直播视频和弹幕,这次为一次性的下载
/stoprecdan/uid:正在下载指定主播的直播视频和弹幕时取消下载
/log :查看log
/quit :退出本程序,退出需要等待半分钟左右
/help :本帮助信息`
var srv *http.Server
// 返回localhost地址和端口
func address(port int) string {
return "http://localhost:" + itoa(port)
}
// 处理 "/cmd"
func cmdHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
cmd := vars["cmd"]
w.Header().Set("Content-Type", "application/json")
if s := handleCmd(cmd); s != "" {
fmt.Fprint(w, s)
} else {
fmt.Fprint(w, "null")
}
}
// 处理 "/cmd/uid"
func cmdUIDHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
cmd := vars["cmd"]
uid, err := atoi(vars["uid"])
checkErr(err)
w.Header().Set("Content-Type", "application/json")
if s := handleCmdUID(cmd, uid); s != "" {
fmt.Fprint(w, s)
} else {
fmt.Fprint(w, "null")
}
}
// 处理 "/cmd/uid/qq"
func cmdQQHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
cmd := vars["cmd"]
uid, err := atoi(vars["uid"])
checkErr(err)
qq, err := atoi(vars["qq"])
checkErr(err)
w.Header().Set("Content-Type", "application/json")
if s := handleCmdQQ(cmd, uid, qq); s != "" {
fmt.Fprint(w, s)
} else {
fmt.Fprint(w, "null")
}
}
// 显示favicon
func faviconHandler(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, logoFile)
}
// 打印日志
func logHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, logString.String())
}
// 打印帮助
func helpHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, webHelp)
}
// 打印web请求
func printRequestURI(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
lPrintln("处理web请求:" + r.RequestURI)
next.ServeHTTP(w, r)
})
}
// web服务
func httpServer() {
defer func() {
if err := recover(); err != nil {
lPrintErr("Recovering from panic in httpServer(), the error is:", err)
lPrintErr("web服务发生错误,尝试重启web服务")
time.Sleep(2 * time.Second)
go httpServer()
}
}()
r := mux.NewRouter()
r.HandleFunc("/favicon.ico", faviconHandler)
r.HandleFunc("/log", logHandler)
r.HandleFunc("/help", helpHandler)
r.HandleFunc("/", helpHandler)
r.HandleFunc("/{cmd}", cmdHandler)
r.HandleFunc("/{cmd}/{uid:[1-9][0-9]*}", cmdUIDHandler)
r.HandleFunc("/{cmd}/{uid:[1-9][0-9]*}/{qq:[1-9][0-9]*}", cmdQQHandler)
r.Use(printRequestURI)
// 跨域处理
handler := cors.Default().Handler(r)
srv = &http.Server{
Addr: ":" + itoa(config.WebPort),
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
IdleTimeout: 60 * time.Second,
Handler: handler,
}
err := srv.ListenAndServe()
if err != http.ErrServerClosed {
lPrintln(err)
panic(err)
}
}
// 启动web服务
func startWeb() bool {
if *isWebServer {
lPrintWarn("已经启动过web服务")
} else {
*isWebServer = true
lPrintln("启动web服务,现在可以通过 " + address(config.WebPort) + " 来查看状态和发送命令")
go httpServer()
}
return true
}
// 停止web服务
func stopWeb() bool {
if *isWebServer {
*isWebServer = false
lPrintln("停止web服务")
ctx, cancel := context.WithCancel(mainCtx)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
lPrintErr("web服务关闭错误:", err)
lPrintWarn("强行关闭web服务")
cancel()
}
} else {
lPrintWarn("没有启动web服务")
}
return true
}