Code Monkey home page Code Monkey logo

Comments (6)

ChristianRiedl avatar ChristianRiedl commented on May 14, 2024 1

@chkr1011 : Great, I allready added a handler (= simple callback for topics) and RPC experimental feature for my needs. Every topic level is processed by a dispatcher. Maybe you can use some ideas of my MqttLib.

MqttLib.zip

Server side sample (registration of RPC stubs) :

var rootDispatcher = new MqttDispatcher("smarthome");
mqttServer.ApplicationMessageReceived += rootDispatcher.OnMessageReceived;
rootDispatcher.AddHandler("command", async(frag, msg) => {
          string value = Encoding.UTF8.GetString(msg.Payload);
          return await devices.Command(frag[2], frag[3], frag[4], value);
}, MqttQualityOfServiceLevel.AtLeastOnce);

var rpcDispatcher = new MqttRpcDispatcher(mqttServer, "rpcrequest", new MqttRpcJsonSerializer(), logger);
rootDispatcher.AddDispatcher(rpcDispatcher);
rpcDispatcher.AddFunction<SensorCommand,bool>("testfunc", TestFunc);
rpcDispatcher.AddFunction<SensorCommand,bool>("command", async(cmd) => {
          return await devices.Command(cmd.DeviceName, cmd.SensorName, cmd.Name, cmd.Value);
          });
rpcDispatcher.AddFunction<string, string>("ping", (cmd) => { return Task.FromResult(cmd); });

static Task<bool> TestFunc (SensorCommand cmd)
        {
            return Task.FromResult(true);
        }

Client side sample :

_mqttClient = new MqttClient(new MqttClientAdapterFactory(), new MqttLoggerEx(logger));
_rootDispatcher = new MqttClientDispatcher("smarthome");
_mqttClient.ApplicationMessageReceived += _rootDispatcher.OnMessageReceived;
_rootDispatcher.AddHandler("sensortype", ProcessSensorType);
_rootDispatcher.AddHandler("sensor", ProcessSensor, subscribeAllSensors ? 
        MqttQualityOfServiceLevel.AtLeastOnce : (MqttQualityOfServiceLevel?)null);
_rootDispatcher.AddHandler("event", ProcessEvent, MqttQualityOfServiceLevel.AtLeastOnce);
_mqttRpc = new MqttClientRpc(_mqttClient, "rpcreply",null,  _serializer, 
        MqttQualityOfServiceLevel.AtLeastOnce, _logger);
_rootDispatcher.AddDispatcher(_mqttRpc);

public async Task<bool> Command<T>(string deviceName, string sensorName, string name, T value)
        {
            SensorCommand cmd = new SensorCommand { DeviceName = deviceName, SensorName = sensorName, Name = name, Value = value.ToString() };
            bool rc = await _mqttRpc.Call<bool, SensorCommand>("command", cmd);
            return rc;
        }
public async Task<string> Ping()
        {
            string str = await _mqttRpc.Call<string, string>("ping", "1234");
            return str;
        }


from mqttnet.

JanEggers avatar JanEggers commented on May 14, 2024

im using a dictionary with int to taskCompletionSource similar to the MqttPacketDispatcher so i can send request with an id and wait for the response with the same id. that way i get call semantic.

By the way what is the essential difference between SignalR and the MQTT AspNet Core integration ?

signalr uses websockets or some other transport, a HubProtocol and Groups to filter who receives what. im planning to do a lib that glues this library and signalr together once signalr leaves alpha. im not yet shure how to emulate hubprotocol. im thinking of either send all messages to one hub or dispatch them according to their topic. for me the main advantage of signalr is it provides a more fleshed out programming model and scaleout, here we just have an eventhandler

from mqttnet.

chkr1011 avatar chkr1011 commented on May 14, 2024

I had also such an idea. Also creating a standalone MQTT server based on this library running in Windows IoT Core or on a PC. Like a product and also available at the store. My idea was to make the config all via MQTT messages. So that the server will have one admin credential with default values and then you can use messages for writing configuration etc. But finally I had one security flaw because everyone can subscribe to the RPC-Response-Messages and also the RPC-Request messages and thus sniff these messages. Does someone of you have an idea to fix this? One idea is to deny subscriptions to those message types if the client is not a client which uses the Admin credentials.

from mqttnet.

JanEggers avatar JanEggers commented on May 14, 2024

deny subscribe based on credentials and only allow with tls is all you can do i guess. mqtt isnt really build with security in mind anyone can subscribe and publish anything (with default mechanics)

from mqttnet.

chkr1011 avatar chkr1011 commented on May 14, 2024

As long as there is no progress I will close this ticket. I still have this on my plate but due to several open security flaws I would not implement it in this library and on a higher level instead.

from mqttnet.

chkr1011 avatar chkr1011 commented on May 14, 2024

I reopened this ticket because this topic is now relevant for me as well 😄
My idea is to add a new project (and also nuget) to this repository called "MQTTnet.Extensions" which contains some implementations like the storage for the server which is based on JSON etc. So that in a UWP app only 5 lines are required to start a fully featured MQTT server.

Another topic for this lib is the RPC feature. I usually use "PubSubClient" for my ESP8266 code so that the solution must be usable with that library as well. My ideas are as follows:

  1. The extension provides an async method like "ExecuteAsync" which takes a custom payload (byte[] at low level but overloads can use JSON.net for serialization of real classes for request and response).
  2. When called, the extension will create a topic like "$RPC/[clientId]/[custom method name/[guid]" which can be subscribed from the client like "$RPC/[clientId]/#".
  3. The server already allows denying of subscriptions. This means that the server will only allow subscribing to "own" RPC topics (ClientId is in topic).
  4. Same for the response. Nobody can subscribe to a response topic.
  5. The client will read everything from the payload and perform an operation. Then the client will send the reply with the exact same topic to the server.
  6. The server only accepts the response from the same client (truncated if different one).
  7. Like the PacketAwaiter a waiting TaskCompletionSource will be set (identified by the guid in the topic) with the response.
  8. Timeouts etc. can be specified for the TaskCompletionSource.
  9. No changes for MQTTnet core are required because the extension only uses already available features.

@ChristianRiedl What do you think?

from mqttnet.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.