Esempio n. 1
0
// getBroker gets or creates a broker association and returns the broker
// the first time it also starts a goroutine that receives downlink from the broker
func (r *router) getBroker(brokerAnnouncement *pb_discovery.Announcement) (*broker, error) {
	// We're going to be optimistic and guess that the broker is already active
	r.brokersLock.RLock()
	brk, ok := r.brokers[brokerAnnouncement.Id]
	r.brokersLock.RUnlock()
	if ok {
		return brk, nil
	}

	// If it doesn't we still have to lock
	r.brokersLock.Lock()
	defer r.brokersLock.Unlock()
	if _, ok := r.brokers[brokerAnnouncement.Id]; !ok {

		// Connect to the server
		// TODO(htdvisser): This is blocking
		conn, err := brokerAnnouncement.Dial()
		if err != nil {
			return nil, err
		}
		client := pb_broker.NewBrokerClient(conn)

		association := pb_broker.NewMonitoredRouterStream(client, func() context.Context {
			return r.GetContext("")
		})
		downlink := association.Channel()

		brk := &broker{
			conn:        conn,
			association: association,
			client:      client,
			uplink:      make(chan *pb_broker.UplinkMessage),
		}

		go func() {
			for {
				select {
				case message := <-brk.uplink:
					association.Send(message)
				case message := <-downlink:
					go r.HandleDownlink(message)
				}
			}
		}()

		r.brokers[brokerAnnouncement.Id] = brk
	}
	return r.brokers[brokerAnnouncement.Id], nil
}
Esempio n. 2
0
func (h *handler) associateBroker() error {
	broker, err := h.Discover("broker", h.ttnBrokerID)
	if err != nil {
		return err
	}
	conn, err := broker.Dial()
	if err != nil {
		return err
	}
	h.ttnBrokerConn = conn
	h.ttnBroker = pb_broker.NewBrokerClient(conn)
	h.ttnBrokerManager = pb_broker.NewBrokerManagerClient(conn)

	h.downlink = make(chan *pb_broker.DownlinkMessage)

	contextFunc := func() context.Context { return h.GetContext("") }

	upStream := pb_broker.NewMonitoredHandlerSubscribeStream(h.ttnBroker, contextFunc)
	downStream := pb_broker.NewMonitoredHandlerPublishStream(h.ttnBroker, contextFunc)

	go func() {
		for message := range upStream.Channel() {
			go h.HandleUplink(message)
		}
	}()

	go func() {
		for message := range h.downlink {
			if err := downStream.Send(message); err != nil {
				h.Ctx.WithError(err).Warn("Could not send downlink to Broker")
			}
		}
	}()

	return nil
}