-
Notifications
You must be signed in to change notification settings - Fork 2
/
template.go
130 lines (105 loc) · 2.87 KB
/
template.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
package main
import (
"bytes"
"strings"
"text/template"
)
var WebSocketTemplate = `
{{$svrType := .ServiceType}}
{{$svrName := .ServiceName}}
type {{.ServiceType}}WebSocketRequest struct {
Action string
Input string
}
type {{.ServiceType}}WebSocketResponse struct {
Action string
Code int
Message string
Data interface{}
}
func (ws *{{.ServiceType}}WebSocketResponse)Error(ctx context.Context) (rs []byte){
rs,_ = json.Marshal(ws)
return
}
func Register{{.ServiceType}}WebSocketServer(s *http1.Server, srv {{.ServiceType}}Server,sessionHandler func(ctx context.Context, sid string) (context.Context, error)) {
var m = melody_v1.New()
s.HandleFunc("/ws", func(rw http.ResponseWriter, r *http.Request) {
m.HandleRequest(rw, r)
})
m.HandleMessage(func(s *melody_v1.Session, msg []byte) {
var rs []byte
wsmsg := &{{.ServiceType}}WebSocketRequest{}
err := json.Unmarshal(msg, wsmsg)
if err != nil {
rs,_ = json.Marshal({{$svrType}}WebSocketResponse{Action:wsmsg.Action,Code:500,Message:err.Error()})
s.Write(rs)
return
}
ctx, err := sessionHandler(s.Request.Context(), s.Request.Header.Get("sid"))
if err != nil {
rs,_ = json.Marshal({{$svrType}}WebSocketResponse{Action:wsmsg.Action,Code:500,Message:err.Error()})
s.Write(rs)
return
}
var out interface{}
if out,err = wsmsg.HandleMessage(ctx,srv);err !=nil{
rs,_ = json.Marshal({{$svrType}}WebSocketResponse{Action:wsmsg.Action,Code:500,Message:err.Error()})
s.Write(rs)
return
}
rs,_ = json.Marshal({{$svrType}}WebSocketResponse{Action:wsmsg.Action,Code:200,Data:out})
s.Write(rs)
})
}
func (ws *{{.ServiceType}}WebSocketRequest)HandleMessage(ctx context.Context,srv {{.ServiceType}}Server) (interface{},error){
var err error
switch ws.Action {
{{- range .Methods}}
case "/{{$svrName}}/{{.Name}}":
var in {{.Request}}
if err = json.Unmarshal([]byte(ws.Input), &in); err != nil {
return nil,err
}
return srv.{{.Name}}(ctx, &in)
{{- end}}
}
return nil, errors.New("action not found")
}
`
type serviceDesc struct {
ServiceType string // Greeter
ServiceName string // helloworld.Greeter
Metadata string // api/helloworld/helloworld.proto
Methods []*methodDesc
MethodSets map[string]*methodDesc
}
type methodDesc struct {
// method
Name string
Num int
Request string
Response string
Reply string
// WebSocket_rule
Path string
Method string
HasVars bool
HasBody bool
Body string
ResponseBody string
}
func (s *serviceDesc) execute() string {
s.MethodSets = make(map[string]*methodDesc)
for _, m := range s.Methods {
s.MethodSets[m.Name] = m
}
buf := new(bytes.Buffer)
tmpl, err := template.New("WebSocket").Parse(strings.TrimSpace(WebSocketTemplate))
if err != nil {
panic(err)
}
if err := tmpl.Execute(buf, s); err != nil {
panic(err)
}
return strings.Trim(buf.String(), "\r\n")
}