예제 #1
0
파일: engine.go 프로젝트: aonx/momonga
func (self *Momonga) SendMessage(topic string, message []byte, qos int) {
	msg := codec.NewPublishMessage()
	msg.TopicName = topic
	msg.Payload = message
	msg.QosLevel = qos
	self.SendPublishMessage(msg, "", false)
}
예제 #2
0
func (self *MyConnection) Publish(TopicName string, Payload []byte, QosLevel int, retain bool, opaque interface{}) {
	sb := codec.NewPublishMessage()
	sb.TopicName = TopicName
	sb.Payload = Payload
	sb.QosLevel = QosLevel

	state := self.GetState()
	if state == STATE_CONNECTED || state == STATE_CONNECTING {
		if retain {
			sb.Retain = 1
		}

		if sb.QosLevel < 0 {
			self.logger.Error("QoS under zero. %s: %#v", self.Id, sb)
			return
		}

		if sb.QosLevel > 0 {
			id := self.InflightTable.NewId()
			sb.PacketIdentifier = id
			self.InflightTable.Register(id, sb, nil)
		}

		e := self.writeMessage(sb)
		if e != nil {
			if v, ok := self.Events["error"].(func(error)); ok {
				v(e)
			}
		}
		self.invalidateTimer()
	} else {
		self.OfflineQueue = append(self.OfflineQueue, sb)
	}
}
예제 #3
0
파일: engine.go 프로젝트: aonx/momonga
func (self *Momonga) setupCallback() {
	self.OutGoingTable.SetOnFinish(func(id uint16, message codec.Message, opaque interface{}) {
		switch message.GetType() {
		case codec.PACKET_TYPE_PUBLISH:
			p := message.(*codec.PublishMessage)
			if p.QosLevel == 2 {
				ack := codec.NewPubcompMessage()
				ack.PacketIdentifier = p.PacketIdentifier
				// TODO: WHAAAT? I don't remember this
				//				if conn != nil {
				//					conn.WriteMessageQueue(ack)
				//				}
			}
			break
		default:
			log.Debug("1Not supported; %d", message.GetType())
		}
	})

	// For now
	if self.EnableSys {
		msg := codec.NewPublishMessage()
		msg.TopicName = "$SYS/broker/broker/version"
		msg.Payload = []byte("0.1.0")
		msg.Retain = 1

		self.SendPublishMessage(msg, "", false)
	}
}
예제 #4
0
파일: engine.go 프로젝트: aonx/momonga
func (self *Momonga) SendWillMessage(conn Connection) {
	will := conn.GetWillMessage()
	msg := codec.NewPublishMessage()
	msg.TopicName = will.Topic
	msg.Payload = []byte(will.Message)
	msg.QosLevel = int(will.Qos)

	self.SendPublishMessage(msg, conn.GetId(), conn.IsBridge())
}
예제 #5
0
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?
}
예제 #6
0
파일: engine_test.go 프로젝트: aonx/momonga
func (s *EngineSuite) BenchmarkSimple(c *C) {
	log.SetupLogging("error", "stdout")

	engine := CreateEngine()
	go engine.Run()

	mock := &MockConnection{}
	conn := NewMyConnection(nil)
	conn.SetMyConnection(mock)
	conn.SetId("debug")

	hndr := NewHandler(conn, engine)
	conn.SetOpaque(hndr)

	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)

	for i := 0; i < c.N; i++ {
		// (Client) Publish
		pub := codec.NewPublishMessage()
		pub.TopicName = "/debug"
		pub.Payload = []byte("hello")
		codec.WriteMessageTo(pub, mock)

		// (Server)
		conn.ParseMessage()
	}

	// That's it.
	engine.Terminate()
}
예제 #7
0
파일: engine_test.go 프로젝트: aonx/momonga
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()
}