forked from OpenAyame/ayame
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathayame.go
191 lines (166 loc) · 5.11 KB
/
ayame.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
181
182
183
184
185
186
187
188
189
190
191
/*
main function of ayame signaling server package
*/
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
"github.com/ambelovsky/gosf"
"github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
)
var AyameVersion = "19.05.04"
type AyameOptions struct {
LogDir string `yaml:"log_dir"`
LogName string `yaml:"log_name"`
LogLevel string `yaml:"log_level"`
Addr string `yaml:"addr"`
PortPlain int `yaml:"port_plain"`
PortSecure int `yaml:"port_secure"`
OverWsPingPong bool `yaml:"over_ws_ping_pong"`
AuthWebhookURL string `yaml:"auth_webhook_url"`
AllowOrigin string `yaml:"allow_origin"`
MaxSessions int `yaml:"max_sessions"`
FileDir string
}
var (
// start options
Options *AyameOptions
logger *logrus.Logger
)
// initialization from config
func init() {
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
configFilePath := flag.String("c", "./config.yaml", "ayame configuration file path (yaml)")
// yaml file read
buf, err := ioutil.ReadFile(*configFilePath)
if err != nil {
log.Fatal("cannot open config file, err=", err)
}
// yaml data parse
err = yaml.Unmarshal(buf, &Options)
if err != nil {
log.Fatal("cannot parse config file, err=", err)
}
}
func main() {
defer sendDebugStackToSlack()
flag.Parse()
args := flag.Args()
// argument processing
if len(args) > 0 {
if args[0] == "version" {
log.Printf("WebRTC Signaling Server Ayame version=%s", AyameVersion)
return
}
}
// NOTICE: I will not use logrus for readability
// logger = setupLogger()
// CAUTION: don't use localhost in url
urlPlain := fmt.Sprintf(":%d", Options.PortPlain)
urlSecure := fmt.Sprintf(":%d", Options.PortSecure)
log.Printf("WebRTC Signaling Server, Ayame v%s", AyameVersion)
log.Printf("running on http://<server>%s and https://<server>%s (Press Ctrl+C quit)", urlPlain, urlSecure)
hub := newHub(fmt.Sprintf("Ayame v%s (%d, %v)", AyameVersion,
Options.MaxSessions,
Options.OverWsPingPong))
go hub.run()
setupServerAPI(hub)
// start servers for protocols supported
go runPlainServer(urlPlain)
go runSecureServer(urlSecure)
go runSocketioServer(hub) // support ws and wss at the same time
runSelfChecker(hub)
}
// Setting API endpoints for signalling
func setupServerAPI(hub *Hub) {
// web file server for working a sample page
// http.HandleFunc("/asset", func(w http.ResponseWriter, r *http.Request) {
// http.ServeFile(w, r, r.URL.Path[1:])
// })
//http.Handle("/", http.FileServer(http.Dir("asset"))) // the simplest use
fs := http.FileServer(http.Dir("asset"))
http.Handle("/static/", http.StripPrefix("/static/", fs))
// Belows are API endpoints
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
// log.Printf("/hello")
fmt.Fprintf(w, "{\"msg\":\"hello\"}")
})
http.HandleFunc("/upload", func(w http.ResponseWriter, r *http.Request) {
// log.Printf("/upload")
uploadHandler(hub, w, r)
})
http.HandleFunc("/fetch", func(w http.ResponseWriter, r *http.Request) {
// log.Printf("/upload")
fetchHandler(hub, w, r)
})
// /ws endpoint is same with /signaling for compatibility
http.HandleFunc("/admin", func(w http.ResponseWriter, r *http.Request) {
// log.Printf("/admin")
adminHandler(hub, w, r)
})
http.HandleFunc("/event/", func(w http.ResponseWriter, r *http.Request) {
// log.Printf("/event")
eventHandler(hub, w, r)
})
http.HandleFunc("/chat", func(w http.ResponseWriter, r *http.Request) {
// log.Printf("/chat")
chatHandler(hub, w, r)
})
http.HandleFunc("/signal", func(w http.ResponseWriter, r *http.Request) {
// log.Printf("/signal")
signalHandler(hub, w, r)
})
}
/*
websocket CORS example
https://play.golang.org/p/AOrlJsWhvf
*/
// Plain server supporint http and ws
func runPlainServer(url string) {
timeout := 10 * time.Second
// corsObj := handlers.AllowedOrigins([]string{"*"})
// server := &http.Server{Addr: url, Handler: handlers.CORS(corsObj)(), ReadHeaderTimeout: timeout}
server := &http.Server{Addr: url, Handler: nil, ReadHeaderTimeout: timeout}
err := server.ListenAndServe()
if err != nil {
log.Fatal(err)
}
}
// Secure server supporting https and wss
func runSecureServer(url string) {
timeout := 10 * time.Second
server := &http.Server{Addr: url, Handler: nil, ReadHeaderTimeout: timeout}
err := server.ListenAndServeTLS("certs/cert.pem", "certs/key.pem")
if err != nil {
log.Fatal(err)
}
}
// Socket.io(gosf) server for plain and secure connections
func runSocketioServer(hub *Hub) {
gosf.Listen("message", handleSignalMessage)
gosf.Startup(map[string]interface{}{"port": 9999})
log.Printf("socket.io closed")
}
func runSelfChecker(hub *Hub) {
// chatting daemon function
go procChatMessages()
check := CheckConfig{level: 10.0, period: 10}
disk := DiskUsage("/")
summary := StringDiskUsage(disk)
log.Println(summary)
// checking the status
for {
event := &EventInfo{content: "event test"}
hub.event <- event
log.Printf("The service is now alive with %d min interval checking", check.period)
time.Sleep(10 * time.Minute)
disk := DiskUsage("/")
CheckDiskWarning(disk, check.level)
time.Sleep(time.Duration(check.period) * time.Minute)
}
}