forked from zhaojh329/rttys
-
Notifications
You must be signed in to change notification settings - Fork 0
/
device.go
104 lines (87 loc) · 2.06 KB
/
device.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
package main
import (
"github.com/gorilla/websocket"
log "github.com/sirupsen/logrus"
"time"
)
const (
/* Max session id for each device */
RTTY_MAX_SESSION_ID_DEV = 5
)
type Device struct {
*Client
desc string /* description of the device */
timestamp int64 /* Connection time */
sessions map[uint8]string /* sessions of each device */
}
type DeviceInfo struct {
ID string `json:"id"`
Uptime int64 `json:"uptime"`
Description string `json:"description"`
}
type DevMessage struct {
msgType int
data []byte
dev *Device
}
func (dev *Device) Close() {
dev.Client.Close()
dev.br.disconnecting <- dev
}
func (dev *Device) getFreeSid() uint8 {
for sid := uint8(1); sid <= RTTY_MAX_SESSION_ID_DEV; sid++ {
if _, ok := dev.sessions[sid]; !ok {
return sid
}
}
return uint8(0)
}
/*
* If the Server does not receive a PING Packet from the Client within one and
* a half times the Keep Alive time period, the server will disconnect the
* Connection
*/
func (dev *Device) keepAlive(keepalive int64) {
defer dev.Close()
ticker := time.NewTicker(time.Second * time.Duration(keepalive))
defer ticker.Stop()
last := time.Now().Unix()
keepalive = keepalive * 3
/* Get the current ping handler */
pingHandler := dev.ws.PingHandler()
dev.ws.SetPingHandler(func(appData string) error {
last = time.Now().Unix()
return pingHandler(appData)
})
for {
select {
case <-dev.closeChan:
return
case <-ticker.C:
now := time.Now().Unix()
if now-last > keepalive {
log.Error("Inactive device in long time, now kill it: %s", dev.devid)
return
}
}
}
}
func (dev *Device) readAlway() {
defer dev.Close()
for {
msgType, data, err := dev.ws.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
log.Errorf("error: %v", err)
}
break
}
msg := &DevMessage{msgType, data, dev}
select {
case dev.br.inDevMessage <- msg:
case <-dev.closeChan:
log.Error("closeChan from readAlway")
return
}
}
}