github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/cmd/pub_client/main.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/json"
     5  	"flag"
     6  	"fmt"
     7  	"os"
     8  	"path"
     9  	"time"
    10  
    11  	mqtt "github.com/eclipse/paho.mqtt.golang"
    12  	"github.com/golang/protobuf/proto"
    13  	"github.com/google/uuid"
    14  	"github.com/pkg/errors"
    15  
    16  	"github.com/machinefi/w3bstream/pkg/depends/base/types"
    17  	conflog "github.com/machinefi/w3bstream/pkg/depends/conf/log"
    18  	confmqtt "github.com/machinefi/w3bstream/pkg/depends/conf/mqtt"
    19  	"github.com/machinefi/w3bstream/pkg/depends/protocol/eventpb"
    20  	"github.com/machinefi/w3bstream/pkg/depends/x/misc/retry"
    21  	"github.com/machinefi/w3bstream/pkg/depends/x/misc/timer"
    22  	"github.com/machinefi/w3bstream/pkg/modules/event"
    23  )
    24  
    25  var (
    26  	broker *confmqtt.Broker
    27  	logger = conflog.Std()
    28  )
    29  
    30  func init() {
    31  	flag.StringVar(&mn, "mn", "", "publisher(device) mn")
    32  	flag.StringVar(&topic, "topic", "", "publish topic")
    33  	flag.StringVar(&token, "token", "", "publish token")
    34  	flag.StringVar(&data, "data", "", "payload data, read file pls use '@PATH'")
    35  	flag.StringVar(&seq, "seq", "", "message sequence")
    36  	flag.StringVar(&host, "host", "localhost", "mqtt broker host")
    37  	flag.IntVar(&port, "port", 1883, "mqtt broker port")
    38  	flag.StringVar(&username, "username", "", "mqtt client username")
    39  	flag.StringVar(&password, "password", "", "mqtt client password")
    40  	flag.IntVar(&wait, "wait", 10, "mqtt wait ack timeout(seconds)")
    41  	flag.Parse()
    42  }
    43  
    44  var (
    45  	mn       string         // publisher mn
    46  	data     string         // message payload
    47  	topic    string         // mqtt topic
    48  	token    string         // publisher token
    49  	host     string         // mqtt broker host
    50  	port     int            // mqtt broker port
    51  	username string         // mqtt client username
    52  	password string         // mqtt client password
    53  	wait     int            // mqtt wait ack timeout
    54  	seq      string         // message sequence
    55  	raw      []byte         // mqtt message
    56  	msg      *eventpb.Event // mqtt message (protobuf)
    57  )
    58  
    59  func init() {
    60  	if seq == "" {
    61  		seq = uuid.NewString()
    62  	}
    63  	if mn == "" {
    64  		mn = uuid.NewString()
    65  	}
    66  	if host == "" {
    67  		host = "localhost"
    68  	}
    69  	if port == 0 {
    70  		port = 1883
    71  	}
    72  
    73  	broker = &confmqtt.Broker{
    74  		Server: types.Endpoint{
    75  			Scheme:   "mqtt",
    76  			Hostname: host,
    77  			Port:     uint16(port),
    78  			Username: username,
    79  			Password: types.Password(password),
    80  		},
    81  		Retry:     *retry.Default,
    82  		Timeout:   types.Duration(time.Second * time.Duration(wait)),
    83  		Keepalive: types.Duration(time.Second * time.Duration(wait)),
    84  		QoS:       confmqtt.QOS__ONLY_ONCE,
    85  	}
    86  
    87  	broker.SetDefault()
    88  	if err := broker.Init(); err != nil {
    89  		panic(errors.Wrap(err, "init broker"))
    90  	}
    91  
    92  	var err error
    93  
    94  	pl := []byte(data)
    95  	if len(data) > 0 && data[0] == '@' {
    96  		pl, err = os.ReadFile(data[1:])
    97  		if err != nil {
    98  			panic(errors.Wrap(err, "read file: "+data[1:]))
    99  		}
   100  	}
   101  
   102  	msg = &eventpb.Event{
   103  		Header: &eventpb.Header{
   104  			Token:   token,
   105  			PubTime: time.Now().UTC().UnixMicro(),
   106  			EventId: seq,
   107  			PubId:   mn,
   108  		},
   109  		Payload: pl,
   110  	}
   111  
   112  	raw, err = proto.Marshal(msg)
   113  	if err != nil {
   114  		panic(errors.Wrap(err, "build message"))
   115  	}
   116  }
   117  
   118  func main() {
   119  	c, err := broker.Client(mn)
   120  	if err != nil {
   121  		fmt.Println(err)
   122  		return
   123  	}
   124  	cost := timer.Start()
   125  	err = c.WithTopic(topic).Publish(raw)
   126  	if err != nil {
   127  		fmt.Println(err)
   128  		return
   129  	}
   130  	fmt.Println(">>>> message published")
   131  
   132  	ack := path.Join("ack", mn)
   133  	fmt.Printf("receive ack from %s\n", ack)
   134  	sig := make(chan interface{})
   135  
   136  	err = c.WithTopic(ack).Subscribe(func(cli mqtt.Client, msg mqtt.Message) {
   137  		fmt.Println("<<<< message ack received")
   138  		rsp := &event.EventRsp{}
   139  		if err = json.Unmarshal(msg.Payload(), rsp); err != nil {
   140  			fmt.Println(err)
   141  		}
   142  		content, _ := json.MarshalIndent(rsp, "", "  ")
   143  		if err != nil {
   144  			fmt.Printf("unmarshal failed %v\n", err)
   145  		} else {
   146  			fmt.Println(string(content))
   147  		}
   148  		sig <- 0
   149  	})
   150  	if err != nil {
   151  		fmt.Println(err)
   152  	}
   153  	select {
   154  	case <-sig:
   155  	case <-time.After(time.Second * time.Duration(wait)):
   156  		fmt.Println("**** message ack timeout")
   157  	}
   158  	fmt.Printf("cost: %dms", cost().Milliseconds())
   159  	_ = c.WithTopic(ack).Unsubscribe()
   160  }