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

Vert.X MQTT Router #55

Open
alexgtn opened this issue Sep 5, 2017 · 12 comments
Open

Vert.X MQTT Router #55

alexgtn opened this issue Sep 5, 2017 · 12 comments

Comments

@alexgtn
Copy link

alexgtn commented Sep 5, 2017

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.

@ppatierno
Copy link
Member

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 ? :-)

@alexgtn
Copy link
Author

alexgtn commented Sep 5, 2017

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

@ppatierno
Copy link
Member

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

@vietj
Copy link
Contributor

vietj commented Sep 5, 2017

@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

@alexgtn
Copy link
Author

alexgtn commented Sep 5, 2017

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

@ppatierno
Copy link
Member

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.

@alexgtn
Copy link
Author

alexgtn commented Sep 5, 2017

@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
Copy link
Author

alexgtn commented Sep 6, 2017

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

@vietj
Copy link
Contributor

vietj commented Sep 6, 2017

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

@alexgtn
Copy link
Author

alexgtn commented Sep 6, 2017

@vietj @pmlopes any updates on this?

@vaIgarashi
Copy link

Ping from 2019

@vietj
Copy link
Contributor

vietj commented Jan 17, 2019

@vagola unfortunately there is no progress on this issue yet

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

No branches or pull requests

4 participants