fix
This commit is contained in:
parent
8abb8c1f2f
commit
3b95cf5645
16
README.md
Normal file
16
README.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
participant Device
|
||||||
|
participant Broker
|
||||||
|
participant Web
|
||||||
|
Device->>Broker: 建立TCP连接
|
||||||
|
Broker->>Broker: 5s未注册,主动断开
|
||||||
|
Device->>Broker: 注册报文
|
||||||
|
Broker->>Device: 注册回复
|
||||||
|
Device->>Broker: 心跳报文
|
||||||
|
Broker->>Device: 心跳报文
|
||||||
|
Web->>Broker: 创建Session
|
||||||
|
Broker->>Device: 创建Session
|
||||||
|
|
||||||
|
```
|
@ -19,8 +19,13 @@ import (
|
|||||||
|
|
||||||
// 帧类型 1字节
|
// 帧类型 1字节
|
||||||
// 帧长度 4字节
|
// 帧长度 4字节
|
||||||
|
// 帧数据 帧长度大小的数据
|
||||||
|
|
||||||
|
// 心跳包 02 00 00 00 00
|
||||||
|
// 注册包 01 00 00 00 00 device_id 00 token 00 desc
|
||||||
|
// 创建SESSION 03 00 00 00
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
DeviceId string
|
||||||
AddrServer string
|
AddrServer string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,8 +33,8 @@ const HEART_BEAT_INTERVAL = time.Second * 5 // 心跳超时时间
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
MSG_TYPE_UNKOWNM = iota
|
MSG_TYPE_UNKOWNM = iota
|
||||||
MSG_TYPE_HEARTBEAT
|
|
||||||
MSG_TYPE_REGISTER
|
MSG_TYPE_REGISTER
|
||||||
|
MSG_TYPE_HEARTBEAT
|
||||||
MSG_TYPE_SESSION_CREATE
|
MSG_TYPE_SESSION_CREATE
|
||||||
MSG_TYPE_SESSION_DATA
|
MSG_TYPE_SESSION_DATA
|
||||||
MSG_TYPE_SESSION_DESTORY
|
MSG_TYPE_SESSION_DESTORY
|
||||||
@ -37,6 +42,12 @@ const (
|
|||||||
MSG_TYPE_MAX
|
MSG_TYPE_MAX
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Session struct {
|
||||||
|
sessionId string
|
||||||
|
inBound *os.File
|
||||||
|
dev *Device
|
||||||
|
}
|
||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
id string
|
id string
|
||||||
category string
|
category string
|
||||||
@ -47,6 +58,7 @@ type Device struct {
|
|||||||
registered bool
|
registered bool
|
||||||
closed uint32
|
closed uint32
|
||||||
send chan []byte // Buffered channel of outbound messages.
|
send chan []byte // Buffered channel of outbound messages.
|
||||||
|
sessions map[string]*Session
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -108,7 +120,8 @@ func main() {
|
|||||||
func runClient(c *cli.Context) {
|
func runClient(c *cli.Context) {
|
||||||
|
|
||||||
cfg := &Config{
|
cfg := &Config{
|
||||||
AddrServer: "localhost:9011",
|
DeviceId: "jmq",
|
||||||
|
AddrServer: "dev.xzrobot.com:9011",
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpConn, err := createTcpConn(cfg.AddrServer)
|
tcpConn, err := createTcpConn(cfg.AddrServer)
|
||||||
@ -119,7 +132,7 @@ func runClient(c *cli.Context) {
|
|||||||
fmt.Println(tcpConn.LocalAddr().String() + " : Client Connected")
|
fmt.Println(tcpConn.LocalAddr().String() + " : Client Connected")
|
||||||
|
|
||||||
dev := &Device{
|
dev := &Device{
|
||||||
id: "1234567890",
|
id: cfg.DeviceId,
|
||||||
category: "device",
|
category: "device",
|
||||||
conn: tcpConn,
|
conn: tcpConn,
|
||||||
create_time: time.Now().Unix(),
|
create_time: time.Now().Unix(),
|
||||||
@ -127,35 +140,35 @@ func runClient(c *cli.Context) {
|
|||||||
registered: false,
|
registered: false,
|
||||||
closed: 0,
|
closed: 0,
|
||||||
send: make(chan []byte, 100),
|
send: make(chan []byte, 100),
|
||||||
|
sessions: make(map[string]*Session),
|
||||||
}
|
}
|
||||||
go dev.readLoop()
|
go dev.readLoop()
|
||||||
|
go dev.writeLoop()
|
||||||
|
|
||||||
//registe
|
//registe
|
||||||
s := make([][]byte, 3)
|
s := make([][]byte, 3)
|
||||||
s[0] = []byte("deviceid") //id
|
s[0] = []byte("jmq") //id
|
||||||
s[1] = []byte(dev.id) //desc
|
s[1] = []byte("desc") //desc
|
||||||
s[2] = []byte(dev.id) //token
|
s[2] = []byte("token") //token
|
||||||
dev.WriteMsg(MSG_TYPE_REGISTER, bytes.Join(s, []byte{0}))
|
dev.WriteMsg(MSG_TYPE_REGISTER, bytes.Join(s, []byte{0}))
|
||||||
|
|
||||||
go dev.writeLoop()
|
|
||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dev *Device) WriteMsg(typ int, data []byte) {
|
func (dev *Device) WriteMsg(typ int, data []byte) {
|
||||||
b := []byte{byte(typ), 0, 0, 0, 0}
|
b := []byte{byte(typ), 0, 0, 0, 0}
|
||||||
|
|
||||||
binary.BigEndian.PutUint32(b[1:], uint32(len(data)))
|
binary.BigEndian.PutUint32(b[1:], uint32(len(data)))
|
||||||
|
|
||||||
dev.send <- append(b, data...)
|
dev.send <- append(b, data...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dev *Device) readLoop() {
|
func (dev *Device) readLoop() {
|
||||||
defer dev.conn.Close()
|
defer dev.conn.Close()
|
||||||
|
defer log.Debug().Msgf("dev readLoop finished")
|
||||||
|
|
||||||
reader := bufio.NewReader(dev.conn)
|
reader := bufio.NewReader(dev.conn)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
b, err := reader.Peek(5)
|
b, err := reader.Peek(3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != io.EOF && !strings.Contains(err.Error(), "use of closed network connection") {
|
if err != io.EOF && !strings.Contains(err.Error(), "use of closed network connection") {
|
||||||
log.Error().Msg(err.Error())
|
log.Error().Msg(err.Error())
|
||||||
@ -163,7 +176,7 @@ func (dev *Device) readLoop() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.Discard(5)
|
reader.Discard(3)
|
||||||
|
|
||||||
msg_type := b[0]
|
msg_type := b[0]
|
||||||
|
|
||||||
@ -172,7 +185,7 @@ func (dev *Device) readLoop() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
msg_length := binary.BigEndian.Uint32(b[1:])
|
msg_length := binary.BigEndian.Uint16(b[1:])
|
||||||
data := make([]byte, msg_length)
|
data := make([]byte, msg_length)
|
||||||
_, err = io.ReadFull(reader, data)
|
_, err = io.ReadFull(reader, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -184,11 +197,50 @@ func (dev *Device) readLoop() {
|
|||||||
|
|
||||||
switch msg_type {
|
switch msg_type {
|
||||||
case MSG_TYPE_HEARTBEAT:
|
case MSG_TYPE_HEARTBEAT:
|
||||||
// log.Info().Msgf("Receive Heartbeat Time: %d", time.Now().Unix())
|
log.Info().Msgf("Receive Heartbeat Time: %d", time.Now().Unix())
|
||||||
|
|
||||||
case MSG_TYPE_REGISTER:
|
case MSG_TYPE_REGISTER:
|
||||||
dev.registered = true
|
dev.registered = true
|
||||||
log.Info().Msgf("Device Registry Success")
|
log.Info().Msgf("Device Registry Success")
|
||||||
|
case MSG_TYPE_SESSION_CREATE:
|
||||||
|
sessionId := string(data[:32])
|
||||||
|
|
||||||
|
cmd := exec.Command("bash")
|
||||||
|
ff, err := pty.Start(cmd)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Create Pty Error! " + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s := &Session{
|
||||||
|
sessionId: sessionId,
|
||||||
|
inBound: nil,
|
||||||
|
dev: dev,
|
||||||
|
}
|
||||||
|
|
||||||
|
dev.sessions[sessionId] = s
|
||||||
|
|
||||||
|
go func(s *Session) {
|
||||||
|
defer ff.Close()
|
||||||
|
reader := bufio.NewReader(ff)
|
||||||
|
for {
|
||||||
|
buffer := []byte{}
|
||||||
|
len, err := reader.Read(buffer)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Msg(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dev.WriteMsg(MSG_TYPE_SESSION_DATA, append([]byte(s.sessionId), buffer[:len]...))
|
||||||
|
}
|
||||||
|
}(s)
|
||||||
|
|
||||||
|
case MSG_TYPE_SESSION_DATA:
|
||||||
|
sessionId := string(data[:32])
|
||||||
|
if session, ok := dev.sessions[sessionId]; ok {
|
||||||
|
session.dev.WriteMsg(MSG_TYPE_SESSION_DATA, data)
|
||||||
|
// session.inBound.Write(data[32:])
|
||||||
|
return
|
||||||
|
}
|
||||||
case MSG_TYPE_TUNNEL_CREATE:
|
case MSG_TYPE_TUNNEL_CREATE:
|
||||||
log.Info().Msgf("Receive Tunnel Create")
|
log.Info().Msgf("Receive Tunnel Create")
|
||||||
cmd := exec.Command("bash")
|
cmd := exec.Command("bash")
|
||||||
@ -228,6 +280,7 @@ func (dev *Device) readLoop() {
|
|||||||
log.Error().Msgf("invalid msg type: %d", msg_type)
|
log.Error().Msgf("invalid msg type: %d", msg_type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dev *Device) writeLoop() {
|
func (dev *Device) writeLoop() {
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "./server"
|
"path": "./server"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -25,8 +25,8 @@ const HEART_BEAT_INTERVAL = time.Second * 5 // 心跳超时时间
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
MSG_TYPE_UNKOWNM = iota
|
MSG_TYPE_UNKOWNM = iota
|
||||||
MSG_TYPE_HEARTBEAT
|
|
||||||
MSG_TYPE_REGISTER
|
MSG_TYPE_REGISTER
|
||||||
|
MSG_TYPE_HEARTBEAT
|
||||||
MSG_TYPE_SESSION_CREATE
|
MSG_TYPE_SESSION_CREATE
|
||||||
MSG_TYPE_SESSION_DATA
|
MSG_TYPE_SESSION_DATA
|
||||||
MSG_TYPE_SESSION_DESTORY
|
MSG_TYPE_SESSION_DESTORY
|
||||||
@ -149,9 +149,10 @@ func (dev *Device) readLoop() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !parseDeviceInfo(dev, data) {
|
if !parseDeviceInfo(dev, data) {
|
||||||
|
log.Error().Msg("parseDeviceInfo Failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dev.WriteMsg(MSG_TYPE_TUNNEL_CREATE, []byte{})
|
// dev.WriteMsg(MSG_TYPE_TUNNEL_CREATE, []byte{})
|
||||||
dev.br.register <- dev
|
dev.br.register <- dev
|
||||||
|
|
||||||
case MSG_TYPE_SESSION_CREATE:
|
case MSG_TYPE_SESSION_CREATE:
|
||||||
|
Loading…
Reference in New Issue
Block a user