package AiotSwitchSDK import ( "encoding/json" "errors" "fmt" "github.com/nats-io/nats.go" "github.com/vmihailenco/msgpack/v5" "io/ioutil" "os" "path/filepath" "time" ) // 协议基础信息 var SwitchName string // 连接地址 var SwitchConnect string // 连接地址 var SwitchDescribe string // 协议描述 // 参数配置模版 var SwitchConfig = map[string]map[string]string{} var ns *nats.Conn var funPullHandleStruct func(T_topic string, T_data []byte) error /* name:服务名称 默认 程序名 nats: NATS 地址 默认 nats://127.0.0.1:6503 funPH: 平台-> Switch网关方法 */ func AiotSwitchInit(name, nats string, funPH func(T_topic string, T_data []byte) error) { funPullHandleStruct = nil if len(name) == 0 { name = filepath.Base(os.Args[0]) // 程序名 } SwitchName = name if len(nats) == 0 { nats = "nats://127.0.0.1:6503" // 程序名 } funPullHandleStruct = funPH initNats(nats) initConfig(SwitchName) funPullHandle(SwitchName) } func initNats(url string) { var err error // 连接Nats服务器 ns, err = nats.Connect(url, nats.MaxReconnects(10), nats.ReconnectWait(10*time.Second), nats.DisconnectErrHandler(func(nc *nats.Conn, err error) { // handle disconnect error event fmt.Println("natsS.DisconnectErrHandler 断开 ", err) }), nats.ReconnectHandler(func(nc *nats.Conn) { // handle reconnect event fmt.Println("natsS.ReconnectHandler, 已经重新连接 ", err) })) if err != nil { fmt.Println("natsS 连接失败!", err) panic(any("natsS 连接失败!" + url)) } if err != nil { fmt.Println("nats 连接失败!", err) panic(any(err)) } fmt.Println("nats OK!") } // 配置文件 func initConfig(name string) { Configjson := "./" + name + "json" _, err := os.Stat(Configjson) // 用你的文件路径替换"/path/to/your/file" if os.IsNotExist(err) { fmt.Println("文件不存在") jsonData, err := json.Marshal(SwitchConfig) if err != nil { fmt.Println(err) } err = ioutil.WriteFile(Configjson, jsonData, 0644) if err != nil { fmt.Println("Error unmarshalling JSON:", err) } } else { fmt.Println("文件存在") jsonData, err := ioutil.ReadFile(Configjson) if err != nil { fmt.Println(err) } err = json.Unmarshal(jsonData, &SwitchConfig) if err != nil { fmt.Println("Error unmarshalling JSON:", err) } } // nats 注册 服务 type Struct struct { T_name string T_SwitchConfig map[string]map[string]string } b, _ := msgpack.Marshal(&Struct{T_name: SwitchName, T_SwitchConfig: SwitchConfig}) // 请求-响应, 向 test3 发布一个 `help me` 请求数据,设置超时间3秒,如果有多个响应,只接收第一个收到的消息 ns.Request("/Switch/Init", b, 3*time.Second) if err != nil { fmt.Println(err) panic(any("nats 注册失败!")) } } // 设备->平台 设备状态 1 在线 2 离线 func AiotSwitchState(T_sn, T_password string, T_State int, T_Reason string) error { type Struct struct { T_sn string T_password string T_State int T_Reason string } b, _ := msgpack.Marshal(&Struct{T_sn: T_sn, T_password: T_password, T_State: T_State, T_Reason: T_Reason}) // 请求-响应, 向 test3 发布一个 `help me` 请求数据,设置超时间3秒,如果有多个响应,只接收第一个收到的消息 msg, err := ns.Request("/Switch/State", b, 3*time.Second) if err != nil { fmt.Println(err) return errors.New("通讯异常") } if len(msg.Data) != 0 { return errors.New(string(msg.Data)) } return nil } // 设备->平台 验证 func AiotSwitchVerify(T_sn, T_password string) error { type Struct struct { T_sn string T_password string } b, _ := msgpack.Marshal(&Struct{T_sn: T_sn, T_password: T_password}) // 请求-响应, 向 test3 发布一个 `help me` 请求数据,设置超时间3秒,如果有多个响应,只接收第一个收到的消息 msg, err := ns.Request("/Switch/Verify", b, 3*time.Second) if err != nil { fmt.Println(err) return errors.New("通讯异常") } if len(msg.Data) != 0 { return errors.New(string(msg.Data)) } return nil } // 设备->平台 添加设备 func AiotSwitchAdd(T_ProductID, T_ProductKey, T_sn, T_password string) error { type Struct struct { T_ProductID string T_ProductKey string T_sn string T_password string } b, _ := msgpack.Marshal(&Struct{T_sn: T_sn, T_password: T_password, T_ProductID: T_ProductID, T_ProductKey: T_ProductKey}) // 请求-响应, 向 test3 发布一个 `help me` 请求数据,设置超时间3秒,如果有多个响应,只接收第一个收到的消息 msg, err := ns.Request("/Switch/Add", b, 3*time.Second) if err != nil { fmt.Println(err) return errors.New("通讯异常") } if len(msg.Data) != 0 { return errors.New(string(msg.Data)) } return nil } // 设备->平台 func AiotSwitchPush(T_sn, T_password, T_topic string, T_data []byte) error { type Struct struct { T_sn string T_password string T_topic string T_data []byte } b, _ := msgpack.Marshal(&Struct{T_sn: T_sn, T_password: T_password, T_topic: T_topic, T_data: T_data}) // 请求-响应, 向 test3 发布一个 `help me` 请求数据,设置超时间3秒,如果有多个响应,只接收第一个收到的消息 msg, err := ns.Request("/Switch/Pull", b, 3*time.Second) if err != nil { fmt.Println(err) return errors.New("通讯异常") } if len(msg.Data) != 0 { return errors.New(string(msg.Data)) } return nil } // 平台->设备 func funPullHandle(T_name string) { ns.Subscribe("/Switch/"+T_name, func(m *nats.Msg) { go func(m *nats.Msg) { type Struct struct { T_topic string T_data []byte } var date_r Struct err := msgpack.Unmarshal(m.Data, &date_r) if err != nil { fmt.Println("Nats:", err) ns.Publish(m.Reply, []byte("Unmarshal 错误!")) return } // 防止 没有给方法报错 if funPullHandleStruct != nil { err = funPullHandleStruct(date_r.T_topic, date_r.T_data) if err != nil { ns.Publish(m.Reply, []byte(err.Error())) return } } ns.Publish(m.Reply, []byte("")) }(m) }) }