vertx-mqtt icon indicating copy to clipboard operation
vertx-mqtt copied to clipboard

Vert.X MQTT Router

Open alexgtn opened this issue 7 years ago • 12 comments

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.

alexgtn avatar Sep 05 '17 10:09 alexgtn

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 avatar Sep 05 '17 11:09 ppatierno

@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?

alexgtn avatar Sep 05 '17 11:09 alexgtn

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")

ppatierno avatar Sep 05 '17 12:09 ppatierno

@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

vietj avatar Sep 05 '17 13:09 vietj

@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"

alexgtn avatar Sep 05 '17 13:09 alexgtn

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 avatar Sep 05 '17 13:09 ppatierno

@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

alexgtn avatar Sep 05 '17 13:09 alexgtn

@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.

alexgtn avatar Sep 06 '17 07:09 alexgtn

@AGutan that's something we need to discuss with @pmlopes and see how best we can address this

vietj avatar Sep 06 '17 07:09 vietj

@vietj @pmlopes any updates on this?

alexgtn avatar Sep 06 '17 13:09 alexgtn

Ping from 2019

vaIgarashi avatar Jan 17 '19 08:01 vaIgarashi

@vagola unfortunately there is no progress on this issue yet

vietj avatar Jan 17 '19 14:01 vietj