XSockets / MQTT

A MQTT plugin for XSockets based on Paolo Patiernos GnatMQ
Eclipse Public License 1.0
2 stars 2 forks source link

xSockets MQTT Plugin without Putty #1

Open AngeloBestetti opened 8 years ago

AngeloBestetti commented 8 years ago

Hi All,

When you´re using MQTT FX as client connected to xSockets Server with MQTT Plugin and you try to publish any message and you have another MQTT FX as Subscriber everything works fine, but the OnMessage Event on the controller is not fireing, just fire when you use Putty as Publisher.

Why MQTT Plugin is not raising the event?

uffebjorklund commented 8 years ago

Hi Angelo Can you please provide some sample code for how you do this so that we can take a look? Nothing advanced is needed, just a screen-dump showing putty and MQTT FX will be fine.

AngeloBestetti commented 8 years ago

mqttconfig.cs public class MqttConfig : ConfigurationSetting { public MqttConfig() : base(string.Format("ws://{0}:1883", "localhost")) { } }

program.cs class Program { static void Main(string[] args) { using (var container = Composable.GetExport()) { container.Start(); Console.ReadLine(); } } }

foo.cs public class Foo : XSocketController {
public void Bar(IMessage message) { //Send to all clients MQTT excluded this.InvokeToAll(message); //Send to all MQTT clients, still just a POC, so it is kind of hacky foreach (var c in this.FindOn()) { c.MqttClient.Publish(message.Topic,Encoding.UTF8.GetBytes(message.Data)); }
} }

When using just MQTT Clients never get into the "Bar"

AngeloBestetti commented 8 years ago

I just did another test with the IXSocketAuthenticationPipeline, same thing when using with Putty works like a charm, but when MQTT Client connects never gets into the pipeline.

I think there is something missing in mqtt plugin.

uffebjorklund commented 8 years ago

This is because we use the GnatMQ implementation of MQTT. MQTT is great, but does not allow (by default) for server side logic. It is just a broker that handles every incoming message according to the MQTT protocol. In XSockets we can send messages to MQTT clients from other client, but the MQTT clients can only talk to a single controller (the https://github.com/XSockets/MQTT/blob/master/src/XSockets.Protocol.Mqtt/Modules/Controller/MqttManager.cs).

It would not take much to route MQTT messages into another controller, but since this is based on custom logic you have to implement that your self for now.

We plan to remove the GnatMQ implementation and instead allow a MQTT protocol (like today) where you implement a message router to decide where each MQTT message would go and then let XSockets Quality Of Service handle the MQTT logic.

If you are using pure MQTT and no other clients I recomd you to use GnatMQ instead of XSockets. If you mix MQTT with other clients you can make it work with XSockets.

AngeloBestetti commented 8 years ago

That´s good, that´s bad, do you have a milestone to do that? Yes I´m willing to mix clients such this scenario bellow:

Customer A: Using MQTT Client on IoT Device publishing messages Customer B: Using web app .net with a console (ws and angular/knockout) "monitoring" what Customer A is publishing Customer C: Using MQTT Client on ERP Subscribing what Customer A is publishing.

xSockets is perfect for what we need, we just need instead of PuttyProtocol make it work with MQTT protocol.

uffebjorklund commented 8 years ago

Ok, will take a look and see if we can find a quick fix for this scenario. Give me 24 hours.

AngeloBestetti commented 8 years ago

Sure. Thank you

uffebjorklund commented 8 years ago

FYI - XSockets 5.0.3 will support QoS and Retain flags as well as CleanSession like MQTT, but the client is not MQTT FX but instead the regular C# client of XSockets. It also supports wild card matching on subscriptions. Do not know if the C# client is an option for you or if you want to use the real MQTT protocol.

Just wanted to let you know...

AngeloBestetti commented 8 years ago

Can be another option but I still need MQTT compliance with the protocol so generic MQTT clients can consume the service.

uffebjorklund commented 8 years ago

Ok, so I have way to communicate between MQTT clients and other XSockets clients. The thing is that MQTT is just a message broker where you do not write server-side code. XSockets on the other hand is very much about writing logic in server-side controllers. So... To be able to pass a MQTT message to XSockets clients we have to make sure that the MQTT message arrives at a specific MQTT message handler. Then we can send that message to other XSockets clients.

To make this work I added a method on the MqttManager so that we can regiter a XSockets controller that will handle all the MQTT messages.

public static void RegisterMqttController<T>() where T : class, IXSocketController

So, before starting the XSockets server you can create a custom controller. For example like this

public class MqttMessageBroker : XSocketController
{
    /// <summary>
    /// Messages that do ´not match any other method will end up here
    /// </summary>
    /// <param name="m"></param>
    /// <returns></returns>

    public override async Task OnMessage(IMessage m)
    {
        await this.PublishToAll(m);
    }

    /// <summary>
    /// Specific for handling topic Foo 
    /// </summary>
    /// <param name="m"></param>
    /// <returns></returns>
    public async Task Foo(IMessage m)
    {  
        //Do stuff...

        //Publish to subscribers         
        await this.PublishToAll(m);
    }        
}

And register this controller to be used when MQTT clients send messages

XSockets.Protocol.Mqtt.Modules.Controller.MqttManager.RegisterMqttController<MqttMessageBroker>();

If this looks like a ok workaround we will publish this a.s.a.p

Note that the Authenticaiton pipeline will not be hit by MQTT client since it is a another process running GNATMQ. So if you want to authenticate MQTT clients that have to be done the GNATMQ way.

The goal is of course to implement a good MQTT module that is completely XSockets so that things like this wont be needed. But for now this is what we got.

AngeloBestetti commented 8 years ago

Hi Uffe,

Thank you for your efforts to make this work, for now this workaround can fit some of our needs, but it´s far from what we need, I will need xSockets to authenticate the clients.

Imagine this situation, a Client A (IoT Device MQTT Standard) it will connect to xSockets with credentials, xSockets needs to understand MQTT Connection and on the "Event" we will validate that device "Allow" or "Denied" to publish telemetry.

I Could have another Customer "B" such as ERP subscribing the topic on xSockets to receive the telemetry.

This is why we need to autheticate the mqtt clients.

Let me motivate you LOL, Do you have any idea of budget for that?

uffebjorklund commented 8 years ago

Hi, yes I understand that this is what you need. IMHO the correct/best way to go for is to remove GnatMQ and implement MQTT in XSockets. Will think about how to do this. Hopefully it can be done in a smooth and quick way.

Do you have a deadline? (probably yesterday ;) )

uffebjorklund commented 8 years ago

Might be able to get the auth pipeline to work with MQTT after all. Will try it out. Stay tuned :)

AngeloBestetti commented 8 years ago

Not Yesterday!!! yesterday before LOL, just kidding, Our deadline to this project is by end of April.

Of course we need to code everything before, so if you do that in about a month will be perfect. If you confirm that it´s possible I can buy a license right now, just to keep things going.

Also you can reach me at angelobestetti@gmail.com Google Hangout

Many thx