Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MQTT client should wait for PUBLISH before sending PUBREC #359

Closed
dborovcanin opened this issue Oct 11, 2019 · 2 comments · Fixed by #360
Closed

MQTT client should wait for PUBLISH before sending PUBREC #359

dborovcanin opened this issue Oct 11, 2019 · 2 comments · Fixed by #360

Comments

@dborovcanin
Copy link
Contributor

Here is the snippet:

package main

import (
	"flag"
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	mqtt "github.com/eclipse/paho.mqtt.golang"
)

const server = "tcp://localhost:1883"

const username = "36e1f808-ec19-43fd-9068-710c2dc8c597"
const password = "36f72eb5-4f13-4a87-83d4-bd60c2551529"
const clientID = "test"
const topic = "channels/3b04078c-5217-4bed-9334-9fca6a142b1f/messages/request"

func main() {
	off := flag.Bool("off", true, "Exit on message received.")
	flag.Parse()
	opts := mqtt.NewClientOptions().AddBroker(server)
	opts.SetUsername(username)
	opts.SetPassword(password)
	opts.SetClientID(clientID)
	opts.SetAutoReconnect(false)
	opts.SetMaxReconnectInterval(time.Second * 55)
	opts.SetCleanSession(false)
	opts.SetProtocolVersion(4)
	opts.SetStore(mqtt.NewFileStore("./store"))
	mc := mqtt.NewClient(opts)
	token := mc.Connect()
	token.Wait()
	if token.Error() != nil {
		fmt.Printf("UH OH %s", token.Error())
		return
	}
	mc.Subscribe(topic, 2, makeHandler(*off))
	fmt.Printf("subscribed to %s", topic)
	errs := make(chan error, 2)
	go func() {
		c := make(chan os.Signal)
		signal.Notify(c, syscall.SIGINT)
		errs <- fmt.Errorf("%s", <-c)
	}()
	err := <-errs
	fmt.Printf("terminated %s", err)
}

func makeHandler(off bool) func(client mqtt.Client, msg mqtt.Message) {
	return func(client mqtt.Client, msg mqtt.Message) {
		fmt.Println("received msg", string(msg.Payload()))
		if off {
			os.Exit(1)
		}
	}
}

Running it with the off flag set to false (the flag is here just for convenience, you can simply comment os.Exit(1)) means that the client will exit after PUBLISH receive, but before PUBREC. Once the client is restarted, it will continue where it stopped: sending PUBREC. Though this is not against the protocol specification (at least I could not find anything that confronts this behavior), according to the spec, the client should be waiting for the broker to loop back PUBLISH with DUP=1 in this scenario. It looks that something like removing *packets.PublishPacket from here will solve this issue. I'm willing to send a PR, but I didn't want to do it on my own, before opening this discussion.

@alsm
Copy link
Contributor

alsm commented Oct 23, 2019

Thanks for noticing this, while I don't think it should cause any issues it's better to be correct.

@alsm
Copy link
Contributor

alsm commented Oct 23, 2019

Read the linked issues, turns out it does cause issues, even more reason to be correct.

@alsm alsm closed this as completed in #360 Oct 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants