public void ConfigureMqttServerOptions(AspNetMqttServerOptionsBuilder options)
 {
     mqttConnectionService.ConfigureMqttServerOptions(options);
     mqttSubscriptionService.ConfigureMqttServerOptions(options);
     mqttPublishingService.ConfigureMqttServerOptions(options);
     options.WithoutDefaultEndpoint();
 }
Exemple #2
0
 /// <summary>
 ///     Builds the MQTT Server options
 /// </summary>
 /// <param name="options">AspNetMqttServerOptionsBuilder</param>
 public void ConfigureMqttServerOptions(AspNetMqttServerOptionsBuilder options)
 {
     options
     .WithConnectionValidator(this)
     .WithApplicationMessageInterceptor(this)
     .WithSubscriptionInterceptor(this)
     .WithClientId("localhost")
     .WithStorage(new RetainedMessageHandler());
 }
        public static AspNetMqttServerOptionsBuilder WithAttributeRouting(this AspNetMqttServerOptionsBuilder options)
        {
            var router      = options.ServiceProvider.GetRequiredService <MqttRouter>();
            var interceptor = new MqttServerApplicationMessageInterceptorDelegate(context => router.OnIncomingApplicationMessage(options, context));

            options.WithApplicationMessageInterceptor(interceptor);

            return(options);
        }
        public static IServiceCollection AddHostedMqttServerWithServices(this IServiceCollection services, Action<AspNetMqttServerOptionsBuilder> configure)
        {
            services.AddSingleton<IMqttServerOptions>(s =>
            {
                var builder = new AspNetMqttServerOptionsBuilder(s);
                configure(builder);
                return builder.Build();
            });

            services.AddHostedMqttServer();

            return services;
        }
 public void ConfigureMqttServerOptions(AspNetMqttServerOptionsBuilder options)
 {
     options.WithConnectionValidator(this);
 }
Exemple #6
0
 public void ConfigureMqttServerOptions(AspNetMqttServerOptionsBuilder options)
 {
     options.WithApplicationMessageInterceptor(this);
 }
 public void ConfigureMqttServerOptions(AspNetMqttServerOptionsBuilder options)
 {
     options.WithSubscriptionInterceptor(this);
     options.WithUnsubscriptionInterceptor(this);
 }
        internal async Task OnIncomingApplicationMessage(AspNetMqttServerOptionsBuilder options, MqttApplicationMessageInterceptorContext context)
        {
            // Don't process messages sent from the server itself. This avoids footguns like a server failing to publish
            // a message because a route isn't found on a controller.
            if (context.ClientId == null)
            {
                return;
            }

            var routeContext = new MqttRouteContext(context.ApplicationMessage.Topic);

            routeTable.Route(routeContext);

            if (routeContext.Handler == null)
            {
                // Route not found
                logger.LogDebug($"Rejecting message publish because '{context.ApplicationMessage.Topic}' did not match any known routes.");

                context.AcceptPublish = false;
            }
            else
            {
                using (var scope = options.ServiceProvider.CreateScope())
                {
                    Type?declaringType = routeContext.Handler.DeclaringType;

                    if (declaringType == null)
                    {
                        throw new InvalidOperationException($"{routeContext.Handler} must have a declaring type.");
                    }

                    var classInstance = typeActivator.CreateInstance <object>(scope.ServiceProvider, declaringType);

                    // Potential perf improvement is to cache this reflection work in the future.
                    var activateProperties = declaringType.GetRuntimeProperties()
                                             .Where((property) =>
                    {
                        return
                        (property.IsDefined(typeof(MqttControllerContextAttribute)) &&
                         property.GetIndexParameters().Length == 0 &&
                         property.SetMethod != null &&
                         !property.SetMethod.IsStatic);
                    })
                                             .ToArray();

                    if (activateProperties.Length == 0)
                    {
                        logger.LogDebug($"MqttController '{declaringType.FullName}' does not have a property that can accept a controller context.  You may want to add a [{nameof(MqttControllerContextAttribute)}] to a pubilc property.");
                    }

                    var controllerContext = new MqttControllerContext()
                    {
                        MqttContext = context,
                        MqttServer  = scope.ServiceProvider.GetRequiredService <IMqttServer>()
                    };

                    for (int i = 0; i < activateProperties.Length; i++)
                    {
                        PropertyInfo property = activateProperties[i];
                        property.SetValue(classInstance, controllerContext);
                    }

                    ParameterInfo[] parameters = routeContext.Handler.GetParameters();

                    context.AcceptPublish = true;

                    if (parameters.Length == 0)
                    {
                        await HandlerInvoker(routeContext.Handler, classInstance, null).ConfigureAwait(false);
                    }
                    else
                    {
                        object?[] paramArray;

                        try
                        {
                            paramArray = parameters.Select(p => MatchParameterOrThrow(p, routeContext.Parameters)).ToArray();

                            await HandlerInvoker(routeContext.Handler, classInstance, paramArray).ConfigureAwait(false);
                        }
                        catch (ArgumentException ex)
                        {
                            logger.LogError(ex, $"Unable to match route parameters to all arguments. See inner exception for details.");

                            context.AcceptPublish = false;
                        }
                        catch (TargetInvocationException ex)
                        {
                            logger.LogError(ex.InnerException, $"Unhandled MQTT action exception. See inner exception for details.");

                            // This is an unandled exception from the invoked action
                            context.AcceptPublish = false;
                        }
                        catch (Exception ex)
                        {
                            logger.LogError(ex, "Unable to invoke Mqtt Action.  See inner exception for details.");

                            context.AcceptPublish = false;
                        }
                    }
                }
            }
        }