link.go 2.1 KB
Newer Older
J
Jason 已提交
1 2 3 4
package dtu

import (
	"bytes"
5
	"encoding/hex"
J
Jason 已提交
6
	"errors"
J
Jason 已提交
7
	"fmt"
J
Jason 已提交
8
	"log"
J
Jason 已提交
9 10
	"net"
	"regexp"
J
Jason 已提交
11
	"time"
J
Jason 已提交
12 13
)

J
顶替  
Jason 已提交
14 15
type Link struct {
	ID int64
J
 
Jason 已提交
16

J
Jason 已提交
17 18 19
	Error      string
	Serial     string
	RemoteAddr net.Addr
J
 
Jason 已提交
20

J
 
Jason 已提交
21 22
	Rx int
	Tx int
J
Jason 已提交
23

J
Jason 已提交
24 25
	conn interface{}

J
Jason 已提交
26 27
	lastTime time.Time

J
Jason 已提交
28
	channel *Channel
J
Jason 已提交
29

J
Jason 已提交
30 31
}

J
顶替  
Jason 已提交
32
func (l *Link) checkRegister(buf []byte) error {
J
Jason 已提交
33
	n := len(buf)
J
顶替  
Jason 已提交
34
	if n < l.channel.Register.Length {
J
Jason 已提交
35 36 37 38 39
		return fmt.Errorf("register package is too short %d %s", n, string(buf[:n]))
	}
	serial := string(buf[:n])

	// 正则表达式判断合法性
J
顶替  
Jason 已提交
40 41
	if l.channel.Register.Regex != "" {
		reg := regexp.MustCompile(`^` + l.channel.Register.Regex + `$`)
J
Jason 已提交
42 43 44 45 46 47
		match := reg.MatchString(serial)
		if !match {
			return fmt.Errorf("register package format error %s", serial)
		}
	}

48
	//TODO 更新数据库中 serial
J
Jason 已提交
49 50 51 52

	return nil
}

J
顶替  
Jason 已提交
53 54 55
func (l *Link) onData(buf []byte) {
	l.Rx += len(buf)
	l.lastTime = time.Now()
J
Jason 已提交
56

J
Jason 已提交
57
	//检查注册包
J
顶替  
Jason 已提交
58 59
	if l.channel.Register.Enable && l.Serial != "" {
		err := l.checkRegister(buf)
J
Jason 已提交
60
		if err != nil {
J
Jason 已提交
61
			log.Println(err)
J
顶替  
Jason 已提交
62
			_ = l.Close()
J
Jason 已提交
63 64 65 66 67 68 69 70
			return
		}

		//TODO 转发剩余内容

		return
	}

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
	hb := l.channel.HeartBeat
	//检查心跳包, 判断上次收发时间,是否已经过去心跳间隔
	if hb.Enable && time.Now().Sub(l.lastTime) > time.Second * time.Duration(hb.Interval) {
		var b []byte
		if hb.IsHex {
			var e error
			b, e = hex.DecodeString(hb.Content)
			if e != nil {
				log.Println(e)
			}
		} else {
			b = []byte(hb.Content)
		}
		if bytes.Compare(b, buf) == 0 {
			return
		}
J
Jason 已提交
87 88
	}

J
Jason 已提交
89
	//TODO 内容转发,暂时直接回复
J
顶替  
Jason 已提交
90
	_, _ = l.Send(buf)
J
Jason 已提交
91 92 93

}

J
顶替  
Jason 已提交
94 95 96
func (l *Link) Send(buf []byte) (int, error) {
	l.Tx += len(buf)
	l.lastTime = time.Now()
J
Jason 已提交
97

J
顶替  
Jason 已提交
98
	if conn, ok := l.conn.(net.Conn); ok {
J
Jason 已提交
99
		return conn.Write(buf)
J
Jason 已提交
100
	}
J
顶替  
Jason 已提交
101 102
	if conn, ok := l.conn.(net.PacketConn); ok {
		return conn.WriteTo(buf, l.RemoteAddr)
J
Jason 已提交
103
	}
J
Jason 已提交
104
	return 0, errors.New("错误的链接类型")
J
Jason 已提交
105 106
}

J
顶替  
Jason 已提交
107 108
func (l *Link) Close() error {
	return l.conn.(net.Conn).Close()
J
Jason 已提交
109
}
J
Jason 已提交
110

J
顶替  
Jason 已提交
111 112
func newConnection(conn net.Conn) *Link {
	return &Link{
J
Jason 已提交
113 114
		RemoteAddr: conn.RemoteAddr(),
		conn:       conn,
J
Jason 已提交
115 116 117
	}
}

J
顶替  
Jason 已提交
118 119
func newPacketConnection(conn net.PacketConn, addr net.Addr) *Link {
	return &Link{
J
 
Jason 已提交
120 121
		RemoteAddr: addr,
		conn:       conn,
J
Jason 已提交
122
	}
J
Jason 已提交
123
}