// NewClient creates a new DefaultClient func NewClient(ctx log.Interface, id, username, password string, brokers ...string) Client { if ctx == nil { ctx = log.Get() } mqttOpts := MQTT.NewClientOptions() for _, broker := range brokers { mqttOpts.AddBroker(broker) } mqttOpts.SetClientID(fmt.Sprintf("%s-%s", id, random.String(16))) mqttOpts.SetUsername(username) mqttOpts.SetPassword(password) // TODO: Some tuning of these values probably won't hurt: mqttOpts.SetKeepAlive(30 * time.Second) mqttOpts.SetPingTimeout(10 * time.Second) mqttOpts.SetCleanSession(true) mqttOpts.SetDefaultPublishHandler(func(client MQTT.Client, msg MQTT.Message) { ctx.Warnf("Received unhandled message: %v", msg) }) var reconnecting bool mqttOpts.SetConnectionLostHandler(func(client MQTT.Client, err error) { ctx.Warnf("Disconnected (%s). Reconnecting...", err.Error()) reconnecting = true }) ttnClient := &DefaultClient{ ctx: ctx, subscriptions: make(map[string]MQTT.MessageHandler), } mqttOpts.SetOnConnectHandler(func(client MQTT.Client) { ctx.Info("Connected to MQTT") if reconnecting { for topic, handler := range ttnClient.subscriptions { ctx.Infof("Re-subscribing to topic: %s", topic) ttnClient.subscribe(topic, handler) } reconnecting = false } }) ttnClient.mqtt = MQTT.NewClient(mqttOpts) return ttnClient }
// see interface func (s *schedule) GetOption(timestamp uint32, length uint32) (id string, score uint) { id = random.String(32) score = s.getConflicts(timestamp, length) item := &scheduledItem{ id: id, deadlineAt: s.realtime(timestamp).Add(-1 * Deadline), timestamp: timestamp, length: length, score: score, } s.Lock() defer s.Unlock() s.items[id] = item return id, score }
func (r *routerRPC) getDownlink(md metadata.MD) (ch <-chan *pb.DownlinkMessage, cancel func(), err error) { gateway, err := r.gatewayFromMetadata(md) if err != nil { return nil, nil, err } subscriptionID := random.String(10) ch = make(chan *pb.DownlinkMessage) cancel = func() { r.router.UnsubscribeDownlink(gateway.ID, subscriptionID) } downlinkChannel, err := r.router.SubscribeDownlink(gateway.ID, subscriptionID) if err != nil { return nil, nil, err } return downlinkChannel, cancel, nil }