package tcp import ( "fmt" "go.uber.org/zap" "golang.org/x/text/encoding/simplifiedchinese" "golang.org/x/text/transform" "io" "net" "regexp" "server/dao" "server/global" "strconv" "strings" "time" ) var ( Devices = make(map[string]*Device) // 存储连接的全局 map ) type Device struct { Info dao.Screens Conn net.Conn IsLogin bool LastTime time.Time SumHighSpeed int SumLowSpeed int } // 实例所有设备 func InitDevices() { //// 将数据库中的设备全部离线 //screens, _ := dao.QueryAllScreens() //for _, screen := range screens { // Devices[screen.Sn] = &Device{Info: screen} //} } func (s *Device) Start(conn net.Conn) { s.Conn = conn go s.Process() } func (s *Device) Process() { // 函数执行完之后关闭连接 defer s.Conn.Close() for { buf := make([]byte, 256) // 将tcp连接读取到的数据读取到byte数组中, 返回读取到的byte的数目 n, err := s.Conn.Read(buf) if err != nil { // 从客户端读取数据的过程中发生错误 这里如果没读到可以视为设备离线了 global.GVA_LOG.Error("read err,dev offLine") break } data := string(buf[:n]) fmt.Println("读取", string(buf[:n])) if data[2:7] == "login" { s.Conn.Write([]byte("login:successful")) } if data[2:11] == "heartbeat" { //默认一分钟发一次心跳 s.LastTime = time.Now() if !s.IsLogin { s.Conn.Write([]byte("{'trans':'on'}")) //开启上传状态 screen, _ := dao.QueryScreensBySn(data[20:44]) s.Info = screen s.IsLogin = true Devices[data[20:44]] = s _ = dao.UpdateScreensStatusBySn(s.Info.Sn, 1) } //更新上次发送心跳时间 Devices[data[20:44]].Conn = s.Conn global.GVA_LOG.Info("设备心跳", zap.String("ScreensName", s.Info.ScreensName)) } if strings.Contains(data, `"status":"highspeed"`) { s.SumLowSpeed = 0 re := regexp.MustCompile(`"speed1":"(\d+)"`) match := re.FindStringSubmatch(data) if len(match) > 1 { speed1, _ := strconv.Atoi(match[1]) if speed1 > 30 { //大于40认为超速 s.SumHighSpeed++ if s.SumHighSpeed >= 3 { fmt.Println("********************************************************************超速了") } } else { s.SumHighSpeed = 0 } } else { fmt.Println("Speed1 not found") continue } } //判断低速 if strings.Contains(data, `"status":"normalspeed"`) { s.SumHighSpeed = 0 re := regexp.MustCompile(`"speed1":"(\d+)"`) match := re.FindStringSubmatch(data) if len(match) > 1 { speed1, _ := strconv.Atoi(match[1]) if speed1 < 20 { //小于10认为低速 s.SumLowSpeed++ if s.SumLowSpeed >= 8 { fmt.Println("********************************************************************低低速了") } } else { s.SumLowSpeed = 0 } } else { fmt.Println("Speed1 not found") continue } } //if strings.Contains(data, `"status":"none"`) { // s.SumHighSpeed = 0 // s.SumLowSpeed = 0 //} } } //func IsOnline() { // t := time.NewTicker(5 * time.Second) //每分钟 // for { // select { // case <-t.C: // topic := devices.MqttService.GetTopic("071995171560000000c40808", devices.TopicChanStatus) // err := devices.MqttService.Publish(topic, "1") // if err != nil { // fmt.Println(err.Error()) // } // fmt.Println("发送了。。。。。。。。。。。。。。。。。。。。。。") // for _, device := range Devices { // //commond := `{ // // "setdiscontent0":{ // // "num":"7", // // "effect":"11", // // "speed":"3", // // "stay":"5", // // "total":"100", // // "color":"3", // // "content":"[24M]哈哈哈哈" // // } // //}` // // //conyuyin := `{"audionumset0":{"num0":"21","num1":"[m0]前方路口,注意来车","num2":"[m1]您已超速,请减速","num3":"[m0]对向来车,请减速","num4":"[m0]双向来车,请减速"}}` // // //consy := `` // // //gb2312, _ := UTF8ToGB2312(conyuyin) // // //n, err := Devices[device.Info.Sn].Conn.Write(gb2312) // //fmt.Println("我是n,", n) // //if err != nil { // // fmt.Println("err:", err) // //} // //fmt.Println("发送了。。。。。。。。。。。。。。。。。。。。。。") // //符合条件 // if time.Now().Add(-2*time.Minute).After(device.LastTime) || device.LastTime.IsZero() { // state := 0 // err := dao.UpdateScreensStatusBySn(device.Info.Sn, state) // delete(Devices, device.Info.Sn) // if err != nil { // continue // } // device.Info.Status = 0 // global.GVA_LOG.Info("设备离线了", zap.String("ScreensName", device.Info.ScreensName)) // } // } // } // } //} func UTF8ToGB2312(s string) ([]byte, error) { reader := transform.NewReader(strings.NewReader(s), simplifiedchinese.GB18030.NewEncoder()) return io.ReadAll(reader) }