// handle an incoming PublishPacket func (c *Client) processPublish(publish *packet.PublishPacket) error { if publish.Message.QOS == 1 { // prepare puback packet puback := packet.NewPubackPacket() puback.PacketID = publish.PacketID // acknowledge qos 1 publish err := c.send(puback, true) if err != nil { return c.die(err, false) } } if publish.Message.QOS == 2 { // store packet err := c.Session.SavePacket(incoming, publish) if err != nil { return c.die(err, true) } // prepare pubrec packet pubrec := packet.NewPubrecPacket() pubrec.PacketID = publish.PacketID // acknowledge qos 2 publish err = c.send(pubrec, true) if err != nil { return c.die(err, false) } } if publish.Message.QOS <= 1 { // call callback if c.Callback != nil { c.Callback(&publish.Message, nil) } } return nil }
func TestClientPublishSubscribeQOS2(t *testing.T) { subscribe := packet.NewSubscribePacket() subscribe.Subscriptions = []packet.Subscription{{Topic: "test", QOS: 2}} subscribe.PacketID = 1 suback := packet.NewSubackPacket() suback.ReturnCodes = []uint8{2} suback.PacketID = 1 publish := packet.NewPublishPacket() publish.Message.Topic = "test" publish.Message.Payload = []byte("test") publish.Message.QOS = 2 publish.PacketID = 2 pubrec := packet.NewPubrecPacket() pubrec.PacketID = 2 pubrel := packet.NewPubrelPacket() pubrel.PacketID = 2 pubcomp := packet.NewPubcompPacket() pubcomp.PacketID = 2 broker := tools.NewFlow(). Receive(connectPacket()). Send(connackPacket()). Receive(subscribe). Send(suback). Receive(publish). Send(pubrec). Receive(pubrel). Send(pubcomp). Send(publish). Receive(pubrec). Send(pubrel). Receive(pubcomp). Receive(disconnectPacket()). End() done, port := fakeBroker(t, broker) wait := make(chan struct{}) c := New() c.Callback = func(msg *packet.Message, err error) { assert.NoError(t, err) assert.Equal(t, "test", msg.Topic) assert.Equal(t, []byte("test"), msg.Payload) assert.Equal(t, uint8(2), msg.QOS) assert.False(t, msg.Retain) close(wait) } future, err := c.Connect(NewConfig("tcp://localhost:" + port)) assert.NoError(t, err) assert.NoError(t, future.Wait()) assert.False(t, future.SessionPresent) assert.Equal(t, packet.ConnectionAccepted, future.ReturnCode) subscribeFuture, err := c.Subscribe("test", 2) assert.NoError(t, err) assert.NoError(t, subscribeFuture.Wait()) assert.Equal(t, []uint8{2}, subscribeFuture.ReturnCodes) publishFuture, err := c.Publish("test", []byte("test"), 2, false) assert.NoError(t, err) assert.NoError(t, publishFuture.Wait()) <-wait err = c.Disconnect() assert.NoError(t, err) <-done in, err := c.Session.AllPackets(incoming) assert.NoError(t, err) assert.Equal(t, 0, len(in)) out, err := c.Session.AllPackets(outgoing) assert.NoError(t, err) assert.Equal(t, 0, len(out)) }