CarTrackingRuleEngine/SimulatedTrackingDevice/Program.cs

168 lines
6.9 KiB
C#

using System.Security.Cryptography;
using System.Text.Json;
using System.Text;
using MQTTnet;
using MQTTnet.Protocol;
using Newtonsoft.Json;
using System.Collections.Concurrent;
namespace SimulatedTrackingDevice
{
internal class Program
{
private static readonly string BrokerIp = "127.0.0.1";
//private static readonly string BrokerIp = "localhost";
private static readonly int BrokerPort = 1883;
private static readonly string Username = "emqxdevice";
private static readonly string Password = "sivan@123";
private static readonly string DevicePasswordSalt = "navis@salt";
private static readonly int secondsToReconnect = 2000;
private static readonly int secondsToHealthcheck = 10000;
//private static readonly int DeviceCount = 1000;
private static readonly string UpdatePVTTopic = "iot/device/update_pvt";
private static readonly ConcurrentDictionary<string, string> deviceTokens = new();
private static readonly ConcurrentDictionary<string, SemaphoreSlim> deviceSemaphores = new();
static async Task Main(string[] args)
{
List<Task> deviceTasks = new();
for (int i = 1; i <= 1; i++)
{
string localMacAddress = $"DeviceTest{i:0000}";
deviceSemaphores[localMacAddress] = new SemaphoreSlim(1, 1); // Tạo semaphore riêng cho từng thiết bị
//deviceTasks.Add(AllDevicePublish(macAddress, i));
deviceTasks.Add(SimulateDevice(localMacAddress));
await Task.Delay(50); // Tránh quá tải khi tạo quá nhiều thiết bị cùng lúc
}
await Task.WhenAll(deviceTasks);
}
private static async Task SimulateDevice(string localMacAddress)
{
try
{
var factory = new MqttClientFactory();
var mqttClient = factory.CreateMqttClient();
string token = "";
var options = new MqttClientOptionsBuilder()
.WithClientId(localMacAddress)
.WithTcpServer(BrokerIp, BrokerPort)
.WithCredentials(Username, Password)
.WithCleanSession()
.Build();
mqttClient.ApplicationMessageReceivedAsync += async e =>
{
var macAddressProperty = e.ApplicationMessage.UserProperties
.FirstOrDefault(p => p.Name == "MacAddress")?.Value;
if (macAddressProperty == localMacAddress)
{
var commandTopic = "iot/server/" + localMacAddress + "/command";
string topic = e.ApplicationMessage.Topic;
string payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
if (topic == ResponseTopic)
{
if (!string.IsNullOrEmpty(payload))
{
var response = System.Text.Json.JsonSerializer.Deserialize<DeviceRegisterResponse>(payload);
token = response.AccessToken;
// Unsubscribe khỏi topic response sau khi nhận token
await mqttClient.UnsubscribeAsync(ResponseTopic);
Console.WriteLine(localMacAddress + ": Unsubscribed from response topic");
// log file
Log2File("./LogFiles/" + localMacAddress + ".txt", DateTime.UtcNow.AddHours(7).ToString("yyyy/MM/dd HH:mm:ss") + " - Received: " + payload);
}
}
else if (topic == commandTopic)
{
// xu ly lenh gui tu server
Console.WriteLine(localMacAddress + ": " + payload);
// log file
Log2File("./LogFiles/" + localMacAddress + ".txt", DateTime.UtcNow.AddHours(7).ToString("yyyy/MM/dd HH:mm:ss") + " - Received: " + payload);
}
}
};
await mqttClient.ConnectAsync(options, CancellationToken.None);
await mqttClient.SubscribeAsync(ResponseTopic, MqttQualityOfServiceLevel.AtLeastOnce);
await SendRegistrationRequest(mqttClient, localMacAddress);
while (string.IsNullOrEmpty(token))
{
await Task.Delay(1000);
}
var _factory = new MqttClientFactory();
var _mqttClient = _factory.CreateMqttClient();
var _options = new MqttClientOptionsBuilder()
.WithClientId(localMacAddress)
.WithTcpServer(BrokerIp, BrokerPort)
.WithCredentials(localMacAddress, token)
.WithCleanSession()
.Build();
_mqttClient.DisconnectedAsync += async (e) =>
{
Console.WriteLine($"MQTT Disconnected. Reason: {e.ToString()}");
// Nếu lỗi có thể do token hết hạn, gửi lại request đăng ký
if (e.Reason == MqttClientDisconnectReason.NotAuthorized)
{
Console.WriteLine("Token might be expired. Sending Register...");
}
};
await _mqttClient.ConnectAsync(_options, CancellationToken.None);
while (true)
{
await SendHealthData(_mqttClient, localMacAddress, token);
await Task.Delay(10000);
}
}
catch (Exception ex)
{
// log file
Log2File("./LogFiles/Exceptions.txt", DateTime.UtcNow.AddHours(7).ToString("yyyy/MM/dd HH:mm:ss") + "- User: " + Username + " - " + localMacAddress + ": " + ex.ToString());
}
}
public static void Log2File(string filePath, string data)
{
try
{
FileInfo info = new FileInfo(filePath);
try
{
if (info.Exists && info.Length > 10000000) // delete the file first if 10 MB
{
File.Delete(filePath);
}
}
catch (Exception ex)
{
}
using (var fs = File.Open(filePath, FileMode.Append))
{
using (var sw = new StreamWriter(fs))
{
sw.WriteLine(data);
}
}
}
catch (Exception ex)
{
}
}
}
}