c#实现通过MQTTnet库接收MQTT订阅信息并立即将数据写入ModbusRTU设备的功能主要代码
Program.cs
`
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.ObjectPool;
class Program
{
static async Task Main(string[] args)
{
var config = new AppConfig {
MqttBroker = "broker.example.com",
MqttPort = 1883,
MqttTopic = "modbus/commands",
ModbusPort = "COM3",
BaudRate = 9600
};
var services = new ServiceCollection();
services.AddSingleton(config);
services.AddSingleton<IModbusService, ModbusRtuService>();
services.AddSingleton<IMqttService, MqttClientService>();
services.AddHostedService<DataProcessingService>();
using var host = Host.CreateDefaultBuilder()
.ConfigureServices(services)
.Build();
await host.RunAsync();
}
}
AppConfig.cspublic class AppConfig
{
public string MqttBroker { get; set; }
public int MqttPort { get; set; }
public string MqttTopic { get; set; }
public string ModbusPort { get; set; }
public int BaudRate { get; set; }
}IModbusService.cspublic interface IModbusService : IAsyncDisposable
{
Task InitializeAsync(string portName, int baudRate);
Task WriteSingleRegisterAsync(byte slaveAddress, ushort startAddress, ushort value);
Task WriteMultipleRegistersAsync(byte slaveAddress, ushort startAddress, ushort[] values);
}
ModbusRtuService.cs System.IO.Ports;
using NModbus;
using NModbus.Serial;
public class ModbusRtuService : IModbusService
{
private SerialPort _serialPort;
private IModbusSerialMaster _modbusMaster;
private readonly SemaphoreSlim _semaphore = new(1, 1);
public async Task InitializeAsync(string portName, int baudRate)
{
await _semaphore.WaitAsync();
try {
_serialPort = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);
_serialPort.Open();
var factory = new ModbusFactory();
_modbusMaster = factory.CreateRtuMaster(_serialPort);
}
finally {
_semaphore.Release();
}
}
public async Task WriteSingleRegisterAsync(byte slaveAddress, ushort startAddress, ushort value)
{
await _semaphore.WaitAsync();
try {
await _modbusMaster.WriteSingleRegisterAsync(slaveAddress, startAddress, value);
}
finally {
_semaphore.Release();
}
}
public async ValueTask DisposeAsync()
{
_modbusMaster?.Dispose();
_serialPort?.Close();
_serialPort?.Dispose();
}
}
IMqttService.cs interface IMqttService
{
Task ConnectAsync();
event Func<MqttMessage, Task> MessageReceived;
}
MqttClientService.cs MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
public class MqttClientService : IMqttService
{
private readonly IMqttClient _mqttClient;
private readonly AppConfig _config;
public event Func<MqttMessage, Task> MessageReceived;
public MqttClientService(AppConfig config)
{
_config = config;
var factory = new MqttFactory();
_mqttClient = factory.CreateMqttClient();
}
public async Task ConnectAsync()
{
var options = new MqttClientOptionsBuilder()
.WithTcpServer(_config.MqttBroker, _config.MqttPort)
.WithClientId($"ModbusGateway_{Guid.NewGuid()}")
.Build();
_mqttClient.UseApplicationMessageReceivedHandler(async e => {
var message = new MqttMessage {
Topic = e.ApplicationMessage.Topic,
Payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload)
};
await MessageReceived?.Invoke(message);
});
await _mqttClient.ConnectAsync(options);
await _mqttClient.SubscribeAsync(_config.MqttTopic);
}
}
DataProcessingService.cs System.Threading.Channels;
public class DataProcessingService : BackgroundService
{
private readonly Channel
private readonly IMqttService _mqttService;
private readonly IModbusService _modbusService;
public DataProcessingService(IMqttService mqttService, IModbusService modbusService)
{
_mqttService = mqttService;
_modbusService = modbusService;
_mqttService.MessageReceived += async msg => await _messageChannel.Writer.WriteAsync(msg);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await _modbusService.InitializeAsync("COM3", 9600);
await _mqttService.ConnectAsync();
await foreach (var message in _messageChannel.Reader.ReadAllAsync(stoppingToken))
{
await ProcessMessageAsync(message);
}
}
private async Task ProcessMessageAsync(MqttMessage message)
{
try {
var modbusMsg = JsonSerializer.Deserialize<ModbusMessage>(message.Payload);
if (modbusMsg.RegisterValues.Length == 1) {
await _modbusService.WriteSingleRegisterAsync(
modbusMsg.SlaveAddress,
modbusMsg.StartAddress,
modbusMsg.RegisterValues[0]);
} else {
await _modbusService.WriteMultipleRegistersAsync(
modbusMsg.SlaveAddress,
modbusMsg.StartAddress,
modbusMsg.RegisterValues);
}
}
catch (Exception ex) {
// 错误处理和日志记录
}
}
}
Models.cs class MqttMessage
{
public string Topic { get; set; }
public string Payload { get; set; }
}
public class ModbusMessage
{
public byte SlaveAddress { get; set; }
public ushort StartAddress { get; set; }
public ushort[] RegisterValues { get; set; }
}
`
总结:该实现包含完整的MQTT消息接收、ModbusRTU写入、异步处理管道和错误处理机制,可直接集成到.NET Core应用中

浙公网安备 33010602011771号