C# 无法连接到作为docker容器部署的MQTTNet服务器

C# 无法连接到作为docker容器部署的MQTTNet服务器,c#,docker,containers,connect,mqttnet,C#,Docker,Containers,Connect,Mqttnet,我有一个示例MQTTNet服务器,希望将其部署为docker容器。 下面是服务器代码,它是Net Core Web App(Net Core 2.2)的一部分,我将在命令行中手动构建并部署到Docker: 我使用的是NETCore2.2,MQTTNET3.0.8 “docker生成-t mqttwebservice。” “docker run-d-p 32780:80-p 1883:1883--名称myapp2 mqttwebservice” 部署成功。 但是,我无法连接到MQTT服务器(Mqt

我有一个示例MQTTNet服务器,希望将其部署为docker容器。 下面是服务器代码,它是Net Core Web App(Net Core 2.2)的一部分,我将在命令行中手动构建并部署到Docker:

我使用的是NETCore2.2,MQTTNET3.0.8

“docker生成-t mqttwebservice。” “docker run-d-p 32780:80-p 1883:1883--名称myapp2 mqttwebservice”

部署成功。 但是,我无法连接到MQTT服务器(MqttCommunicationTimedOutException)

1) 什么可以阻止mqtt客户机与服务器通信

2) 如何知道服务器是否已正确启动

