link.go 2.2 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 48
		match := reg.MatchString(serial)
		if !match {
			return fmt.Errorf("register package format error %s", serial)
		}
	}

	//按序号保存索引,供外部使用
J
顶替  
Jason 已提交
49
	connections.Store(serial, l)
J
Jason 已提交
50 51 52 53

	return nil
}

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

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

		//TODO 转发剩余内容

		return
	}

72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
	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 已提交
88 89
	}

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

}

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

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

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

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

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