C# 无法连接到作为docker容器部署的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服务器(MqttCommunicationTimedOutException) 1) 什么可以阻止mqtt客户机与服务器通信 2) 如何知道服务器是否已正确启动 DockerFileC# 无法连接到作为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
名称空间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;
}
}