From 30e49910328d687fc3465b9d800571eb468484d6 Mon Sep 17 00:00:00 2001 From: Noe Date: Mon, 27 Nov 2023 16:43:42 +0100 Subject: [PATCH] Separate websocket manager to rabbitmq consumer, fixed bug in creating user function --- Things-to-know-Kim.txt | 2 +- csharp/App/Backend/Controller.cs | 15 +- csharp/App/Backend/Program.cs | 14 +- .../App/Backend/Websockets/RabbitMQManager.cs | 174 ++++++++++++++++++ .../Backend/Websockets/WebsockerManager.cs | 150 --------------- csharp/App/Middleware/InstallationInfo.cs | 9 - csharp/App/Middleware/Middleware.csproj | 18 -- csharp/App/Middleware/Program.cs | 66 ------- csharp/App/Middleware/RabbitMQConsumer.cs | 88 --------- csharp/App/Middleware/StatusMessage.cs | 8 - csharp/App/Middleware/WebSocketListener.cs | 129 ------------- csharp/App/Middleware/deploy.sh | 1 - csharp/App/SaliMax/src/Program.cs | 11 +- .../Configuration/Configuration.tsx | 4 +- .../Installations/installationForm.tsx | 5 +- .../content/dashboards/Users/UsersSearch.tsx | 2 +- .../src/content/dashboards/Users/userForm.tsx | 2 +- 17 files changed, 200 insertions(+), 498 deletions(-) create mode 100644 csharp/App/Backend/Websockets/RabbitMQManager.cs delete mode 100644 csharp/App/Middleware/InstallationInfo.cs delete mode 100644 csharp/App/Middleware/Middleware.csproj delete mode 100644 csharp/App/Middleware/Program.cs delete mode 100644 csharp/App/Middleware/RabbitMQConsumer.cs delete mode 100644 csharp/App/Middleware/StatusMessage.cs delete mode 100644 csharp/App/Middleware/WebSocketListener.cs delete mode 100755 csharp/App/Middleware/deploy.sh diff --git a/Things-to-know-Kim.txt b/Things-to-know-Kim.txt index 567e4d7eb..80ef6fb93 100644 --- a/Things-to-know-Kim.txt +++ b/Things-to-know-Kim.txt @@ -14,7 +14,7 @@ I'll reroute my emails to one of you for software updates. MARIOS: Please make sure to patch out the vulnerable npm packages in the frontend. - And in my opinion, get started on React or Testcafe Integration tests ;) + Get started on React or Testcafe Integration tests ;) You can add them into the Gitea Actions Pipeline, read the documentation on Github-actions and integration tests. Runner: diff --git a/csharp/App/Backend/Controller.cs b/csharp/App/Backend/Controller.cs index e01f2481c..d74099345 100644 --- a/csharp/App/Backend/Controller.cs +++ b/csharp/App/Backend/Controller.cs @@ -326,11 +326,20 @@ public class Controller : ControllerBase [HttpPost(nameof(CreateUser))] public async Task> CreateUser([FromBody] User newUser, Token authToken) { + var create = Db.GetSession(authToken).Create(newUser); + if (create) + { + var mail_success= await Db.SendNewUserEmail(newUser); + if (!mail_success) + { + Db.GetSession(authToken).Delete(newUser); + } + + return mail_success ? newUser.HidePassword():Unauthorized(); + } - return create && await Db.SendNewUserEmail(newUser) - ? newUser.HidePassword() - : Unauthorized() ; + return Unauthorized() ; } [HttpPost(nameof(CreateInstallation))] diff --git a/csharp/App/Backend/Program.cs b/csharp/App/Backend/Program.cs index 4d27d66ce..1d68676f8 100644 --- a/csharp/App/Backend/Program.cs +++ b/csharp/App/Backend/Program.cs @@ -21,19 +21,11 @@ public static class Program Watchdog.NotifyReady(); Db.Init(); var builder = WebApplication.CreateBuilder(args); - - - string vpnServerIp = "194.182.190.208"; - //string vpnServerIp = "127.0.0.1"; - WebsocketManager.Factory = new ConnectionFactory { HostName = vpnServerIp}; - WebsocketManager.Connection = WebsocketManager.Factory.CreateConnection(); - WebsocketManager.Channel = WebsocketManager.Connection.CreateModel(); - Console.WriteLine("Middleware subscribed to RabbitMQ queue, ready for receiving messages"); - WebsocketManager.Channel.QueueDeclare(queue: "statusQueue", durable: true, exclusive: false, autoDelete: false, arguments: null); - WebsocketManager.StartRabbitMqConsumer(); + RabbitMqManager.InitializeEnvironment(); + RabbitMqManager.StartRabbitMqConsumer(); Console.WriteLine("Queue declared"); - WebsocketManager.InformInstallationsToSubscribeToRabbitMq(); + //WebsocketManager.InformInstallationsToSubscribeToRabbitMq(); WebsocketManager.MonitorInstallationTable(); builder.Services.AddControllers(); diff --git a/csharp/App/Backend/Websockets/RabbitMQManager.cs b/csharp/App/Backend/Websockets/RabbitMQManager.cs new file mode 100644 index 000000000..a928f6e84 --- /dev/null +++ b/csharp/App/Backend/Websockets/RabbitMQManager.cs @@ -0,0 +1,174 @@ +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Text.Json; +using InnovEnergy.App.Backend.Database; +using InnovEnergy.App.Backend.DataTypes; +using RabbitMQ.Client; +using RabbitMQ.Client.Events; + +namespace InnovEnergy.App.Backend.Websockets; + +public static class RabbitMqManager +{ + + public static ConnectionFactory Factory = null!; + public static IConnection Connection = null!; + public static IModel Channel = null!; + + + public static void InitializeEnvironment() + { + + string vpnServerIp = "194.182.190.208"; + Factory = new ConnectionFactory { HostName = vpnServerIp}; + Connection = Factory.CreateConnection(); + Channel = Connection.CreateModel(); + Console.WriteLine("Middleware subscribed to RabbitMQ queue, ready for receiving messages"); + Channel.QueueDeclare(queue: "statusQueue", durable: true, exclusive: false, autoDelete: false, arguments: null); + } + + public static async Task StartRabbitMqConsumer() + { + var consumer = new EventingBasicConsumer(Channel); + consumer.Received += (_, ea) => + { + var body = ea.Body.ToArray(); + var message = Encoding.UTF8.GetString(body); + StatusMessage? receivedStatusMessage = JsonSerializer.Deserialize(message); + var InstallationConnections = WebsocketManager.InstallationConnections; + + lock (InstallationConnections) + { + //Consumer received a message + if (receivedStatusMessage != null) + { + Console.WriteLine("----------------------------------------------"); + Console.WriteLine("Received a message from installation: " + receivedStatusMessage.InstallationId + " and status is: " + receivedStatusMessage.Status); + var installationId = receivedStatusMessage.InstallationId; + + //This is a heartbit message, just update the timestamp for this installation. + //There is no need to notify the corresponding front-ends. + if (receivedStatusMessage.Type == MessageType.Heartbit) + { + Console.WriteLine("This is a heartbit message from installation: " + installationId); + } + else + { + //Traverse the Warnings list, and store each of them to the database + if (receivedStatusMessage.Warnings != null) + { + foreach (var warning in receivedStatusMessage.Warnings) + { + Warning newWarning = new Warning + { + InstallationId = receivedStatusMessage.InstallationId, + Description = warning.Description, + Date = warning.Date, + Time = warning.Time, + DeviceCreatedTheMessage = warning.CreatedBy, + Seen = false + }; + //Create a new warning and add it to the database + Db.HandleWarning(newWarning, receivedStatusMessage.InstallationId); + } + } + + + //Traverse the Alarm list, and store each of them to the database + if (receivedStatusMessage.Alarms != null) + { + foreach (var alarm in receivedStatusMessage.Alarms) + { + Error newError = new Error + { + InstallationId = receivedStatusMessage.InstallationId, + Description = alarm.Description, + Date = alarm.Date, + Time = alarm.Time, + DeviceCreatedTheMessage = alarm.CreatedBy, + Seen = false + }; + //Create a new error and add it to the database + Db.HandleError(newError, receivedStatusMessage.InstallationId); + } + } + } + + //This installation id does not exist in our data structure, add it. + if (!InstallationConnections.ContainsKey(installationId)) + { + Console.WriteLine("Create new empty list for installation: " + installationId); + InstallationConnections[installationId] = new InstallationInfo + { + Status = receivedStatusMessage.Status, + Timestamp = DateTime.Now + }; + } + else + { + InstallationConnections[installationId].Status = receivedStatusMessage.Status; + InstallationConnections[installationId].Timestamp = DateTime.Now; + } + + //Console.WriteLine("----------------------------------------------"); + //Update all the connected front-ends regarding this installation + if(InstallationConnections[installationId].Connections.Count > 0) + { + WebsocketManager.InformWebsocketsForInstallation(installationId); + } + + } + } + }; + Channel.BasicConsume(queue: "statusQueue", autoAck: true, consumer: consumer); + } + + public static void InformInstallationsToSubscribeToRabbitMq() + { + var installationIps = Db.Installations.Select(inst => inst.VpnIp).ToList(); + Console.WriteLine("Count is "+installationIps.Count); + var maxRetransmissions = 2; + + UdpClient udpClient = new UdpClient(); + udpClient.Client.ReceiveTimeout = 2000; + int port = 9000; + //Send a message to each installation and tell it to subscribe to the queue + using (udpClient) + { + for (int i = 0; i < installationIps.Count; i++) + { + if(installationIps[i]==""){continue;} + Console.WriteLine("-----------------------------------------------------------"); + Console.WriteLine("Trying to reach installation with IP: " + installationIps[i]); + //Try at most MAX_RETRANSMISSIONS times to reach an installation. + for (int j = 0; j < maxRetransmissions; j++) + { + string message = "This is a message from RabbitMQ server, you can subscribe to the RabbitMQ queue"; + byte[] data = Encoding.UTF8.GetBytes(message); + udpClient.Send(data, data.Length, installationIps[i], port); + + Console.WriteLine($"Sent UDP message to {installationIps[i]}:{port}: {message}"); + IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(installationIps[i]), port); + + try + { + byte[] replyData = udpClient.Receive(ref remoteEndPoint); + string replyMessage = Encoding.UTF8.GetString(replyData); + Console.WriteLine("Received " + replyMessage + " from installation " + installationIps[i]); + break; + } + catch (SocketException ex) + { + if (ex.SocketErrorCode == SocketError.TimedOut){Console.WriteLine("Timed out waiting for a response. Retry...");} + else{Console.WriteLine("Error: " + ex.Message);} + } + } + } + } + + Console.WriteLine("Start RabbitMQ Consumer"); + + } + +} \ No newline at end of file diff --git a/csharp/App/Backend/Websockets/WebsockerManager.cs b/csharp/App/Backend/Websockets/WebsockerManager.cs index ef4d9a107..24e6c60bb 100644 --- a/csharp/App/Backend/Websockets/WebsockerManager.cs +++ b/csharp/App/Backend/Websockets/WebsockerManager.cs @@ -1,68 +1,12 @@ -using System.Net; -using System.Net.Sockets; using System.Net.WebSockets; using System.Text; using System.Text.Json; -using InnovEnergy.App.Backend.Database; -using InnovEnergy.App.Backend.DataTypes; -using RabbitMQ.Client; -using RabbitMQ.Client.Events; namespace InnovEnergy.App.Backend.Websockets; public static class WebsocketManager { public static Dictionary InstallationConnections = new Dictionary(); - public static ConnectionFactory Factory = null!; - public static IConnection Connection = null!; - public static IModel Channel = null!; - - public static void InformInstallationsToSubscribeToRabbitMq() - { - var installationIps = Db.Installations.Select(inst => inst.VpnIp).ToList(); - Console.WriteLine("Count is "+installationIps.Count); - var maxRetransmissions = 2; - - UdpClient udpClient = new UdpClient(); - udpClient.Client.ReceiveTimeout = 2000; - int port = 9000; - //Send a message to each installation and tell it to subscribe to the queue - using (udpClient) - { - for (int i = 0; i < installationIps.Count; i++) - { - if(installationIps[i]==""){continue;} - Console.WriteLine("-----------------------------------------------------------"); - Console.WriteLine("Trying to reach installation with IP: " + installationIps[i]); - //Try at most MAX_RETRANSMISSIONS times to reach an installation. - for (int j = 0; j < maxRetransmissions; j++) - { - string message = "This is a message from RabbitMQ server, you can subscribe to the RabbitMQ queue"; - byte[] data = Encoding.UTF8.GetBytes(message); - udpClient.Send(data, data.Length, installationIps[i], port); - - Console.WriteLine($"Sent UDP message to {installationIps[i]}:{port}: {message}"); - IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(installationIps[i]), port); - - try - { - byte[] replyData = udpClient.Receive(ref remoteEndPoint); - string replyMessage = Encoding.UTF8.GetString(replyData); - Console.WriteLine("Received " + replyMessage + " from installation " + installationIps[i]); - break; - } - catch (SocketException ex) - { - if (ex.SocketErrorCode == SocketError.TimedOut){Console.WriteLine("Timed out waiting for a response. Retry...");} - else{Console.WriteLine("Error: " + ex.Message);} - } - } - } - } - - Console.WriteLine("Start RabbitMQ Consumer"); - - } //Every 1 minute, check the timestamp of the latest received message for every installation. //If the difference between the two timestamps is more than one minute, we consider this installation unavailable. @@ -82,100 +26,6 @@ public static class WebsocketManager } } - public static async Task StartRabbitMqConsumer() - { - var consumer = new EventingBasicConsumer(Channel); - consumer.Received += (_, ea) => - { - var body = ea.Body.ToArray(); - var message = Encoding.UTF8.GetString(body); - StatusMessage? receivedStatusMessage = JsonSerializer.Deserialize(message); - - lock (InstallationConnections) - { - //Consumer received a message - if (receivedStatusMessage != null) - { - Console.WriteLine("Received a message from installation: " + receivedStatusMessage.InstallationId + " and status is: " + receivedStatusMessage.Status); - Console.WriteLine("----------------------------------------------"); - Console.WriteLine("Update installation connection table"); - var installationId = receivedStatusMessage.InstallationId; - - //This is a heartbit message, just update the timestamp for this installation. - //There is no need to notify the corresponding front-ends. - if (receivedStatusMessage.Type == MessageType.Heartbit) - { - InstallationConnections[installationId].Timestamp = DateTime.Now; - } - else - { - //Traverse the Warnings list, and store each of them to the database - if (receivedStatusMessage.Warnings != null) - { - foreach (var warning in receivedStatusMessage.Warnings) - { - Warning newWarning = new Warning - { - InstallationId = receivedStatusMessage.InstallationId, - Description = warning.Description, - Date = warning.Date, - Time = warning.Time, - DeviceCreatedTheMessage = warning.CreatedBy, - Seen = false - }; - //Create a new warning and add it to the database - Db.HandleWarning(newWarning, receivedStatusMessage.InstallationId); - } - } - - //Traverse the Alarm list, and store each of them to the database - if (receivedStatusMessage.Alarms != null) - { - foreach (var alarm in receivedStatusMessage.Alarms) - { - Error newError = new Error - { - InstallationId = receivedStatusMessage.InstallationId, - Description = alarm.Description, - Date = alarm.Date, - Time = alarm.Time, - DeviceCreatedTheMessage = alarm.CreatedBy, - Seen = false - }; - //Create a new error and add it to the database - Db.HandleError(newError, receivedStatusMessage.InstallationId); - } - } - - //This installation id does not exist in our data structure, add it. - if (!InstallationConnections.ContainsKey(installationId)) - { - Console.WriteLine("Create new empty list for installation: " + installationId); - InstallationConnections[installationId] = new InstallationInfo - { - Status = receivedStatusMessage.Status, - Timestamp = DateTime.Now - }; - } - else - { - InstallationConnections[installationId].Status = receivedStatusMessage.Status; - InstallationConnections[installationId].Timestamp = DateTime.Now; - } - - Console.WriteLine("----------------------------------------------"); - //Update all the connected front-ends regarding this installation - if(InstallationConnections[installationId].Connections.Count > 0) - { - InformWebsocketsForInstallation(installationId); - } - } - } - } - }; - Channel.BasicConsume(queue: "statusQueue", autoAck: true, consumer: consumer); - } - //Inform all the connected websockets regarding installation "installationId" public static void InformWebsocketsForInstallation(int installationId) { diff --git a/csharp/App/Middleware/InstallationInfo.cs b/csharp/App/Middleware/InstallationInfo.cs deleted file mode 100644 index 2e1f5bd79..000000000 --- a/csharp/App/Middleware/InstallationInfo.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Net.WebSockets; - -namespace InnovEnergy.App.Middleware; - -public class InstallationInfo -{ - public int Status { get; set; } - public List Connections { get; } = new List(); -} \ No newline at end of file diff --git a/csharp/App/Middleware/Middleware.csproj b/csharp/App/Middleware/Middleware.csproj deleted file mode 100644 index 34fc15eab..000000000 --- a/csharp/App/Middleware/Middleware.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - InnovEnergy.App.Middleware - - - - - - - - - - - - diff --git a/csharp/App/Middleware/Program.cs b/csharp/App/Middleware/Program.cs deleted file mode 100644 index 7a5bd0ed4..000000000 --- a/csharp/App/Middleware/Program.cs +++ /dev/null @@ -1,66 +0,0 @@ -using InnovEnergy.App.Middleware; -using System; -using System.Net; -using System.Net.Sockets; -using System.Net.WebSockets; -using System.Text; -using InnovEnergy.Lib.Utils; - -internal class Program -{ - public static readonly object SharedDataLock = new object(); - - public static async Task Main(string[] args) - { - //For each installation id, we maintain a list of the connected clients - var installationConnections = new Dictionary(); - var installationsIds = new List {1}; - var installationIps = new List {"10.2.3.115"}; - var MAX_RETRANSMISSIONS = 2; - - RabbitMqConsumer.StartRabbitMqConsumer(installationConnections,SharedDataLock); - - UdpClient udpClient = new UdpClient(); - udpClient.Client.ReceiveTimeout = 2000; - int port = 9000; - //Send a message to each installation and tell it to subscribe to the queue - for (int i = 0; i < installationsIds.Count; i++) - { - using (udpClient) - { - //Try at most MAX_RETRANSMISSIONS times to reach an installation. - for (int j = 0; j < MAX_RETRANSMISSIONS; j++) - { - string message = "This is a message from RabbitMQ server, you can subscribe to the RabbitMQ queue"; - byte[] data = Encoding.UTF8.GetBytes(message); - udpClient.Send(data, data.Length, installationIps[i], port); - - Console.WriteLine($"Sent UDP message to {installationIps[i]}:{port}: {message}"); - IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(installationIps[i]), port); - - try - { - byte[] replyData = udpClient.Receive(ref remoteEndPoint); - string replyMessage = Encoding.UTF8.GetString(replyData); - Console.WriteLine("Received message from installation " + installationsIds[i]); - break; - } - catch (SocketException ex) - { - if (ex.SocketErrorCode == SocketError.TimedOut) - { - Console.WriteLine("Timed out waiting for a response. Retry..."); - } - else - { - Console.WriteLine("Error: " + ex.Message); - } - } - } - } - } - - Console.WriteLine("WebSocket server is running. Press Enter to exit."); - await WebSocketListener.StartServerAsync(installationConnections,SharedDataLock); - } -} \ No newline at end of file diff --git a/csharp/App/Middleware/RabbitMQConsumer.cs b/csharp/App/Middleware/RabbitMQConsumer.cs deleted file mode 100644 index 688f202b9..000000000 --- a/csharp/App/Middleware/RabbitMQConsumer.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System.Net.WebSockets; -using System.Text.Json; -namespace InnovEnergy.App.Middleware; -using System.Text; -using RabbitMQ.Client; -using RabbitMQ.Client.Events; - -public static class RabbitMqConsumer -{ - - private static ConnectionFactory _factory = null!; - private static IConnection _connection = null!; - private static IModel _channel= null!; - - public static void StartRabbitMqConsumer(Dictionary installationConnections, Object sharedDataLock) - { - string vpnServerIp = "194.182.190.208"; - _factory = new ConnectionFactory { HostName = "localhost" }; - _connection = _factory.CreateConnection(); - _channel = _connection.CreateModel(); - Console.WriteLine("Middleware subscribed to RabbitMQ queue, ready for receiving messages"); - _channel.QueueDeclare(queue: "statusQueue", durable: false, exclusive: false, autoDelete: false, arguments: null); - - var consumer = new EventingBasicConsumer(_channel); - consumer.Received += (_, ea) => Callback(installationConnections, sharedDataLock, ea); - - _channel.BasicConsume(queue: "statusQueue", autoAck: true, consumer: consumer); - - } - - private static void Callback(Dictionary installationConnections, Object sharedDataLock, BasicDeliverEventArgs ea) - { - var body = ea.Body.ToArray(); - var message = Encoding.UTF8.GetString(body); - StatusMessage? receivedStatusMessage = JsonSerializer.Deserialize(message); - - lock (sharedDataLock) - { - // Process the received message - if (receivedStatusMessage != null) - { - Console.WriteLine("Received a message from installation: " + receivedStatusMessage.InstallationId + " and status is: " + receivedStatusMessage.Status); - Console.WriteLine("----------------------------------------------"); - Console.WriteLine("Update installation connection table"); - var installationId = receivedStatusMessage.InstallationId; - - if (!installationConnections.ContainsKey(installationId)) - { - Console.WriteLine("Create new empty list for installation: " + installationId); - installationConnections[installationId] = new InstallationInfo - { - Status = receivedStatusMessage.Status - }; - } - - Console.WriteLine("----------------------------------------------"); - - foreach (var installationConnection in installationConnections) - { - if (installationConnection.Key == installationId && installationConnection.Value.Connections.Count > 0) - { - Console.WriteLine("Update all the connected websockets for installation " + installationId); - installationConnection.Value.Status = receivedStatusMessage.Status; - - var jsonObject = new - { - id = installationId, - status = receivedStatusMessage.Status - }; - - string jsonString = JsonSerializer.Serialize(jsonObject); - byte[] dataToSend = Encoding.UTF8.GetBytes(jsonString); - - foreach (var connection in installationConnection.Value.Connections) - { - connection.SendAsync( - new ArraySegment(dataToSend, 0, dataToSend.Length), - WebSocketMessageType.Text, - true, // Indicates that this is the end of the message - CancellationToken.None - ); - } - } - } - } - } - } -} \ No newline at end of file diff --git a/csharp/App/Middleware/StatusMessage.cs b/csharp/App/Middleware/StatusMessage.cs deleted file mode 100644 index fd96aa3df..000000000 --- a/csharp/App/Middleware/StatusMessage.cs +++ /dev/null @@ -1,8 +0,0 @@ - -namespace InnovEnergy.App.Middleware; - -public class StatusMessage -{ - public required int InstallationId { get; init; } - public required int Status { get; init; } -} \ No newline at end of file diff --git a/csharp/App/Middleware/WebSocketListener.cs b/csharp/App/Middleware/WebSocketListener.cs deleted file mode 100644 index 5abf6c263..000000000 --- a/csharp/App/Middleware/WebSocketListener.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System.Net; -using System.Net.WebSockets; -using System.Text; -using System.Text.Json; - -namespace InnovEnergy.App.Middleware; - -public static class WebSocketListener -{ - - public static async Task StartServerAsync(Dictionary installationConnections, Object sharedDataLock) - { - var listener = new HttpListener(); - listener.Prefixes.Add("http://127.0.0.1:8080/"); - - listener.Start(); - - //Http listener listens for connections. When it accepts a new connection, it creates a new Task to handle this connection - while (true) - { - var context = await listener.GetContextAsync(); - if (context.Request.IsWebSocketRequest) - { - var webSocketContext = await context.AcceptWebSocketAsync(null); - var webSocket = webSocketContext.WebSocket; - - // Add the connected WebSocket to the collection - Console.WriteLine("Accepted a new websocket connection"); - HandleWebSocketConnection(webSocket, installationConnections); - } - else - { - context.Response.StatusCode = 400; - context.Response.Close(); - } - } - - //We have a task per websocket connection - async Task HandleWebSocketConnection(WebSocket currentWebSocket, Dictionary installationConnections) - { - - var buffer = new byte[4096]; - - try - { - while (currentWebSocket.State == WebSocketState.Open) - { - //Listen for incoming messages on this WebSocket - var result = await currentWebSocket.ReceiveAsync(buffer, CancellationToken.None); - Console.WriteLine("Received a new message from websocket"); - if (result.MessageType != WebSocketMessageType.Text) - continue; - - var message = Encoding.UTF8.GetString(buffer, 0, result.Count); - var installationIds = JsonSerializer.Deserialize(message); - - lock (sharedDataLock) - { - //Each front-end will send the list of the installations it wants to access - //If this is a new key (installation id), initialize the list for this key and then add the websocket object for this client - //Then, report the status of each requested installation to the front-end that created the websocket connection - foreach (var installationId in installationIds) - { - if (!installationConnections.ContainsKey(installationId)) - { - Console.WriteLine("Create new empty list for installation id "+installationId); - installationConnections[installationId] = new InstallationInfo - { - Status = -2 - }; - } - - installationConnections[installationId].Connections.Add(currentWebSocket); - - var jsonObject = new - { - id = installationId, - status = installationConnections[installationId].Status - }; - - var jsonString = JsonSerializer.Serialize(jsonObject); - var dataToSend = Encoding.UTF8.GetBytes(jsonString); - - - currentWebSocket.SendAsync(dataToSend, - WebSocketMessageType.Text, - true, // Indicates that this is the end of the message - CancellationToken.None - ); - } - - Console.WriteLine("Printing installation connection list"); - Console.WriteLine("----------------------------------------------"); - foreach (var installationConnection in installationConnections) - { - Console.WriteLine("Installation ID: " + installationConnection.Key + " Number of Connections: " + installationConnection.Value.Connections.Count); - } - Console.WriteLine("----------------------------------------------"); - } - } - - //When the front-end terminates the connection, the following code will be executed - Console.WriteLine("The connection has been terminated"); - foreach (var installationConnection in installationConnections) - { - if (installationConnection.Value.Connections.Contains(currentWebSocket)) - { - installationConnection.Value.Connections.Remove(currentWebSocket); - } - } - - await currentWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Connection closed by server", CancellationToken.None); - //Print the installationConnections dictionary after deleting a websocket - Console.WriteLine("Print the installation connections list after deleting a websocket"); - Console.WriteLine("----------------------------------------------"); - foreach (var installationConnection in installationConnections) - { - Console.WriteLine("Installation ID: "+ installationConnection.Key+" Number of Connections: "+installationConnection.Value.Connections.Count); - } - Console.WriteLine("----------------------------------------------"); - } - catch (Exception ex) - { - Console.WriteLine("WebSocket error: " + ex.Message); - } - } - } -} - diff --git a/csharp/App/Middleware/deploy.sh b/csharp/App/Middleware/deploy.sh deleted file mode 100755 index d8017c7c0..000000000 --- a/csharp/App/Middleware/deploy.sh +++ /dev/null @@ -1 +0,0 @@ -dotnet publish Middleware.csproj -c Release -r linux-x64 --self-contained true -p:PublishTrimmed=false && rsync -av bin/Release/net6.0/linux-x64/publish/ ubuntu@194.182.190.208:~/middleware diff --git a/csharp/App/SaliMax/src/Program.cs b/csharp/App/SaliMax/src/Program.cs index b9c6dbbeb..88fb7e913 100644 --- a/csharp/App/SaliMax/src/Program.cs +++ b/csharp/App/SaliMax/src/Program.cs @@ -262,6 +262,7 @@ internal static class Program { var s3Bucket = Config.Load().S3?.Bucket; + //Every 15 iterations(30 seconds), the installation sends a heartbit message to the queue _heartBitInterval++; //When the controller boots, it tries to subscribe to the queue @@ -269,14 +270,9 @@ internal static class Program { _subscribeToQueueForTheFirstTime = true; SubscribeToQueue(currentSalimaxState, s3Bucket); - - if (_subscribedToQueue && currentSalimaxState.Status != _prevSalimaxState) - { - _prevSalimaxState = currentSalimaxState.Status; - } } //If already subscribed to the queue and the status has been changed, update the queue - else if (_subscribedToQueue && currentSalimaxState.Status != _prevSalimaxState) + if (_subscribedToQueue && currentSalimaxState.Status != _prevSalimaxState) { _prevSalimaxState = currentSalimaxState.Status; if (s3Bucket != null) @@ -284,6 +280,7 @@ internal static class Program } else if (_subscribedToQueue && _heartBitInterval>=15) { + //Send a heartbit to the backend Console.WriteLine("----------------------------------------Sending Heartbit----------------------------------------"); _heartBitInterval = 0; currentSalimaxState.Type = MessageType.Heartbit; @@ -320,11 +317,9 @@ internal static class Program _factory = new ConnectionFactory { HostName = VpnServerIp }; _connection = _factory.CreateConnection(); _channel = _connection.CreateModel(); - _channel.QueueDeclare(queue: "statusQueue", durable: true, exclusive: false, autoDelete: false, arguments: null); Console.WriteLine("The controller sends its status to the middleware for the first time"); - if (s3Bucket != null) InformMiddleware(currentSalimaxState); _subscribedToQueue = true; diff --git a/typescript/frontend-marios2/src/content/dashboards/Configuration/Configuration.tsx b/typescript/frontend-marios2/src/content/dashboards/Configuration/Configuration.tsx index f204ebf6a..e93a7aa98 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Configuration/Configuration.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Configuration/Configuration.tsx @@ -48,8 +48,8 @@ function Configuration(props: ConfigurationProps) { } value={props.values.calibrationChargeForced.values[0].value} diff --git a/typescript/frontend-marios2/src/content/dashboards/Installations/installationForm.tsx b/typescript/frontend-marios2/src/content/dashboards/Installations/installationForm.tsx index 935666a8c..76a0916d5 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Installations/installationForm.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Installations/installationForm.tsx @@ -80,7 +80,7 @@ function installationForm(props: installationFormProps) { +
} - name="VpnIp" + name="vpnIp" value={formValues.vpnIp} onChange={handleChange} fullWidth diff --git a/typescript/frontend-marios2/src/content/dashboards/Users/UsersSearch.tsx b/typescript/frontend-marios2/src/content/dashboards/Users/UsersSearch.tsx index ea0fa2950..71e039321 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Users/UsersSearch.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Users/UsersSearch.tsx @@ -95,7 +95,7 @@ function UsersSearch() { >