-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBotAdapter.go
More file actions
153 lines (125 loc) · 2.72 KB
/
Copy pathBotAdapter.go
File metadata and controls
153 lines (125 loc) · 2.72 KB
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
package main
import (
"fmt"
"strings"
"time"
"github.com/gorilla/websocket"
)
type BotAdapter struct {
toBot chan *Message
fromBot chan *Message
socket *websocket.Conn
roomId int
nick string // bot nickname
}
func NewBotAdapter(roomId int) *BotAdapter {
// websocket 서버에 연결한다.
wsURI := fmt.Sprintf("ws://%s:%d/ws", conf.Domain, conf.Port)
conn, _, err := websocket.DefaultDialer.Dial(wsURI, nil)
if err != nil {
Error.Println("connect:", err)
return nil
}
botAdapter := &BotAdapter{
toBot: make(chan *Message, MAX_CHAN),
fromBot: make(chan *Message, MAX_CHAN),
roomId: roomId,
socket: conn,
}
// server -> bot
go botAdapter.Read()
// bot -> server
go botAdapter.Write()
return botAdapter
}
// newNick :
func (ba *BotAdapter) newNick(msg *Message) {
ba.nick = msg.Data
// nick을 bot으로 변경한다.
go func() {
<-time.NewTimer(500 * time.Millisecond).C
ba.socket.WriteJSON(&Message{
Action: "set-nick",
Data: strings.Replace(ba.nick, "user", "bot", 1),
Sender: ba.nick,
})
}()
// room에 join 한다.
go func() {
<-time.NewTimer(1 * time.Second).C
ba.socket.WriteJSON(&Message{
Action: "join-room",
Data: fmt.Sprintf("%d", ba.roomId),
Sender: ba.nick,
})
}()
}
func (ba *BotAdapter) startGame(msg *Message) {
ba.toBot <- msg
}
// Read : server -> bot
func (ba *BotAdapter) Read() {
defer func() {
close(ba.fromBot)
if r := recover(); r != nil {
Error.Println("Write panic:", r)
}
}()
for {
var msg Message
err := ba.socket.ReadJSON(&msg)
if err != nil {
Trace.Println("websocket handelr read", ba.nick, err)
ba.socket.Close()
break
}
switch msg.Action {
case "new-nick":
ba.newNick(&msg)
case "set-nick":
if msg.Sender == ba.nick {
ba.nick = msg.Data
}
case "start-game":
ba.startGame(&msg)
case "over-game":
if msg.Sender == ba.nick {
ba.toBot <- &msg
}
default:
ba.toBot <- &msg
}
}
Trace.Println("Read", ba.nick, "end")
}
// Write : bot -> server
func (ba *BotAdapter) Write() {
defer func() {
if r := recover(); r != nil {
Error.Println("Write panic:", r)
}
}()
for {
msg, ok := <-ba.fromBot
if !ok {
Trace.Println("websocket handelr write:", ba.nick, "channel closed")
break
}
err := ba.socket.WriteJSON(msg)
if err != nil {
Error.Println("websocket handelr write:", err)
break
}
if msg.Action == "leave-room" {
// BotFather.fromBot 채널이 닫혔는지 확인하고 안전하게 전송
select {
case BotFather.fromBot <- msg:
// 성공적으로 전송
default:
// 채널이 닫혔거나 가득 참
Warning.Println("BotFather.fromBot channel unavailable")
}
}
}
Trace.Println("Write", ba.nick, "end")
}