/
prime_wss4.go
117 lines (106 loc) · 2.81 KB
/
prime_wss4.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
package main
import (
"flag"
"fmt"
"github.com/gorilla/websocket"
"log"
"math"
"net/http"
"os"
"primelib/v4"
"strings"
)
var portNum = flag.Uint("port", 7573, "(Websocket) port number to listen to")
func main() {
flag.Parse()
url := fmt.Sprintf(":%d", *portNum)
if *portNum > math.MaxUint16 {
log.Fatalln("FATAL: Illegal port number -", *portNum)
}
log.Println("INFO: Starting the Prime WebSocket Server listening at port", *portNum, "...")
http.HandleFunc("/", primeRequest)
if err := http.ListenAndServe(url, nil); err != nil {
log.Fatalln("FATAL:", err.Error())
}
}
const beginHelpMsg = `
===============================
Primelib v4 Web(socket) Service
-------------------------------
Available Commands (case-sensitive):
`
const endHelpMsg = `
nodiag:
turns off diagnostic messages
wantdiag:
turns on diagnostic messages
exit | quit | close:
closes the websocket client connection @server-end
===============================
`
const warnArgCount = "WARNING: Invalid number of args"
const errorUnknownCmd = "ERROR: Unknown request / command"
const MB = 1024 * 1024
func primeRequest(w http.ResponseWriter, r *http.Request) {
ws, err := websocket.Upgrade(w, r, nil, 1*MB, 1*MB)
if _, ok := err.(websocket.HandshakeError); ok {
http.Error(w, "Not a websocket handshake", 400)
return
} else if err != nil {
log.Println("ERROR: Websocket Handshake -", err)
return
}
fmt.Fprintln(os.Stderr, "INFO: Websocket opened")
primeRequestMainLoop(ws)
ws.Close()
fmt.Fprintln(os.Stderr, "INFO: Closing Websocket...")
}
func primeRequestMainLoop(ws *websocket.Conn) {
wantDiagOutput := true
msgType, msg, err := ws.ReadMessage()
MainLoop:
for ; err == nil && msgType == websocket.TextMessage; msgType, msg, err = ws.ReadMessage() {
req := strings.ToLower(strings.Trim(string(msg), " \r\n\t\v\f"))
switch req {
case "nodiag":
wantDiagOutput = false
ws.WriteMessage(websocket.TextMessage, []byte("Diag OFF\n"))
case "wantdiag":
wantDiagOutput = true
ws.WriteMessage(websocket.TextMessage, []byte("Diag ON\n"))
case "exit":
fallthrough
case "quit":
fallthrough
case "close":
break MainLoop
default:
if w, e := ws.NextWriter(websocket.TextMessage); e == nil {
if req == "?" {
w.Write([]byte(beginHelpMsg))
}
_, out, diag := primelib.DoCmd(req)
if out != nil {
for output := range out {
outputStr := fmt.Sprintf("%v", output)
_, err = w.Write([]byte(outputStr))
_, err = w.Write([]byte("\n"))
}
}
if wantDiagOutput {
for diagOutput := range diag {
diagOutputStr := fmt.Sprintf("%v", diagOutput)
_, err = w.Write([]byte(diagOutputStr))
_, err = w.Write([]byte("\n"))
}
}
if req == "?" {
w.Write([]byte(endHelpMsg))
}
w.Close()
} else {
log.Printf("ERROR: %v\n", e.Error())
}
}
}
}