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 }