无法从运行在 Windows 服务中的 .Net 客户端连接到 Mqtt Broker

问题描述 投票:0回答:0

我在 C# 中创建了一个Mqtt.NetWindows 服务,使用Framework 4.6.1.

我本地 Win 10 机器上的服务运行完美,向/从 EMQX Broker 发布/订阅消息。 然而,一旦我将我的 x64 发布版本部署到另一个盒子,就不再有与 Broker 的连接。 我记录了很多调试消息,但没有错误。

这是 EMQX Monitor UI 与我的 3 个客户端连接(我的本地 WinSvc、一个 TS 浏览器连接和 EMQX 云测试客户端)的样子:

我正在使用此 .Net 代码作为我的 Win 服务代码(框架 4.6.1)的指南

https://github.com/emqx/MQTT-Client-Examples/blob/master/mqtt-client-Csharp-MqttNet/mqtt-client-Csharp-MqttNet/Program.cs

我所有的参数都来自我项目的 app.config 文件

<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;
    }

mqtt mqttnet emqx
© www.soinside.com 2019 - 2024. All rights reserved.