I have created a Mqtt.Net Windows Service in C#, using Framework 4.6.1.
The service on my local Win 10 box works perfectly, publishing/subscribing to messages to/from the EMQX Broker. However once I deploy my x64 release version to another box, there’s NO connection to the Broker any longer. I am logging lots of debug messages, but there are NO errors.
This is what the EMQX Monitor UI looks like with my 3 client connections (my local WinSvc, a TS browser conn, and the EMQX Cloud test client):
I'm using this .Net code as a guide for my Win Service code (Framework 4.6.1)
All of my params are coming from my project's app.config file
<add key="MqttBrokerAddress" value="THE-BROKER.emqxsl.com" />
<!--defaults are 1883(mqtt), 8083(ws) 8084(wss)-->
<add key="MqttPort" value="8084" />
<add key="MqttProtocol" value="wss" />
<add key="QualityOfService" value="0"/>
<!-- certificate required for TLS over wss (port value shuold be 8084)-->
<add key="UseTlsCertificate" value="true" />
<add key="CertificateFileName" value="MY-CERTIFICATE.pfx" />
<add key="CertificatePswd" value="......" />
public void CreateThreadAndRun()
{
Thread m_Thread = new Thread(new ThreadStart(StartPublisherAndSubscriber));
m_Thread.SetApartmentState(ApartmentState.STA);
m_Thread.Name = "MT";
m_Thread.Priority = ThreadPriority.Highest;
m_Thread.Start();
}
private void StartPublisherAndSubscriber()
{
StartSubscriber();
StartPublisher();
}
public async void StartPublisher()
{
var mqttFactory = new MqttFactory();
this.managedMqttClientPublisher = mqttFactory.CreateManagedMqttClient();
// If tls is enabled in app.config, we use wss with cert file
if (MqttUseTls)
{
var managedClientOptions = WsSecureClientOptions();
await this.managedMqttClientPublisher.StartAsync(managedClientOptions);
}
else
{
var insecureOptions = WsInsecureOptions();
await this.managedMqttClientPublisher.StartAsync(
new ManagedMqttClientOptions
{
ClientOptions = insecureOptions
});
}
applog.Debug($"In StartPublisher()");
Publish(defaultMessage + " - " + this.hostName, this.topicThisHost);
}
public ManagedMqttClientOptions WsSecureClientOptions()
{
string assemblyPath = Path.GetDirectoryName(Assembly.GetAssembly(typeof(MqttService)).CodeBase);
// Building out the secure wss url (both pfx/crt certificate file types appear to work here)
var url = $"{mqttBrokerAddress}:{mqttPort}/mqtt";
X509Certificate2 x509Cert = null;
var file = CertificateFileName;
var filePath = Path.Combine(assemblyPath, file).Remove(0, 6);
// pfx file contains both pub and priv keys (needs pswd); crt file only has pub key (no pswd req'd)
if (Path.GetExtension(CertificateFileName.ToLower()) == ".pfx") {
// using a PFX cert file via the X509 class
x509Cert = new X509Certificate2(filePath, CertificatePwd);
}
else if (Path.GetExtension(CertificateFileName.ToLower()) == ".crt")
{
x509Cert = new X509Certificate2(filePath);
}
//var caFile = "broker.emqx.io-ca.crt"; // PULLING FROM APP.CONFIG
//var certFilePath = Path.Combine(assemblyPath, caFile).Remove(0, 6);
var clientOptionsBldr = new MqttClientOptionsBuilder()
.WithWebSocketServer(url)
.WithCredentials(mqttClientUser, mqttClientPswd)
.WithClientId(clientId)
.WithCleanSession()
.WithCredentials(mqttClientUser, mqttClientPswd)
.WithTls(
new MqttClientOptionsBuilderTlsParameters()
{
UseTls = true,
SslProtocol = System.Security.Authentication.SslProtocols.Tls12,
Certificates = new List<X509Certificate2>() { x509Cert}
});
ManagedMqttClientOptions managedClientOptions = null;
try
{
applog.Debug($"In WsSecureClientOptions(), about to Build Publisher - ${url}");
managedClientOptions = new ManagedMqttClientOptionsBuilder()
.WithClientOptions(clientOptionsBldr)
.Build();
}
catch (Exception ex)
{
applog.Error("CERT ERROR ! Exception in WsSecureClientOptions() " + ex.Message);
}
return managedClientOptions;
}