func Test_persistInbound_pubrel(t *testing.T) {
	ts := &TestStore{}
	pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pub.Qos = 2
	pub.TopicName = "/pub2"
	pub.Payload = []byte{0xCC, 0x06}
	pub.MessageID = 55
	publishKey := inboundKeyFromMID(pub.MessageID)
	ts.Put(publishKey, pub)

	m := packets.NewControlPacket(packets.Pubrel).(*packets.PubrelPacket)
	m.MessageID = 55

	persistInbound(ts, m) // will overwrite publish

	if len(ts.mput) != 2 {
		t.Fatalf("persistInbound in bad state")
	}

	if len(ts.mget) != 0 {
		t.Fatalf("persistInbound in bad state")
	}

	if len(ts.mdel) != 0 {
		t.Fatalf("persistInbound in bad state")
	}
}
func Test_persistInbound_puback(t *testing.T) {
	ts := &TestStore{}
	pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pub.Qos = 1
	pub.TopicName = "/pub1"
	pub.Payload = []byte{0xCC, 0x04}
	pub.MessageID = 53
	publishKey := inboundKeyFromMID(pub.MessageID)
	ts.Put(publishKey, pub)

	m := packets.NewControlPacket(packets.Puback).(*packets.PubackPacket)
	m.MessageID = 53

	persistInbound(ts, m) // "deletes" packets.Publish from store

	if len(ts.mput) != 1 { // not actually deleted in TestStore
		t.Fatalf("persistInbound in bad state")
	}

	if len(ts.mget) != 0 {
		t.Fatalf("persistInbound in bad state")
	}

	if len(ts.mdel) != 1 || ts.mdel[0] != 53 {
		t.Fatalf("persistInbound in bad state")
	}
}
func Test_persistInbound_pubrec(t *testing.T) {
	ts := &TestStore{}
	pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pub.Qos = 2
	pub.TopicName = "/pub2"
	pub.Payload = []byte{0xCC, 0x05}
	pub.MessageID = 54
	publishKey := inboundKeyFromMID(pub.MessageID)
	ts.Put(publishKey, pub)

	m := packets.NewControlPacket(packets.Pubrec).(*packets.PubrecPacket)
	m.MessageID = 54

	persistInbound(ts, m)

	if len(ts.mput) != 1 || ts.mput[0] != 54 {
		t.Fatalf("persistInbound in bad state")
	}

	if len(ts.mget) != 0 {
		t.Fatalf("persistInbound in bad state")
	}

	if len(ts.mdel) != 0 {
		t.Fatalf("persistInbound in bad state")
	}
}
func Test_MatchAndDispatch(t *testing.T) {
	calledback := make(chan bool)

	cb := func(c *Client, m Message) {
		calledback <- true
	}

	pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pub.Qos = 2
	pub.TopicName = "a"
	pub.Payload = []byte("foo")

	msgs := make(chan *packets.PublishPacket)

	router, stopper := newRouter()
	router.addRoute("a", cb)

	router.matchAndDispatch(msgs, true, nil)

	msgs <- pub

	<-calledback

	stopper <- true

	select {
	case msgs <- pub:
		t.Errorf("msgs should not have a listener")
	default:
	}

}
Exemple #5
0
// SubscribeMultiple starts a new subscription for multiple topics. Provide a MessageHandler to
// be executed when a message is published on one of the topics provided.
func (c *Client) SubscribeMultiple(filters map[string]byte, callback MessageHandler) Token {
	var err error
	token := newToken(packets.Subscribe).(*SubscribeToken)
	DEBUG.Println(CLI, "enter SubscribeMultiple")
	if !c.IsConnected() {
		token.err = ErrNotConnected
		token.flowComplete()
		return token
	}
	sub := packets.NewControlPacket(packets.Subscribe).(*packets.SubscribePacket)
	if sub.Topics, sub.Qoss, err = validateSubscribeMap(filters); err != nil {
		token.err = err
		return token
	}

	if callback != nil {
		for topic := range filters {
			c.msgRouter.addRoute(topic, callback)
		}
	}
	token.subs = make([]string, len(sub.Topics))
	copy(token.subs, sub.Topics)
	//c.oboundP <- &PacketAndToken{p: sub, t: token}
	sendServer(c, sub, token)
	DEBUG.Println(CLI, "exit SubscribeMultiple")
	return token
}
Exemple #6
0
// Subscribe starts a new subscription. Provide a MessageHandler to be executed when
// a message is published on the topic provided.
func (c *Client) Subscribe(topic string, qos byte, callback MessageHandler) Token {
	token := newToken(packets.Subscribe).(*SubscribeToken)
	DEBUG.Println(CLI, "enter Subscribe")
	if !c.IsConnected() {
		token.err = ErrNotConnected
		token.flowComplete()
		return token
	}
	sub := packets.NewControlPacket(packets.Subscribe).(*packets.SubscribePacket)
	if err := validateTopicAndQos(topic, qos); err != nil {
		token.err = err
		return token
	}
	sub.Topics = append(sub.Topics, topic)
	sub.Qoss = append(sub.Qoss, qos)
	DEBUG.Println(sub.String())

	if callback != nil {
		c.msgRouter.addRoute(topic, callback)
	}

	token.subs = append(token.subs, topic)
	//c.oboundP <- &PacketAndToken{p: sub, t: token}
	sendServer(c, sub, token)
	DEBUG.Println(CLI, "exit Subscribe")
	return token
}
Exemple #7
0
// Publish will publish a message with the specified QoS
// and content to the specified topic.
// Returns a read only channel used to track
// the delivery of the message.
func (c *Client) Publish(topic string, qos byte, retained bool, payload interface{}) Token {
	token := newToken(packets.Publish).(*PublishToken)
	DEBUG.Println(CLI, "enter Publish")
	if !c.IsConnected() {
		token.err = ErrNotConnected
		token.flowComplete()
		return token
	}
	pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pub.Qos = qos
	pub.TopicName = topic
	pub.Retain = retained
	switch payload.(type) {
	case string:
		pub.Payload = []byte(payload.(string))
	case []byte:
		pub.Payload = payload.([]byte)
	default:
		token.err = errors.New("Unknown payload type")
		token.flowComplete()
		return token
	}

	DEBUG.Println(CLI, "sending publish message, topic:", topic)

	c.obound <- &PacketAndToken{p: pub, t: token}
	return token
}
Exemple #8
0
func newConnectMsgFromOptions(options *ClientOptions) *packets.ConnectPacket {
	m := packets.NewControlPacket(packets.Connect).(*packets.ConnectPacket)

	m.CleanSession = options.CleanSession
	m.WillFlag = options.WillEnabled
	m.WillRetain = options.WillRetained
	m.ClientIdentifier = options.ClientID

	if options.WillEnabled {
		m.WillQos = options.WillQos
		m.WillTopic = options.WillTopic
		m.WillMessage = options.WillPayload
	}

	if options.Username != "" {
		m.UsernameFlag = true
		m.Username = options.Username
		//mustn't have password without user as well
		if options.Password != "" {
			m.PasswordFlag = true
			m.Password = []byte(options.Password)
		}
	}

	m.KeepaliveTimer = uint16(options.KeepAlive.Seconds())

	return m
}
Exemple #9
0
func Test_NewPingReqMessage(t *testing.T) {
	pr := packets.NewControlPacket(packets.Pingreq).(*packets.PingreqPacket)
	if pr.MessageType != packets.Pingreq {
		t.Errorf("NewPingReqMessage bad msg type: %v", pr.MessageType)
	}
	if pr.RemainingLength != 0 {
		t.Errorf("NewPingReqMessage bad remlen, expected 0, got %d", pr.RemainingLength)
	}

	exp := []byte{
		0xC0,
		0x00,
	}

	var buf bytes.Buffer
	pr.Write(&buf)
	bs := buf.Bytes()

	if len(bs) != 2 {
		t.Errorf("NewPingReqMessage.Bytes() wrong length: %d", len(bs))
	}

	if exp[0] != bs[0] || exp[1] != bs[1] {
		t.Errorf("NewPingMessage.Bytes() wrong")
	}
}
Exemple #10
0
func Test_FileStore_Get(t *testing.T) {
	storedir := "/tmp/TestStore/_get"
	f := NewFileStore(storedir)
	f.Open()
	pm := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pm.Qos = 1
	pm.TopicName = "/a/b/c"
	pm.Payload = []byte{0xBE, 0xEF, 0xED}
	pm.MessageID = 120

	key := outboundKeyFromMID(pm.MessageID)
	f.Put(key, pm)

	if !exists(storedir + "/o.120.msg") {
		t.Fatalf("message not in store")
	}

	exp := []byte{
		/* msg type */
		0x32, // qos 1

		/* remlen */
		0x0d,

		/* topic, msg id in varheader */
		0x00, // length of topic
		0x06,
		0x2F, // /
		0x61, // a
		0x2F, // /
		0x62, // b
		0x2F, // /
		0x63, // c

		/* msg id (is always 2 bytes) */
		0x00,
		0x78,

		/*payload */
		0xBE,
		0xEF,
		0xED,
	}

	m := f.Get(key)

	if m == nil {
		t.Fatalf("message not retreived from store")
	}

	var msg bytes.Buffer
	m.Write(&msg)
	if !bytes.Equal(exp, msg.Bytes()) {
		t.Fatal("message from store not same as what went in", msg.Bytes())
	}
}
Exemple #11
0
func Test_MemoryStore_Get(t *testing.T) {
	m := NewMemoryStore()
	m.Open()
	pm := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pm.Qos = 1
	pm.TopicName = "/a/b/c"
	pm.Payload = []byte{0xBE, 0xEF, 0xED}
	pm.MessageID = 120

	key := outboundKeyFromMID(pm.MessageID)
	m.Put(key, pm)

	if len(m.messages) != 1 {
		t.Fatalf("message not in store")
	}

	exp := []byte{
		/* msg type */
		0x32, // qos 1

		/* remlen */
		0x0d,

		/* topic, msg id in varheader */
		0x00, // length of topic
		0x06,
		0x2F, // /
		0x61, // a
		0x2F, // /
		0x62, // b
		0x2F, // /
		0x63, // c

		/* msg id (is always 2 bytes) */
		0x00,
		0x78,

		/*payload */
		0xBE,
		0xEF,
		0xED,
	}

	msg := m.Get(key)

	if msg == nil {
		t.Fatalf("message not retreived from store")
	}

	var buf bytes.Buffer
	msg.Write(&buf)
	if !bytes.Equal(exp, buf.Bytes()) {
		t.Fatalf("message from store not same as what went in")
	}
}
Exemple #12
0
// Disconnect will end the connection with the server, but not before waiting
// the specified number of milliseconds to wait for existing work to be
// completed.
func (c *Client) Disconnect(quiesce uint) {
	if !c.IsConnected() {
		WARN.Println(CLI, "already disconnected")
		return
	}
	DEBUG.Println(CLI, "disconnecting")
	c.setConnected(false)

	dm := packets.NewControlPacket(packets.Disconnect).(*packets.DisconnectPacket)
	dt := newToken(packets.Disconnect)
	c.oboundP <- &PacketAndToken{p: dm, t: dt}

	// wait for work to finish, or quiesce time consumed
	dt.WaitTimeout(time.Duration(quiesce) * time.Millisecond)
	c.disconnect()
}
Exemple #13
0
func Test_MemoryStore_write(t *testing.T) {
	m := NewMemoryStore()
	m.Open()

	pm := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pm.Qos = 1
	pm.TopicName = "/a/b/c"
	pm.Payload = []byte{0xBE, 0xEF, 0xED}
	pm.MessageID = 91
	key := inboundKeyFromMID(pm.MessageID)
	m.Put(key, pm)

	if len(m.messages) != 1 {
		t.Fatalf("message not in store")
	}
}
Exemple #14
0
func Test_persistInbound_connack(t *testing.T) {
	ts := &TestStore{}
	m := packets.NewControlPacket(packets.Connack)
	persistInbound(ts, m)

	if len(ts.mput) != 0 {
		t.Fatalf("persistInbound in bad state")
	}

	if len(ts.mget) != 0 {
		t.Fatalf("persistInbound in bad state")
	}

	if len(ts.mdel) != 0 {
		t.Fatalf("persistInbound in bad state")
	}
}
Exemple #15
0
func Test_persistOutbound_disconnect(t *testing.T) {
	ts := &TestStore{}
	m := packets.NewControlPacket(packets.Disconnect)
	persistOutbound(ts, m)

	if len(ts.mput) != 0 {
		t.Fatalf("persistOutbound put message it should not have")
	}

	if len(ts.mget) != 0 {
		t.Fatalf("persistOutbound get message it should not have")
	}

	if len(ts.mdel) != 0 {
		t.Fatalf("persistOutbound del message it should not have")
	}
}
Exemple #16
0
func Test_FileStore_write(t *testing.T) {
	storedir := "/tmp/TestStore/_write"
	f := NewFileStore(storedir)
	f.Open()

	pm := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pm.Qos = 1
	pm.TopicName = "a/b/c"
	pm.Payload = []byte{0xBE, 0xEF, 0xED}
	pm.MessageID = 91

	key := inboundKeyFromMID(pm.MessageID)
	f.Put(key, pm)

	if !exists(storedir + "/i.91.msg") {
		t.Fatalf("message not in store")
	}

}
Exemple #17
0
func Test_persistOutbound_pubrel(t *testing.T) {
	ts := &TestStore{}
	m := packets.NewControlPacket(packets.Pubrel).(*packets.PubrelPacket)
	m.MessageID = 43

	persistOutbound(ts, m)

	if len(ts.mput) != 1 || ts.mput[0] != 43 {
		t.Fatalf("persistOutbound put message it should not have")
	}

	if len(ts.mget) != 0 {
		t.Fatalf("persistOutbound get message it should not have")
	}

	if len(ts.mdel) != 0 {
		t.Fatalf("persistOutbound del message it should not have")
	}
}
Exemple #18
0
func Test_persistOutbound_unsubscribe(t *testing.T) {
	ts := &TestStore{}
	m := packets.NewControlPacket(packets.Unsubscribe).(*packets.UnsubscribePacket)
	m.Topics = []string{"/posub"}
	m.MessageID = 45
	persistOutbound(ts, m)

	if len(ts.mput) != 1 || ts.mput[0] != 45 {
		t.Fatalf("persistOutbound put message it should not have")
	}

	if len(ts.mget) != 0 {
		t.Fatalf("persistOutbound get message it should not have")
	}

	if len(ts.mdel) != 0 {
		t.Fatalf("persistOutbound del message it should not have")
	}
}
Exemple #19
0
func Test_persistInbound_unsuback(t *testing.T) {
	ts := &TestStore{}

	m := packets.NewControlPacket(packets.Unsuback).(*packets.UnsubackPacket)
	m.MessageID = 58

	persistInbound(ts, m)

	if len(ts.mput) != 0 {
		t.Fatalf("persistInbound in bad state")
	}

	if len(ts.mget) != 0 {
		t.Fatalf("persistInbound in bad state")
	}

	if len(ts.mdel) != 1 || ts.mdel[0] != 58 {
		t.Fatalf("persistInbound in bad state")
	}
}
Exemple #20
0
func Test_persistInbound_pubcomp(t *testing.T) {
	ts := &TestStore{}

	m := packets.NewControlPacket(packets.Pubcomp).(*packets.PubcompPacket)
	m.MessageID = 56

	persistInbound(ts, m)

	if len(ts.mput) != 0 {
		t.Fatalf("persistInbound in bad state")
	}

	if len(ts.mget) != 0 {
		t.Fatalf("persistInbound in bad state")
	}

	if len(ts.mdel) != 1 || ts.mdel[0] != 56 {
		t.Fatalf("persistInbound in bad state")
	}
}
Exemple #21
0
// Unsubscribe will end the subscription from each of the topics provided.
// Messages published to those topics from other clients will no longer be
// received.
func (c *Client) Unsubscribe(topics ...string) Token {
	token := newToken(packets.Unsubscribe).(*UnsubscribeToken)
	DEBUG.Println(CLI, "enter Unsubscribe")
	if !c.IsConnected() {
		token.err = ErrNotConnected
		token.flowComplete()
		return token
	}
	unsub := packets.NewControlPacket(packets.Unsubscribe).(*packets.UnsubscribePacket)
	unsub.Topics = make([]string, len(topics))
	copy(unsub.Topics, topics)
	sendServer(c, unsub, token)
	//c.oboundP <- &PacketAndToken{p: unsub, t: token}
	for _, topic := range topics {
		c.msgRouter.deleteRoute(topic)
	}

	DEBUG.Println(CLI, "exit Unsubscribe")
	return token
}
Exemple #22
0
func Test_persistInbound_publish_2(t *testing.T) {
	ts := &TestStore{}
	m := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	m.Qos = 2
	m.TopicName = "/pipub2"
	m.Payload = []byte{0xCC, 0x03}
	m.MessageID = 52
	persistInbound(ts, m)

	if len(ts.mput) != 1 || ts.mput[0] != 52 {
		t.Fatalf("persistInbound in bad state")
	}

	if len(ts.mget) != 0 {
		t.Fatalf("persistInbound in bad state")
	}

	if len(ts.mdel) != 0 {
		t.Fatalf("persistInbound in bad state")
	}
}
Exemple #23
0
func Test_persistOutbound_publish_2(t *testing.T) {
	ts := &TestStore{}
	m := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	m.Qos = 2
	m.TopicName = "/popub2"
	m.Payload = []byte{0xBB, 0x00}
	m.MessageID = 42
	persistOutbound(ts, m)

	if len(ts.mput) != 1 || ts.mput[0] != 42 {
		t.Fatalf("persistOutbound put message it should not have")
	}

	if len(ts.mget) != 0 {
		t.Fatalf("persistOutbound get message it should not have")
	}

	if len(ts.mdel) != 0 {
		t.Fatalf("persistOutbound del message it should not have")
	}
}
Exemple #24
0
func Test_FileStore_All(t *testing.T) {
	storedir := "/tmp/TestStore/_all"
	f := NewFileStore(storedir)
	f.Open()
	pm := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pm.Qos = 2
	pm.TopicName = "/t/r/v"
	pm.Payload = []byte{0x01, 0x02}
	pm.MessageID = 121

	key := outboundKeyFromMID(pm.MessageID)
	f.Put(key, pm)

	keys := f.All()
	if len(keys) != 1 {
		t.Fatalf("FileStore.All does not have the messages")
	}

	if keys[0] != "o.121" {
		t.Fatalf("FileStore.All has wrong key")
	}
}
Exemple #25
0
func Test_persistOutbound_connect(t *testing.T) {
	ts := &TestStore{}
	m := packets.NewControlPacket(packets.Connect).(*packets.ConnectPacket)
	m.Qos = 0
	m.Username = "******"
	m.Password = []byte("pass")
	m.ClientIdentifier = "cid"
	//m := newConnectMsg(false, false, QOS_ZERO, false, "", nil, "cid", "user", "pass", 10)
	persistOutbound(ts, m)

	if len(ts.mput) != 0 {
		t.Fatalf("persistOutbound put message it should not have")
	}

	if len(ts.mget) != 0 {
		t.Fatalf("persistOutbound get message it should not have")
	}

	if len(ts.mdel) != 0 {
		t.Fatalf("persistOutbound del message it should not have")
	}
}
Exemple #26
0
func Test_MemoryStore_Reset(t *testing.T) {
	m := NewMemoryStore()
	m.Open()

	pm := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pm.Qos = 2
	pm.TopicName = "/f/r/s"
	pm.Payload = []byte{0xAB}
	pm.MessageID = 81

	key := outboundKeyFromMID(pm.MessageID)
	m.Put(key, pm)

	if len(m.messages) != 1 {
		t.Fatalf("message not in memstore")
	}

	m.Reset()

	if len(m.messages) != 0 {
		t.Fatalf("reset did not clear memstore")
	}
}
Exemple #27
0
func Test_MemoryStore_Del(t *testing.T) {
	m := NewMemoryStore()
	m.Open()

	pm := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pm.Qos = 1
	pm.TopicName = "/a/b/c"
	pm.Payload = []byte{0xBE, 0xEF, 0xED}
	pm.MessageID = 17

	key := outboundKeyFromMID(pm.MessageID)

	m.Put(key, pm)

	if len(m.messages) != 1 {
		t.Fatalf("message not in store")
	}

	m.Del(key)

	if len(m.messages) != 1 {
		t.Fatalf("message still exists after deletion")
	}
}
Exemple #28
0
func keepalive(c *Client) {
	var err error
	defer func(c *Client) {
		c.workers.Done()

		if err != nil {
			ERROR.Println(NET, c.options.ClientID+":keepalive closed :", err)
			c.internalConnLost(err)
			return
		}
		if e := recover(); e != nil {
			ERROR.Println(NET, c.options.ClientID, ":", "keepalive panic closed :", e)
			c.internalConnLost(fmt.Errorf("读取数据出现严重错误:%v", e))
			return
		}
		ERROR.Println(NET, c.options.ClientID+":keepalive closed ")
	}(c)
	DEBUG.Println(PNG, "keepalive starting")
	c.pingOutstanding = false
	waittime := c.options.KeepAlive
	for {
		// keeptime := time.Now().Add(c.options.KeepAlive)
		// keep := uint(time.Since(c.lastContact.get()).Seconds())
		// if keep > c.options.KeepAlive.Seconds() {
		// 	keeptime = time.Now().Add(c.options.KeepAlive)
		// } else {
		// 	time.Now().Add(c.options.KeepAlive)
		// }
		select {
		case <-c.stop:
			DEBUG.Println(PNG, "keepalive stopped")
			//c.workers.Done()
			return
		case <-time.After(waittime):
			last := uint(time.Since(c.lastContact.get()).Seconds())
			//DEBUG.Printf("%s last contact: %d (timeout: %d) %b", PNG, last, uint(c.options.KeepAlive.Seconds()), c.pingOutstanding)
			if last >= uint(c.options.KeepAlive.Seconds()) {
				if !c.pingOutstanding {
					//DEBUG.Println(NET, "keepalive sending ping")
					ping := packets.NewControlPacket(packets.Pingreq).(*packets.PingreqPacket)
					c.pingOutstanding = true
					//We don't want to wait behind large messages being sent, the Write call
					//will block until it it able to send the packet.
					//ping.Write(c.conn)
					sendServer(c, ping, nil)
					waittime = c.options.KeepAlive / 4
					if waittime == 0 {
						waittime = 1 * time.Second
					}
					continue
				} else {
					//CRITICAL.Println(PNG, "pingresp not received, disconnecting")
					err = errors.New("pingresp not received, disconnecting")
					return
				}
			}
			waittime = c.options.KeepAlive - time.Since(c.lastContact.get())

		}
	}
}
Exemple #29
0
// receive Message objects on ibound
// store messages if necessary
// send replies on obound
// delete messages from store if necessary
func alllogic(c *Client) {
	var err error
	defer func(c *Client) {
		c.workers.Done()

		if err != nil {
			ERROR.Println(NET, c.options.ClientID+":alllogic stopped :", err)
			c.internalConnLost(err)
			return
		}
		if e := recover(); e != nil {
			ERROR.Println(NET, c.options.ClientID, ":", "alllogic panic closed :", e)
			c.internalConnLost(fmt.Errorf("处理数据逻辑出现严重错误:%v", e))
			return
		}
		ERROR.Println(NET, c.options.ClientID+":alllogic closed ")
	}(c)
	DEBUG.Println(NET, "logic started")

	for {
		DEBUG.Println(NET, "logic waiting for msg on ibound")

		select {
		case msg := <-c.ibound:
			DEBUG.Println(NET, "logic got msg on ibound, type", reflect.TypeOf(msg))
			persistInbound(c.persist, msg)

			switch msg.(type) {
			case *packets.PingrespPacket:
				DEBUG.Println(NET, "received pingresp")
				c.pingOutstanding = false
			case *packets.SubackPacket:
				sa := msg.(*packets.SubackPacket)
				DEBUG.Println(NET, "received suback, id:", sa.MessageID)
				token := c.getToken(sa.MessageID).(*SubscribeToken)
				DEBUG.Println(NET, "granted qoss", sa.GrantedQoss)
				for i, qos := range sa.GrantedQoss {
					token.subResult[token.subs[i]] = qos
				}
				token.flowComplete()
				go c.freeID(sa.MessageID)
			case *packets.UnsubackPacket:
				ua := msg.(*packets.UnsubackPacket)
				DEBUG.Println(NET, "received unsuback, id:", ua.MessageID)
				token := c.getToken(ua.MessageID).(*UnsubscribeToken)
				token.flowComplete()
				go c.freeID(ua.MessageID)
			case *packets.PublishPacket:
				pp := msg.(*packets.PublishPacket)
				DEBUG.Println(NET, "received publish, msgId:", pp.MessageID)
				DEBUG.Println(NET, "putting msg on onPubChan")
				DEBUG.Println(NET, "done putting msg on incomingPubChan")
				select {
				case c.incomingPubChan <- pp:
				case <-c.stop:
					return
				}
				switch pp.Qos {
				case 2:
					pr := packets.NewControlPacket(packets.Pubrec).(*packets.PubrecPacket)
					pr.MessageID = pp.MessageID

					DEBUG.Println(NET, "putting pubrec msg on obound")
					if !sendServer(c, pr, nil) {
						return
					}
					DEBUG.Println(NET, "done putting pubrec msg on obound")
				case 1:
					pa := packets.NewControlPacket(packets.Puback).(*packets.PubackPacket)
					pa.MessageID = pp.MessageID
					DEBUG.Println(NET, "putting puback msg on obound")
					if !sendServer(c, pa, nil) {
						return
					}
					DEBUG.Println(NET, "done putting puback msg on obound")
				}
			case *packets.PubackPacket:
				pa := msg.(*packets.PubackPacket)
				DEBUG.Println(NET, "received puback, id:", pa.MessageID)
				// c.receipts.get(msg.MsgId()) <- Receipt{}
				// c.receipts.end(msg.MsgId())
				c.getToken(pa.MessageID).flowComplete()
				c.freeID(pa.MessageID)
			case *packets.PubrecPacket:
				prec := msg.(*packets.PubrecPacket)
				DEBUG.Println(NET, "received pubrec, id:", prec.MessageID)
				prel := packets.NewControlPacket(packets.Pubrel).(*packets.PubrelPacket)
				prel.MessageID = prec.MessageID
				if !sendServer(c, prel, nil) {
					return
				}
			case *packets.PubrelPacket:
				pr := msg.(*packets.PubrelPacket)
				DEBUG.Println(NET, "received pubrel, id:", pr.MessageID)
				pc := packets.NewControlPacket(packets.Pubcomp).(*packets.PubcompPacket)
				pc.MessageID = pr.MessageID
				if !sendServer(c, pc, nil) {
					return
				}

			case *packets.PubcompPacket:
				pc := msg.(*packets.PubcompPacket)
				DEBUG.Println(NET, "received pubcomp, id:", pc.MessageID)
				c.getToken(pc.MessageID).flowComplete()
				c.freeID(pc.MessageID)
			}

		case <-c.stop:
			WARN.Println(NET, c.options.ClientID+":logic stopped")
			return

		}

	}
}
Exemple #30
0
func Test_FileStore_Reset(t *testing.T) {
	storedir := "/tmp/TestStore/_reset"
	f := NewFileStore(storedir)
	f.Open()

	pm1 := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pm1.Qos = 1
	pm1.TopicName = "/q/w/e"
	pm1.Payload = []byte{0xBB}
	pm1.MessageID = 71
	key1 := inboundKeyFromMID(pm1.MessageID)
	f.Put(key1, pm1)

	pm2 := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pm2.Qos = 1
	pm2.TopicName = "/q/w/e"
	pm2.Payload = []byte{0xBB}
	pm2.MessageID = 72
	key2 := inboundKeyFromMID(pm2.MessageID)
	f.Put(key2, pm2)

	pm3 := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pm3.Qos = 1
	pm3.TopicName = "/q/w/e"
	pm3.Payload = []byte{0xBB}
	pm3.MessageID = 73
	key3 := inboundKeyFromMID(pm3.MessageID)
	f.Put(key3, pm3)

	pm4 := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pm4.Qos = 1
	pm4.TopicName = "/q/w/e"
	pm4.Payload = []byte{0xBB}
	pm4.MessageID = 74
	key4 := inboundKeyFromMID(pm4.MessageID)
	f.Put(key4, pm4)

	pm5 := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
	pm5.Qos = 1
	pm5.TopicName = "/q/w/e"
	pm5.Payload = []byte{0xBB}
	pm5.MessageID = 75
	key5 := inboundKeyFromMID(pm5.MessageID)
	f.Put(key5, pm5)

	if !exists(storedir + "/i.71.msg") {
		t.Fatalf("message not in store")
	}

	if !exists(storedir + "/i.72.msg") {
		t.Fatalf("message not in store")
	}

	if !exists(storedir + "/i.73.msg") {
		t.Fatalf("message not in store")
	}

	if !exists(storedir + "/i.74.msg") {
		t.Fatalf("message not in store")
	}

	if !exists(storedir + "/i.75.msg") {
		t.Fatalf("message not in store")
	}

	f.Reset()

	if exists(storedir + "/i.71.msg") {
		t.Fatalf("message still exists after reset")
	}

	if exists(storedir + "/i.72.msg") {
		t.Fatalf("message still exists after reset")
	}

	if exists(storedir + "/i.73.msg") {
		t.Fatalf("message still exists after reset")
	}

	if exists(storedir + "/i.74.msg") {
		t.Fatalf("message still exists after reset")
	}

	if exists(storedir + "/i.75.msg") {
		t.Fatalf("message still exists after reset")
	}
}