github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/cmd/cli/commands/client/client.go (about) 1 // This file is part of the Smart Home 2 // Program complex distribution https://github.com/e154/smart-home 3 // Copyright (C) 2016-2023, Filippov Alex 4 // 5 // This library is free software: you can redistribute it and/or 6 // modify it under the terms of the GNU Lesser General Public 7 // License as published by the Free Software Foundation; either 8 // version 3 of the License, or (at your option) any later version. 9 // 10 // This library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 // Library General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public 16 // License along with this library. If not, see 17 // <https://www.gnu.org/licenses/>. 18 19 // Package client 20 // The following command will run pingmq as a client, subscribing to /ping/failure/+ 21 // topic and receiving any failed ping attempts. 22 // 23 // $ ./pingmq client -t /ping/failure/+ 24 // 8.8.8.6: Request timed out for seq 1 25 // 26 // The following command will run pingmq as a client, subscribing to /ping/failure/+ 27 // topic and receiving any failed ping attempts. 28 // 29 // $ ./pingmq client -t /ping/success/+ 30 // 8 bytes from 8.8.8.8: seq=1 ttl=56 tos=32 time=21.753711ms 31 // 32 // One can also subscribe to a specific IP by using the following command. 33 // 34 // $ ./pingmq client -t /ping/+/8.8.8.8 35 // 8 bytes from 8.8.8.8: seq=1 ttl=56 tos=32 time=21.753711ms 36 package client 37 38 import ( 39 "fmt" 40 "log" 41 "os" 42 "strings" 43 "time" 44 45 "github.com/e154/smart-home/system/mqtt_client" 46 mqtt "github.com/eclipse/paho.mqtt.golang" 47 "github.com/koron/netx" 48 "github.com/spf13/cobra" 49 ) 50 51 var ( 52 // Client ... 53 Client = &cobra.Command{ 54 Use: "client", 55 Short: "client subscribes to the pingmq server and prints out the ping results", 56 } 57 58 clientURI string 59 clientTopics strlist 60 user, password string 61 62 done chan struct{} 63 ) 64 65 type strlist []string 66 67 // String ... 68 func (s *strlist) String() string { 69 return fmt.Sprint(*s) 70 } 71 72 // Type ... 73 func (s *strlist) Type() string { 74 return "strlist" 75 } 76 77 // Set ... 78 func (s *strlist) Set(value string) error { 79 for _, ip := range strings.Split(value, ",") { 80 *s = append(*s, ip) 81 } 82 83 return nil 84 } 85 86 func init() { 87 Client.Flags().StringVarP(&clientURI, "server", "s", "tcp://127.0.0.1:1883", "PingMQ server to connect to") 88 Client.Flags().VarP(&clientTopics, "topic", "t", "Comma separated list of topics to subscribe to") 89 Client.Flags().StringVarP(&user, "user", "u", "node1", "user name") 90 Client.Flags().StringVarP(&password, "password", "p", "node1", "password") 91 Client.Run = client 92 93 done = make(chan struct{}) 94 } 95 96 func onPublish(i mqtt.Client, msg mqtt.Message) { 97 98 pr := &netx.PingResult{} 99 if err := pr.GobDecode(msg.Payload()); err != nil { 100 fmt.Println(string(msg.Payload())) 101 return 102 } 103 104 log.Println(pr) 105 } 106 107 func client(cmd *cobra.Command, args []string) { 108 109 cfg := &mqtt_client.Config{ 110 CleanSession: true, 111 Broker: clientURI, 112 KeepAlive: 300, 113 Username: user, 114 Password: password, 115 ClientID: fmt.Sprintf("pingmqclient%d%d", os.Getpid(), time.Now().Unix()), 116 } 117 c, err := mqtt_client.NewClient(cfg) 118 if err != nil { 119 log.Fatalln(err.Error()) 120 return 121 } 122 123 if err = c.Connect(); err != nil { 124 log.Fatalln(err.Error()) 125 return 126 } 127 128 for _, t := range clientTopics { 129 if err := c.Subscribe(t, 0, onPublish); err != nil { 130 log.Fatalln(err.Error()) 131 } 132 } 133 134 <-done 135 }