Closed tobi4321 closed 4 years ago
This is how I usually set it up. You can do all your connection-level stuff in MqttService and your message handling in controllers (using AttributeRouting).
In Startup.cs:
// Add MQTT Server
services.AddMqttControllers();
services.AddSingleton<MqttService>((container) =>
{
var logger = container.GetRequiredService<ILogger<MqttService>>();
return new MqttService() { Logger = logger };
});
services
.AddHostedMqttServerWithServices(mqttServer =>
{
mqttServer.WithoutDefaultEndpoint();
mqttServer.WithAttributeRouting();
var mqttService = mqttServer.ServiceProvider.GetRequiredService<MqttService>();
mqttService.ConfigureMqttServerOptions(mqttServer);
})
.AddMqttConnectionHandler()
.AddConnections();
MqttService.cs
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using MQTTnet.Server;
namespace Api.Service
{
public class MqttService : IMqttServerClientConnectedHandler,
IMqttServerClientDisconnectedHandler,
IMqttServerConnectionValidator,
IMqttServerStartedHandler
{
private IMqttServer Server;
public ILogger<MqttService> Logger { get; set; }
public void ConfigureMqttServerOptions(MqttServerOptionsBuilder options)
{
options.WithConnectionValidator(this);
}
public void ConfigureMqttServer(IMqttServer mqtt)
{
this.Server = mqtt;
mqtt.ClientConnectedHandler = this;
mqtt.ClientDisconnectedHandler = this;
}
public Task HandleClientConnectedAsync(MqttServerClientConnectedEventArgs eventArgs)
{
return Task.CompletedTask;
}
public Task HandleClientDisconnectedAsync(MqttServerClientDisconnectedEventArgs eventArgs)
{
return Task.CompletedTask;
}
public Task HandleServerStartedAsync(EventArgs eventArgs)
{
return Task.CompletedTask;
}
/// <summary>
/// Validate protocol and security context prior to allowing the connection to proceed
/// </summary>
public Task ValidateConnectionAsync(MqttConnectionValidatorContext context)
{
Logger.LogInformation($"Opening connection [Secure={context.IsSecureConnection}]");
#if !DEBUG
if (!context.IsSecureConnection)
{
context.ReasonCode = MqttConnectReasonCode.ProtocolError;
context.ReasonString = "Only secure WSS connections are allowed.";
}
#endif
return Task.CompletedTask;
}
}
}
Thank you for this solution. Does it also work for non wss mode? The hardware im using does not support websockets... my hardware connects for example to my application with ip (later url) and port 1883. The topics are /clientId/hardwarePart/. The clientId is a generated Id by the application to have a connection between user and hardware clients.
The AttributeRouting is only supported for .Net Core 3.1+, how can I use it for older versions?
AspNetCore only supports WS and WSS. This library could be used without AspNetCore, but there are some caveats. This library has a dependency on AspNetCore which has a dependency on .NET Core 3.1 so you will need to reference AspNetCore and have your project on .NET Core 3.1 to use it.
The reason for the dependency is that I'm using the controller activator from AspNetCore to avoid some of the trickier code. It would be some significant effort to remove this dependency, but it could be done. In the meantime, I suggest that this library probably isn't a great fit for your specific use case.
PRs are always welcome if you would like to attempt the above.
This issue has not had any recent activity. It will be automatically closed in 7 days if no further activity occurs. Thank you for your contributions.
Is there a way to use your Code in combination with standard mqtt connections? I have a working mqttnet Server running in the startup class of a ASP.Net Core 2.1 solution. I can do a lot of stuff with the incoming data but only in the startup class... if i use your classes, can i use attribute routing with normal mqtt connection in the asp.net core 2.1 project or do you have another solution to outsource the server logic from the startup class?