mirror of
https://github.com/lwch/natpass
synced 2025-10-06 05:46:49 +08:00
105 lines
2.1 KiB
Go
105 lines
2.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/jkstack/natpass/code/network"
|
|
"github.com/lwch/logging"
|
|
)
|
|
|
|
type client struct {
|
|
sync.RWMutex
|
|
parent *clients
|
|
idx uint32
|
|
conn *network.Conn
|
|
updated time.Time
|
|
links map[string]struct{} // link id => struct{}
|
|
}
|
|
|
|
func (c *client) run() {
|
|
defer c.parent.parent.closeClient(c)
|
|
for {
|
|
if time.Since(c.updated).Seconds() > 600 {
|
|
links := make([]string, 0, len(c.links))
|
|
c.RLock()
|
|
for id := range c.links {
|
|
links = append(links, id)
|
|
}
|
|
c.RUnlock()
|
|
logging.Info("%s-%d is not keepalived, links: %v", c.parent.id, c.idx, links)
|
|
return
|
|
}
|
|
msg, size, err := c.conn.ReadMessage(c.parent.parent.cfg.ReadTimeout)
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), "i/o timeout") {
|
|
continue
|
|
}
|
|
logging.Error("read message from %s-%d: %v", c.parent.id, c.idx, err)
|
|
return
|
|
}
|
|
c.updated = time.Now()
|
|
c.parent.parent.onMessage(c, c.conn, msg, size)
|
|
}
|
|
}
|
|
|
|
func (c *client) writeMessage(msg *network.Msg) error {
|
|
return c.conn.WriteMessage(msg, c.parent.parent.cfg.WriteTimeout)
|
|
}
|
|
|
|
func (c *client) addLink(id string) {
|
|
c.Lock()
|
|
c.links[id] = struct{}{}
|
|
c.Unlock()
|
|
}
|
|
|
|
func (c *client) removeLink(id string) {
|
|
c.Lock()
|
|
delete(c.links, id)
|
|
c.Unlock()
|
|
}
|
|
|
|
func (c *client) getLinks() []string {
|
|
ret := make([]string, 0, len(c.links))
|
|
c.RLock()
|
|
for link := range c.links {
|
|
ret = append(ret, link)
|
|
}
|
|
c.RUnlock()
|
|
return ret
|
|
}
|
|
|
|
func (c *client) closeLink(id string) {
|
|
var msg network.Msg
|
|
msg.From = "server"
|
|
msg.To = c.parent.id
|
|
msg.ToIdx = c.idx
|
|
msg.XType = network.Msg_disconnect
|
|
msg.LinkId = id
|
|
c.conn.WriteMessage(&msg, c.parent.parent.cfg.WriteTimeout)
|
|
c.Lock()
|
|
delete(c.links, id)
|
|
c.Unlock()
|
|
}
|
|
|
|
func (c *client) is(id string, idx uint32) bool {
|
|
return c.parent.id == id && c.idx == idx
|
|
}
|
|
|
|
func (c *client) keepalive() {
|
|
var msg network.Msg
|
|
msg.From = "server"
|
|
msg.To = c.parent.id
|
|
msg.ToIdx = c.idx
|
|
msg.XType = network.Msg_keepalive
|
|
for {
|
|
time.Sleep(10 * time.Second)
|
|
err := c.writeMessage(&msg)
|
|
if err != nil {
|
|
logging.Error("send keepalive: %v", err)
|
|
return
|
|
}
|
|
}
|
|
}
|