/
main.go
150 lines (134 loc) · 3.14 KB
/
main.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
package main
import (
"net/http"
"newgo/test/model"
server "newgo/test/service"
"github.com/gorilla/websocket"
_ "github.com/jinzhu/gorm/dialects/mysql"
log "github.com/sirupsen/logrus"
)
var upgrader websocket.Upgrader
var db map[string]*Client
var todoID int
func main() {
model.Init()
server.StartServer()
// db = make(map[string]*Client)
// upgrader.CheckOrigin = func(r *http.Request) bool {
// return true
// }
// http.HandleFunc("/ws", handler)
// log.Fatal(http.ListenAndServe(":8081", nil))
}
func handler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Error(err)
return
}
for {
clientReq := &ClientRequest{}
err := conn.ReadJSON(clientReq)
if err != nil {
log.Println(err)
return
}
log.Infof("Message from clinet: %#v", clientReq)
if 0 == len(clientReq.Username) {
return
}
clientResp := &ClientResponse{}
var todos Todos
var username = clientReq.Username
switch clientReq.Type {
case "hello":
doLogin(username, conn)
todos = getTodos(username)
case "add":
todos = addTodo(username, clientReq.Todo)
case "delete":
todos = removeTodo(username, clientReq.ID)
case "toggle.done":
todos = toggleDone(username, clientReq.ID)
}
clientResp.Todos = todos
connections := getConnections(username)
log.Infof("Updating %v clients for user %v", len(connections), username)
for _, c := range connections {
if err := c.WriteJSON(clientResp); err != nil {
doLogout(username, c)
}
}
}
}
func doLogout(username string, c *websocket.Conn) {
conns := db[username].Connections
var tmp Connections
for _, v := range conns {
if v != c {
tmp = append(tmp, v)
}
}
db[username].Connections = tmp
}
func getConnections(username string) Connections {
return db[username].Connections
}
func doLogin(username string, c *websocket.Conn) {
if db[username] == nil {
db[username] = &Client{}
}
db[username].Connections = append(db[username].Connections, c)
}
func toggleDone(username string, id int) Todos {
for i, v := range db[username].Todos {
if id == v.ID {
db[username].Todos[i].Done = !v.Done
}
}
return db[username].Todos
}
func getTodos(username string) Todos {
return db[username].Todos
}
func addTodo(username string, todo Todo) Todos {
todoID++
todo.ID = todoID
db[username].Todos = append(db[username].Todos, todo)
return db[username].Todos
}
func removeTodo(username string, id int) Todos {
todos := db[username].Todos
var tmp Todos
for _, v := range todos {
if id != v.ID {
tmp = append(tmp, v)
}
}
db[username].Todos = tmp
return tmp
}
type (
Todo struct {
ID int `json:"id,omitempty"`
Description string `json:"description,omitempty"`
Done bool `json:"done"`
}
Todos []Todo
ClientRequest struct {
Username string `json:"username,omitempty"`
Type string `json:"type,omitempty"` // hello, add, or remove
Todo `json:"todo,omitempty"`
ID int `json:"id,omitempty"`
}
ClientResponse struct {
Todos `json:"todos,omitempty"`
}
Connections []*websocket.Conn
Client struct {
Todos
Connections
}
)
// model.Init()
// server.StartServer()