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  }