DockerFile
名称空间MQTTWebService
{
使用制度;
Net系统;
使用System.Security.Authentication;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
使用Microsoft.Extensions.Hosting;
使用Microsoft.Extensions.Logging;
使用MQTTnet;
使用MQTTnet.Server;
公共类MQTTService:BackgroundService
{
专用静态ILogger mqttServiceLogger;
专用MQTTConfiguration MQTTConfiguration;
专用IMqttServerOptions mqttServerOptions;
专用IMqttServer mqttServer;
/// 
///TODO:在此处实现客户端连接验证程序
/// 
私有操作MQTTConnectionValidator=(c)=>
{
日志消息(mqttServiceLogger,c);
};
/// 
///建造师
/// 
/// 
公共MQTTService(ILogger记录器)
{
mqttServiceLogger=记录器;
this.mqttConfiguration=新的mqttConfiguration
{
BrokerHostName=“127.0.0.1”,
BrokerPort=1883,
MqttSslProtocol=SslProtocols.None,
usesl=false,
};
这个.BuildServerOptions();
这是CreateMqttServer();
}
公共覆盖异步任务StartAsync(CancellationToken CancellationToken)
{
等待此消息;
}
受保护的覆盖异步任务ExecuteAsync(CancellationToken stoppingToken)
{
同时(!stoppingToken.IsCancellationRequested)
{
mqttServiceLogger.LogInformation(“在:{time}运行的工作进程”,DateTimeOffset.Now);
等待任务。延迟(1000,停止待命);
}
}
私有void BuildServerOptions()
{
尝试
{
IPAddress IPAddress=IPAddress.Parse(this.mqttConfiguration.BrokerHostName);
MqttServerOptionsBuilder optionsBuilder=新MqttServerOptionsBuilder();
if(this.mqttConfiguration.usesll)
{
////TODO:实施插入认证
optionsBuilder.WithClientCertificate()
.使用EncryptionSSL协议(此.mqttConfiguration.MqttSslProtocol);
}
optionsBuilder.WithDefaultEndpointBoundIPAddress(ipAddress)
.WithDefaultEndpointPort(此.mqttConfiguration.BrokerPort)
.WithConnectionValidator(MQTTConnectionValidator)
.使用SubscriptionInterceptor(c=>
{
c、 AcceptSubscription=true;
日志消息(mqttServiceLogger,c,true);
})
.WithApplicationMessageInterceptor(c=>
{
c、 AcceptPublish=true;
日志消息(mqttServiceLogger,c);
});
this.mqttServerOptions=optionsBuilder.Build();
}
捕获(例外情况除外)
{
mqttServiceLogger.LogError(例如消息);
投掷;
}
}
私有void CreateMqttServer()
{
尝试
{
this.mqttServer=new MqttFactory().CreateMqttServer();
////为服务器添加处理程序
this.mqttServer.UseClientConnectedHandler(ClientConnectedHandler);
this.mqttServer.UseClientDisconnectedHandler(ClientDisconnectedHandler);
this.mqttServer.ClientSubscribedTopicHandler=新的mqttserverclientsubscribedhandler委托(args=>
{
尝试
{
字符串clientID=args.clientID;
TopicFilter TopicFilter=args.TopicFilter;
字符串topicString=ConvertTopicFilterToString(topicFilter);
mqttServiceLogger.LogInformation($“[{DateTime.Now}]客户端'{clientID}'订阅了{topicString}”);
}
捕获(例外情况除外)
{
mqttServiceLogger.LogError(例如消息);
}
});
this.mqttServer.ClientUnsubscribedTopicHandler=new mqttserverclientunsubscribedtopichandler委托(args=>
{
尝试
{
字符串clientID=args.clientID;
字符串topicFilter=args.topicFilter;
mqttServiceLogger.LogInformation($“[{DateTime.Now}]客户端'{clientID}'未订阅{topicFilter}.”);
}
捕获(例外情况除外)
{
mqttServiceLogger.LogError(例如消息);
}
});
}
捕获(例外情况除外)
{
mqttServiceLogger.LogError(例如消息);
投掷;
}
}
专用异步任务StartMqttServerAsync()
{
尝试
{
if(this.mqttServerOptions==null)
{
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 1883

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["MQTTWebService.csproj", "MQTTWebService/"]
RUN dotnet restore "MQTTWebService/MQTTWebService.csproj"
COPY . .
WORKDIR "/src/MQTTWebService"
COPY . .
RUN dotnet build "MQTTWebService.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "MQTTWebService.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MQTTWebService.dll"]
namespace MQTTWebService
{
    using System;
    using System.Net;
    using System.Security.Authentication;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Extensions.Hosting;
    using Microsoft.Extensions.Logging;
    using MQTTnet;
    using MQTTnet.Server;

    public class MQTTService : BackgroundService
    {
        private static ILogger<MQTTService> mqttServiceLogger;

        private MQTTConfiguration mqttConfiguration;

        private IMqttServerOptions mqttServerOptions;

        private IMqttServer mqttServer;


        /// <summary>
        /// TODO: Implement client connection validator here
        /// </summary>
        private Action<MqttConnectionValidatorContext> MQTTConnectionValidator = (c) =>
        {
            LogMessage(mqttServiceLogger, c);
        };



        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="logger"></param>
        public MQTTService(ILogger<MQTTService> logger)
        {
            mqttServiceLogger = logger;

            this.mqttConfiguration = new MQTTConfiguration
            {
                BrokerHostName = "127.0.0.1",
                BrokerPort = 1883,
                MqttSslProtocol = SslProtocols.None,
                UseSSL = false,
            };
            this.BuildServerOptions();
            this.CreateMqttServer();
        }


        public override async Task StartAsync(CancellationToken cancellationToken)
        {
            await this.StartMqttServerAsync();
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                mqttServiceLogger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(1000, stoppingToken);
            }
        }


        private void BuildServerOptions()
        {
            try
            {
                IPAddress ipAddress = IPAddress.Parse(this.mqttConfiguration.BrokerHostName);
                MqttServerOptionsBuilder optionsBuilder = new MqttServerOptionsBuilder();

                if (this.mqttConfiguration.UseSSL)
                {
                    //// TODO: Implement insert certification
                    optionsBuilder.WithClientCertificate()
                        .WithEncryptionSslProtocol(this.mqttConfiguration.MqttSslProtocol);
                }

                optionsBuilder.WithDefaultEndpointBoundIPAddress(ipAddress)
                    .WithDefaultEndpointPort(this.mqttConfiguration.BrokerPort)
                    .WithConnectionValidator(MQTTConnectionValidator)
                    .WithSubscriptionInterceptor(c =>
                    {
                        c.AcceptSubscription = true;
                        LogMessage(mqttServiceLogger, c, true);
                    })
                    .WithApplicationMessageInterceptor(c =>
                    {
                        c.AcceptPublish = true;
                        LogMessage(mqttServiceLogger, c);
                    });

                this.mqttServerOptions = optionsBuilder.Build();
            }
            catch (Exception ex)
            {
                mqttServiceLogger.LogError(ex.Message);
                throw;
            }
        }

        private void CreateMqttServer()
        {
            try
            {
                this.mqttServer = new MqttFactory().CreateMqttServer();

                //// Add handlers for server
                this.mqttServer.UseClientConnectedHandler(ClientConnectedHandler);
                this.mqttServer.UseClientDisconnectedHandler(ClientDisconnectedHandler);

                this.mqttServer.ClientSubscribedTopicHandler = new MqttServerClientSubscribedHandlerDelegate(args =>
                {
                    try
                    {
                        string clientID = args.ClientId;
                        TopicFilter topicFilter = args.TopicFilter;

                        string topicString = ConvertTopicFilterToString(topicFilter);
                        mqttServiceLogger.LogInformation($"[{DateTime.Now}] Client '{clientID}' subscribed to {topicString}.");
                    }
                    catch (Exception ex)
                    {
                        mqttServiceLogger.LogError(ex.Message);
                    }
                });

                this.mqttServer.ClientUnsubscribedTopicHandler = new MqttServerClientUnsubscribedTopicHandlerDelegate(args =>
                {
                    try
                    {
                        string clientID = args.ClientId;
                        string topicFilter = args.TopicFilter;

                        mqttServiceLogger.LogInformation($"[{DateTime.Now}] Client '{clientID}' un-subscribed to {topicFilter}.");
                    }
                    catch (Exception ex)
                    {
                        mqttServiceLogger.LogError(ex.Message);
                    }
                });
            }
            catch (Exception ex)
            {
                mqttServiceLogger.LogError(ex.Message);
                throw;
            }
        }

        private async Task StartMqttServerAsync()
        {
            try
            {
                if (this.mqttServerOptions == null)
                {
                    throw new ArgumentNullException(nameof(this.mqttServerOptions));
                }

                await this.mqttServer.StartAsync(this.mqttServerOptions);
            }
            catch (Exception ex)
            {
                mqttServiceLogger.LogError(ex.Message);
                throw;
            }
        }



        public static void ClientConnectedHandler(MqttServerClientConnectedEventArgs args)
        {
            try
            {
                string clientID = args.ClientId;
            }
            catch (Exception ex)
            {
                mqttServiceLogger.LogError(ex.Message);
            }
        }

        public static void ClientDisconnectedHandler(MqttServerClientDisconnectedEventArgs args)
        {
            try
            {
                string clientID = args.ClientId;
                MqttClientDisconnectType mqttClientDisconnectType = args.DisconnectType;
            }
            catch (Exception ex)
            {
                mqttServiceLogger.LogError(ex.Message);
            }
        }

        private static string ConvertTopicFilterToString(TopicFilter topicFilter)
        {
            string output = string.Empty;

            if (topicFilter != null)
            {
                output = $"{topicFilter.Topic} - {topicFilter.QualityOfServiceLevel.ToString()}";
            }

            return output;
        }

        /// <summary> 
        /// Logs the message from the MQTT subscription interceptor context. 
        /// </summary> 
        /// <param name="context">The MQTT subscription interceptor context.</param> 
        /// <param name="successful">A <see cref="bool"/> value indicating whether the subscription was successful or not.</param> 
        private static void LogMessage(ILogger<MQTTService> logger, MqttSubscriptionInterceptorContext context, bool successful)
        {
            if (context == null)
            {
                return;
            }

            logger.LogInformation(successful ? $"New subscription: ClientId = {context.ClientId}, TopicFilter = {context.TopicFilter}" : $"Subscription failed for clientId = {context.ClientId}, TopicFilter = {context.TopicFilter}");
        }

        /// <summary>
        /// Logs the message from the MQTT message interceptor context.
        /// </summary>
        /// <param name="context">The MQTT message interceptor context.</param>
        private static void LogMessage(ILogger<MQTTService> logger, MqttApplicationMessageInterceptorContext context)
        {
            if (context == null)
            {
                return;
            }

            var payload = context.ApplicationMessage?.Payload == null ? null : Encoding.UTF8.GetString(context.ApplicationMessage?.Payload);

            logger.LogInformation(
                $"Message: ClientId = {context.ClientId}, Topic = {context.ApplicationMessage?.Topic},"
                + $" Payload = {payload}, QoS = {context.ApplicationMessage?.QualityOfServiceLevel},"
                + $" Retain-Flag = {context.ApplicationMessage?.Retain}");
        }

        /// <summary> 
        /// Logs the message from the MQTT connection validation context. 
        /// </summary> 
        /// <param name="context">The MQTT connection validation context.</param> 
        private static void LogMessage(ILogger<MQTTService> logger, MqttConnectionValidatorContext context)
        {
            if (context == null)
            {
                return;
            }

            logger.LogInformation(
                $"New connection: ClientId = {context.ClientId}, Endpoint = {context.Endpoint},"
                + $" Username = {context.Username}, CleanSession = {context.CleanSession}");
        }
    }


    internal class MQTTConfiguration
    {
        public string BrokerHostName { get; set; }
        public bool UseSSL { get; set; }
        public SslProtocols MqttSslProtocol { get; set; }
        public int BrokerPort { get; set; } = 1883;
    }
}