Closed dealproc closed 6 years ago
Hi I have the same question here, I setup the basics in the BuildWebHost and I specify a port there. But then I want to add certificates and custom callbacks and I can´t seam to figure out how to do that.
//Henrik
have a look at #402 you could copy that code as long as it is not merged.
I created a new OptionsBuilder that lets you access the service provider and resolve services as you desire:
services.AddHostedMqttServer(builder => builder
.WithDefaultEndpoint()
.WithDefaultEndpointPort(9876)
.WithConnectionValidator((ctx) =>
{
var mediator = builder.ServiceProvider.GetService<IMediator>();
if (await mediator.Send(new AuthenticateTerminalForMqttCommand(ctx.Username, ctx.Password)))
{
logger.LogInformation("Client {0} has connected.", ctx.ClientId);
ctx.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
return;
}
logger.LogInformation("Client {0} has failed to authenticate.", ctx.ClientId);
ctx.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
})
);
That's pretty much what I wound up with. I now need to go through the bowels of the wire-up and see if its going to be possible or not to build an orleans backplane for this, so that we can host this within a web farm environment. I know others have advised against this, but I'm trying to keep our stack as compact as possible until we hit a critical mass.
Hi again
I must be stupid but I can´t get this to work with your changes. In my Program.cs file I have this: `private static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseKestrel(o => { o.ListenAnyIP(1883, l => l.UseMqtt()); o.ListenAnyIP(5000);
})
.UseStartup<Startup>().Build();`
And then in Startup.cs I implemented your changes after copying the new changes into my local MQTTnet project.
`public void ConfigureServices(IServiceCollection services) { services.AddHostedMqttServer(builder => builder .WithDefaultEndpoint() .WithDefaultEndpointPort(2222) );
//this adds tcp server support based on Microsoft.AspNetCore.Connections.Abstractions
services.AddMqttConnectionHandler();
//this adds websocket support
services.AddMqttWebSocketServerAdapter();
}`
But the server still starts up on only 1883.
Why are you asking it to do port 1833 and port 2222???
He he I realize that looks a bit strange.
What I actually want to do is this:
.WithConnectionBacklog(100) .WithConnectionValidator(ConnectionValidator) .WithSubscriptionInterceptor(SubscriptionValidator) .WithEncryptionCertificate(mainSubCert.Export(X509ContentType.SerializedCert)) .WithEncryptedEndpointPort(9000) .WithEncryptedEndpoint() .WithDefaultEndpointPort(0);
Has anybody managed to get a asp.net core broker started with certificates using this code. I just can´t figure out how it is done.. It keeps just starting a unencrypted broker with the port specified in my BuildWebHost method.
If that's your pain point, maybe use something like Nginx on the front-end and then go between nginx and your service endpoint un-encrypted? Just a thought (and how we are presently configured)
I just can´t let this go.. Asp.NET Core refuses to start an encrypted endpoint for me. I am using the develop branch with the new ServiceCollectionExtensions.cs by JanEggers
Program.cs looks like this:
public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); }
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel(o =>
{
o.ListenAnyIP(9010, l => l.UseMqtt()); // mqtt pipeline
o.ListenAnyIP(5000); // default http pipeline
})
.UseStartup<Startup>();`
Startup.cs looks like this:
public void ConfigureServices(IServiceCollection services)
{
var rootFolder = Directory.GetCurrentDirectory();
rootFolder = rootFolder + "\device_test_com.pfx";
//2018 test certificate
var appCert = new X509Certificate2(File.ReadAllBytes(rootFolder), "password", X509KeyStorageFlags.Exportable);
var appSubCert = new X509Certificate2(appCert.Export(X509ContentType.Pfx));
services.AddHostedMqttServer(builder => builder
.WithEncryptionCertificate(appSubCert.Export(X509ContentType.SerializedCert))
.WithEncryptedEndpointPort(9010)
.WithEncryptedEndpoint()
.WithConnectionValidator(Value)
.WithoutDefaultEndpoint()
);
services.AddMqttConnectionHandler();
services.AddMqttWebSocketServerAdapter();
}
`
The server starts but it refuses connections with TLS on port 9010, unencrypted clients can connect though on port 9010 for some reason.
Maybe use an nginx proxy with a tcp stream configuration? that's how I'm configured as of today.
I would love that config, but I can´t make it myself. If you would be willing to help me send me an email to henrik@hostserver.nu If not, that is totally OK as well. :-) //Henrik
the problem is that the new pipeline does not yet support encrypted communication. (there is no tls connection middleware yet and using sslstream negates all the performance benefits)
so you should remove
o.ListenAnyIP(9010, l => l.UseMqtt()); // mqtt pipeline
services.AddMqttConnectionHandler();
and instead add the old tcp server adapter with
services.AddMqttTcpServerAdapter();
Thanks you soo much JanEggers!!
That solved the problem, it was driving me crazy. It works perfect now.
this is merged and aviable in 2.8.3.
Considering this code:
We cannot pull anything into
ConfigureServices()
but theIServiceCollection
object. So, with asp.net core 2.1, how do we provide a connection validator, among other items? When I look at the mainConfigure()
method, although we can doapp.UseMqttServer((mqttServer) => { ... custom code here ... });
, it does not seem to let us assign a custom connection validator, as the property is marked as ReadOnly at this point.Any suggestions/ideas for how to overcome this want/need would be great.