func (self *MyConnection) Subscribe(topic string, QoS int) error { sb := codec.NewSubscribeMessage() sb.Payload = append(sb.Payload, codec.SubscribePayload{ TopicPath: topic, RequestedQos: uint8(QoS), }) id := self.InflightTable.NewId() sb.PacketIdentifier = id self.InflightTable.Register(id, sb, nil) self.SubscribeHistory[topic] = QoS if v, ok := self.Events["subscribe"]; ok { if cb, ok := v.(func(*codec.SubscribeMessage, Connection)); ok { cb(sb, self) } } state := self.GetState() if state == STATE_CONNECTED || state == STATE_CONNECTING { self.writeMessage(sb) } else { self.OfflineQueue = append([]codec.Message{sb}, self.OfflineQueue...) } return nil }
func (s *DummyPlugSuite) TestDummyPlug(c *C) { engine := CreateEngine() // 2) Running Engine go engine.Run() p := NewDummyPlug(engine) p.Switch <- true mux := NewMmuxConnection() p.SetState(STATE_CONNECTED) mux.DisableCleanSession() mux.SetId(p.GetId()) mux.Attach(p) // Memo: Normally, engine has correct relation ship between mux and iteself. this is only need for test engine.Connections[p.GetId()] = mux sub := mqtt.NewSubscribeMessage() sub.Payload = append(sub.Payload, mqtt.SubscribePayload{ TopicPath: "/debug/1", RequestedQos: uint8(1), }) sub.Payload = append(sub.Payload, mqtt.SubscribePayload{ TopicPath: "/debug/2", RequestedQos: uint8(2), }) sub.PacketIdentifier = 1 engine.Subscribe(sub, mux) pub := mqtt.NewPublishMessage() pub.TopicName = "/debug/1" pub.Payload = []byte("hello") pub.QosLevel = 1 engine.SendPublishMessage(pub, "dummy", false) pub = mqtt.NewPublishMessage() pub.TopicName = "/debug/2" pub.Payload = []byte("hello") pub.QosLevel = 2 engine.SendPublishMessage(pub, "dummy", false) // TODO: How do i test this? }
func (s *EngineSuite) TestBasic(c *C) { log.SetupLogging("error", "stdout") // This test introduce how to setup custom MQTT server // 1) You need to setup Momonga engine like this. engine := CreateEngine() // 2) Running Engine go engine.Run() // 3) engine expects net.Conn (see MockConnection) mock := &MockConnection{} conn := NewMyConnection(nil) conn.SetMyConnection(mock) conn.SetId("debug") // 4) setup handler. This handler implementation is example. // you can customize behaviour with On method. hndr := NewHandler(conn, engine) conn.SetOpaque(hndr) // 5) Now, msg := codec.NewConnectMessage() msg.Magic = []byte("MQTT") msg.Version = uint8(4) msg.Identifier = "debug" msg.CleanSession = true msg.KeepAlive = uint16(0) // Ping is annoyed at this time codec.WriteMessageTo(msg, mock) // 6) just call conn.ParseMessage(). then handler will work. r, err := conn.ParseMessage() c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_CONNECT) // NOTE: Client turn. don't care this. time.Sleep(time.Millisecond) r, err = conn.ParseMessage() c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_CONNACK) // Subscribe sub := codec.NewSubscribeMessage() sub.Payload = append(sub.Payload, codec.SubscribePayload{TopicPath: "/debug"}) sub.PacketIdentifier = 1 codec.WriteMessageTo(sub, mock) // (Server) r, err = conn.ParseMessage() c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_SUBSCRIBE) rsub := r.(*codec.SubscribeMessage) c.Assert(rsub.PacketIdentifier, Equals, uint16(1)) c.Assert(rsub.Payload[0].TopicPath, Equals, "/debug") // (Client) suback time.Sleep(time.Millisecond) r, err = conn.ParseMessage() c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_SUBACK) // (Client) Publish pub := codec.NewPublishMessage() pub.TopicName = "/debug" pub.Payload = []byte("hello") codec.WriteMessageTo(pub, mock) // (Server) r, err = conn.ParseMessage() c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_PUBLISH) rpub := r.(*codec.PublishMessage) c.Assert(rpub.TopicName, Equals, "/debug") // (Client) received publish message time.Sleep(time.Millisecond) r, err = conn.ParseMessage() rp := r.(*codec.PublishMessage) c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_PUBLISH) c.Assert(rp.TopicName, Equals, "/debug") c.Assert(string(rp.Payload), Equals, "hello") // okay, now disconnect from server dis := codec.NewDisconnectMessage() codec.WriteMessageTo(dis, mock) r, err = conn.ParseMessage() c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_DISCONNECT) // then, receive EOF from server. time.Sleep(time.Millisecond) r, err = conn.ParseMessage() c.Assert(err, Equals, nil) // That's it. engine.Terminate() }