vertx-mqtt
vertx-mqtt copied to clipboard
Vert.X MQTT Router
What is your opinion on adding a Router for handling MQTT messages from clients?
Something very similar to the Vert.X Web Router.
Potential usage:
MqttServer mqttServer = MqttServer.create(vertx, options);
MqttEndpoint mqttEndpoint;
Router router = Router.router(vertx);
mqttServer.endpointHandler(endpoint -> {
endpoint
.publishHandler(router::accept)
.publishReleaseHandler(endpoint::publishComplete);
mqttEndpoint = endpoint;
endpoint.accept(true);
}).listen( ... );
Route tempsGroup1 = router.route().path("/groupOne/temperatureSensor/:deviceId");
Route lightGroup2 = router.route().path("/groupTwo/lightSensor/:deviceId");
tempsGroup1.handler(routingContext -> {
String deviceId = routingContext.message().getParam("deviceId");
Buffer payload = routingContext.message().payload();
// handle temperature data
if (routingContext.message.qosLevel() == MqttQoS.AT_LEAST_ONCE) {
mqttEndpoint.publishAcknowledge(routingContext.message.messageId());
} else if (routingContext.message.qosLevel() == MqttQoS.EXACTLY_ONCE) {
mqttEndpoint.publishRelease(routingContext.message.messageId());
}
});
I think it will add a ton of convenience instead of manually handling every published message.
My use case requires an API, but I prefer MQTT instead of HTTP since it is IoT based.
I really think that it's a cool idea !
What I'm concerned on your example is the "non" standard way to have parameters on the MQTT topic (i.e. :deviceId). It's not something defined by the MQTT spec and I'd like to have the component more MQTT compliant. It means that the only thing that a routingContext
could expose should be the underlying MQTT message.
Do you think to work on a proposal for that with a PR ? :-)
@ppatierno sure. My project kind of requires this functionality anyway, so I'll work on that and submit a pr. Also, what about wildcards? As descibed here. I'm particularly interested in single-level "+" wildcards and to be able to get the value of the single-level wildcard in the handler. What do you think?
Good to know, waiting for your PR ! :) Regarding the wildcard feature can you give me an example of what you need ? Remember that wildcard works only on the subscription side and not on publishing side. Only a subscriber can specify a topic like "foo/+/bar" or "/foo/#" but a publisher can publish only to a well defined topic i.e. "foo/a/bar" (and not to "foo/+/bar")
@pmlopes as we do have a new implementation of router for vertx-web wouldn't it make sense to share common bits with this forthcoming router ? i.e have a component like vertx-uri-router
@ppatierno yes the client will publish to a well defined topic.
suppose the route definition is like this:
Route fooBarRoute = router.route().path("foo/+/bar");
and a client publishes a message on the topic "foo/whatever/bar"
I want to get the value of the + in a variable. In the above case the value of the wildcard is "whatever".
But if the route is
Route fooBarRoute = router.route().path("foo/+/+/bar");
I want to be able to identify the 2 wildcards.
That is why I initially suggested
Route fooBarRoute = router.route().path("foo/:param1/:param2/bar");
This way we can identify between both parameters. If the client publishes a message to the topic "foo/x/y/bar" I can get the x,y values like this:
String x = routingContext.message().getParam("param1"); // "x"
String x = routingContext.message().getParam("param2"); // "y"
As I said I don't agree on having a non standard MQTT support for this feature. The ":param1" syntax isn't defined by the MQTT standard and I'd like to have the component to be compliant with the specification. From the routingContext you will have the published topic isn't it enough for you for getting the value of "x" and "y" ? I know that it could be simpler with your idea but it's not something standard.
@ppatierno ok let's follow the standards. Then I'll implement the wildcards like this
Route fooBarRoute = router.route().path("foo/+/bar");
and if there is need to get the value of the wildcard, one will need to split the topic name
@vietj could you make a separate package for the router files from the vertx-web? A common router package that will be used in vertx-web and vertx-mqtt. I think I've done the most part of the MQTT Router, but I've added the entire vertx-web to my vertx-mqtt. I'll update the new router package with the changes I made.
@AGutan that's something we need to discuss with @pmlopes and see how best we can address this
@vietj @pmlopes any updates on this?
Ping from 2019
@vagola unfortunately there is no progress on this issue yet