// For SUBSCRIBE message, we should add subscriber, then send back SUBACK func (this *service) processSubscribe(msg *message.SubscribeMessage) error { resp := message.NewSubackMessage() resp.SetPacketId(msg.PacketId()) // Subscribe to the different topics var retcodes []byte topics := msg.Topics() qos := msg.Qos() this.rmsgs = this.rmsgs[0:0] for i, t := range topics { rqos, err := this.topicsMgr.Subscribe(t, qos[i], &this.onpub) if err != nil { return err } this.sess.AddTopic(string(t), qos[i]) retcodes = append(retcodes, rqos) // yeah I am not checking errors here. If there's an error we don't want the // subscription to stop, just let it go. this.topicsMgr.Retained(t, &this.rmsgs) glog.Debugf("(%s) topic = %s, retained count = %d", this.cid(), string(t), len(this.rmsgs)) } if err := resp.AddReturnCodes(retcodes); err != nil { return err } if _, err := this.writeMessage(resp); err != nil { return err } for _, rm := range this.rmsgs { if err := this.publish(rm, nil); err != nil { glog.Errorf("service/processSubscribe: Error publishing retained message: %v", err) return err } } return nil }
// For SUBSCRIBE message, we should add subscriber, then send back SUBACK func (this *service) processSubscribe(msg *message.SubscribeMessage) error { resp := message.NewSubackMessage() resp.SetPacketId(msg.PacketId()) // Subscribe to the different topics var retcodes []byte topics := msg.Topics() qos := msg.Qos() // fmt.Printf("this.id: %d, this.sess.ID(): %s\n", this.id, this.cid()) for i, t := range topics { rqos, err := this.topicsMgr.Subscribe(t, qos[i], &this.onpub, this.sess.ID()) // rqos, err := this.topicsMgr.Subscribe(t, qos[i], &this) if err != nil { Log.Errorc(func() string { return fmt.Sprintf("(%s) subscribe topic %s failed: %s", this.cid(), t, err) }) this.stop() return err } Log.Infoc(func() string { return fmt.Sprintf("(%s) subscribe topic %s", this.cid(), t) }) this.sess.AddTopic(string(t), qos[i]) retcodes = append(retcodes, rqos) } if err := resp.AddReturnCodes(retcodes); err != nil { return err } if _, err := this.writeMessage(resp); err != nil { return err } for _, t := range topics { go this.pushOfflineMessage(string(t)) } return nil }
func (this *service) subscribe(msg *message.SubscribeMessage, onComplete OnCompleteFunc, onPublish OnPublishFunc) error { if onPublish == nil { return fmt.Errorf("onPublish function is nil. No need to subscribe.") } _, err := this.writeMessage(msg) if err != nil { return fmt.Errorf("(%s) Error sending %s message: %v", this.cid(), msg.Name(), err) } var onc OnCompleteFunc = func(msg, ack message.Message, err error) error { onComplete := onComplete onPublish := onPublish if err != nil { if onComplete != nil { return onComplete(msg, ack, err) } return err } sub, ok := msg.(*message.SubscribeMessage) if !ok { if onComplete != nil { return onComplete(msg, ack, fmt.Errorf("Invalid SubscribeMessage received")) } return nil } suback, ok := ack.(*message.SubackMessage) if !ok { if onComplete != nil { return onComplete(msg, ack, fmt.Errorf("Invalid SubackMessage received")) } return nil } if sub.PacketId() != suback.PacketId() { if onComplete != nil { return onComplete(msg, ack, fmt.Errorf("Sub and Suback packet ID not the same. %d != %d.", sub.PacketId(), suback.PacketId())) } return nil } retcodes := suback.ReturnCodes() topics := sub.Topics() if len(topics) != len(retcodes) { if onComplete != nil { return onComplete(msg, ack, fmt.Errorf("Incorrect number of return codes received. Expecting %d, got %d.", len(topics), len(retcodes))) } return nil } var err2 error = nil for i, t := range topics { c := retcodes[i] if c == message.QosFailure { err2 = fmt.Errorf("Failed to subscribe to '%s'\n%v", string(t), err2) } else { this.sess.AddTopic(string(t), c) _, err := this.topicsMgr.Subscribe(t, c, &onPublish) if err != nil { err2 = fmt.Errorf("Failed to subscribe to '%s' (%v)\n%v", string(t), err, err2) } } } if onComplete != nil { return onComplete(msg, ack, err2) } return err2 } return this.sess.Suback.Wait(msg, onc) }