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

Add Topic Router #132

Open
burner- opened this issue Nov 2, 2018 · 5 comments
Open

Add Topic Router #132

burner- opened this issue Nov 2, 2018 · 5 comments

Comments

@burner-
Copy link

burner- commented Nov 2, 2018

Currently there is only onMessage(messageReceived) callback. It would be nice that user can make routed subscribes that way:
client.subscribe("/hello", myHelloHandler); and that mqtt client lib will automatically route all /hello messages to that myHelloHandler. To save memory it would be even better if library supports wildcards so user can do:
client.subscribe("/hello/%", myHelloHandler);
or
client.subscribe("/hello/%/byebye", myHelloHandler);
and that will cause that it will get routed to myHelloHandler(int handlerid, String message)

@Urs-Eppenberger
Copy link

I support this idea. It would make for cleaner, better readably and maintainable code, at least in my case.

I have a code for devices which subscribe to two topics, one for commands and one for measurement values from other sensors. In the callback routine, I currently need to check first the topic and then decide what action to take based on the topic. With the above feature, I can split the code in two callback routines, with clearly dedicated tasks.

I'm not very fond of the wildcard idea, though. The library is used primarily in small devices, where the need for wildcarding is rare. But I can see the one or the other use case for this too.

@256dpi
Copy link
Owner

256dpi commented Dec 19, 2018

Thank you all for your comments. I thought about this feature myself a couple of times. However, I think that it unnecessarily complicates the code with little benefit for most users. All my Arduino+MQTT projects involved less than 15 topics, which was easy to handle with a if {} else if {} else {} statements. The most memory efficient and performant way is to let the user choose the best way to handle the topic checks.

The only thing I see as a possibility would be to implement an additional router class that could be used to handle such cases. To do that properly we first nee to implement a Trie in lwmqtt that is similar to what I implemented in gomqtt: https://godoc.org/github.com/256dpi/gomqtt/topic#Tree. This structure can then be used to implement the router efficiently. But again, what are the real use cases?

@256dpi 256dpi changed the title feature request Add Topic Router Feb 8, 2019
@abcd-ca
Copy link

abcd-ca commented Jun 8, 2019

@256dpi what is your strategy when trying to parse which topic it is within your if/elseif/else when the topic has a wildcard like foo/+/bar? You can't just use String.equals() because the topic foo/123/bar obviously won't match foo/+/bar. Do you use a regex lib?

@256dpi
Copy link
Owner

256dpi commented Jun 9, 2019

You can use s.startsWith("foo/") to match the beginning, then use s.indexOf("/", 4) to get the offset of the next "/", then get the segment in the middle using s.substring(4, offset) and use the same approach to get the end of the string using s.substring(offset+1).

@abcd-ca
Copy link

abcd-ca commented Jun 10, 2019

@256dpi good call, thanks. Just to add to the router idea for anyone picking up this thread, the one onMessage handler can get pretty big – I have been doing the minimum if/elseif/else and then calling other functions in my file to handle each (kind of like a router but more basic) which keeps the code more manageable to read and maintain. Router could be a cool optional plugin-in project to this one for very complex needs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants