Skip to content

Commit 4f708b5

Browse files
committed
Just a POC
0 parents  commit 4f708b5

File tree

2 files changed

+241
-0
lines changed

2 files changed

+241
-0
lines changed

main.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package main
2+
3+
import (
4+
"./server"
5+
"fmt"
6+
"net/http"
7+
)
8+
9+
func main() {
10+
server := server.New()
11+
12+
server.Method("hello", func(p []interface{}) (interface{}, error) {
13+
return "result", nil
14+
})
15+
16+
http.HandleFunc("/websocket", server.Handler)
17+
http.ListenAndServe(":9000", nil)
18+
}

server/server.go

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
package server
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"fmt"
7+
"math/rand"
8+
"net/http"
9+
10+
"github.com/gorilla/websocket"
11+
)
12+
13+
type MethodHandler func([]interface{}) (interface{}, error)
14+
15+
type Server struct {
16+
ws *websocket.Conn
17+
methods map[string]MethodHandler
18+
}
19+
20+
type Message struct {
21+
Msg string `json:"msg"`
22+
Session string `json:"session"`
23+
Version string `json:"version"`
24+
Support []string `json:"support"`
25+
Id string `json:"id"`
26+
Method string `json:"method"`
27+
Params []interface{} `json:"params"`
28+
Result string `json:"result"`
29+
Methods []string `json:"methods"`
30+
}
31+
32+
// type ConnectMessage struct {
33+
// Msg string `json:"msg"`
34+
// Session string `json:"session"`
35+
// Version string `json:"version"`
36+
// Support []string `json:"support"`
37+
// }
38+
39+
// type ConnectedMessage struct {
40+
// Msg string `json:"msg"`
41+
// Session string `json:"session"`
42+
// }
43+
44+
// type PingWithIdMessage struct {
45+
// Msg string `json:"msg"`
46+
// Id string `json:"id"`
47+
// }
48+
49+
// type PingWithoutIdMessage struct {
50+
// Msg string `json:"msg"`
51+
// }
52+
53+
// type PongWithIdMessage struct {
54+
// Msg string `json:"msg"`
55+
// Id string `json:"id"`
56+
// }
57+
58+
// type PongWithoutIdMessage struct {
59+
// Msg string `json:"msg"`
60+
// }
61+
62+
// type MethodMessage struct {
63+
// Msg string `json:"msg"`
64+
// Id string `json:"id"`
65+
// Method string `json:"method"`
66+
// Params []interface{} `json:"params"`
67+
// }
68+
69+
// type ResultWithErrorMessage struct {
70+
// Msg string `json:"msg"`
71+
// Id string `json:"id"`
72+
// Error Error `json:"error"`
73+
// }
74+
75+
// type ResultWithoutErrorMessage struct {
76+
// Msg string `json:"msg"`
77+
// Id string `json:"id"`
78+
// Result string `json:"result"`
79+
// }
80+
81+
// type UpdatedMessage struct {
82+
// Msg string `json:"msg"`
83+
// Methods []string `json:"methods"`
84+
// }
85+
86+
// type Error struct {
87+
// error string
88+
// reason string
89+
// details string
90+
// }
91+
92+
var upgrader = websocket.Upgrader{
93+
ReadBufferSize: 1024,
94+
WriteBufferSize: 1024,
95+
}
96+
97+
func New() Server {
98+
server := Server{}
99+
server.methods = make(map[string]MethodHandler)
100+
return server
101+
}
102+
103+
func (s *Server) Method(n string, h MethodHandler) {
104+
s.methods[n] = h
105+
}
106+
107+
// create websocket connection from http handler and runs the websocket handler
108+
func (s *Server) Handler(w http.ResponseWriter, r *http.Request) {
109+
ws, err := upgrader.Upgrade(w, r, nil)
110+
s.ws = ws
111+
112+
if err != nil {
113+
fmt.Println("Error: could not creating websocket connection")
114+
return
115+
}
116+
117+
for {
118+
msg, err := readMessage(ws)
119+
120+
if err != nil {
121+
fmt.Println("Error: could not read from websocket connection")
122+
ws.Close()
123+
break
124+
}
125+
126+
fmt.Println("Message =>", msg)
127+
128+
switch {
129+
case msg.Msg == "ping":
130+
go s.HandlePing(ws, &msg)
131+
case msg.Msg == "connect":
132+
go s.HandleConnect(ws, &msg)
133+
case msg.Msg == "method":
134+
go s.HandleMethod(ws, &msg)
135+
default:
136+
fmt.Println("Error: unknown ddp message", msg)
137+
}
138+
}
139+
}
140+
141+
func (s *Server) HandleConnect(c *websocket.Conn, m *Message) {
142+
err := c.WriteJSON(map[string]string{
143+
"msg": "connected",
144+
"session": randId(17),
145+
})
146+
147+
if err != nil {
148+
fmt.Println(err)
149+
}
150+
}
151+
152+
func (s *Server) HandlePing(c *websocket.Conn, m *Message) {
153+
if m.Id != "" {
154+
err := c.WriteJSON(map[string]string{
155+
"msg": "pong",
156+
"id": m.Id,
157+
})
158+
159+
if err != nil {
160+
fmt.Println(err)
161+
}
162+
} else {
163+
err := c.WriteJSON(map[string]string{
164+
"msg": "pong",
165+
})
166+
167+
if err != nil {
168+
fmt.Println(err)
169+
}
170+
}
171+
}
172+
173+
func (s *Server) HandleMethod(c *websocket.Conn, m *Message) {
174+
res, _ := s.methods[m.Method](m.Params)
175+
err := c.WriteJSON(map[string]interface{}{
176+
"msg": "result",
177+
"id": m.Id,
178+
"result": res,
179+
})
180+
181+
if err != nil {
182+
fmt.Println(err)
183+
}
184+
185+
err = c.WriteJSON(map[string]interface{}{
186+
"msg": "updated",
187+
"methods": []string{m.Id},
188+
})
189+
190+
if err != nil {
191+
fmt.Println(err)
192+
}
193+
}
194+
195+
func readMessage(ws *websocket.Conn) (Message, error) {
196+
t, str, err := ws.ReadMessage()
197+
msg := Message{}
198+
199+
if err != nil {
200+
// error reading message
201+
return msg, err
202+
}
203+
204+
if t != 1 {
205+
// ignore binary data
206+
err = errors.New("Error: websocket data is binary")
207+
return msg, err
208+
}
209+
210+
err = json.Unmarshal(str, &msg)
211+
return msg, err
212+
}
213+
214+
// TODO: move this to another package
215+
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
216+
217+
func randId(n int) string {
218+
b := make([]rune, n)
219+
for i := range b {
220+
b[i] = letters[rand.Intn(len(letters))]
221+
}
222+
return string(b)
223+
}

0 commit comments

Comments
 (0)