using System.Diagnostics.CodeAnalysis; using System.Text.Json; using Backend.Helper; using MessagePack; using Models.Handler; using Models.Model.Backend; using Models.Model.External; using NetMQ; using NetMQ.Sockets; namespace Backend.Handler; public class Communication { private readonly DbHandler _dbHandler; private readonly ThreadHandler _threadHandler; private bool _isRunning = true; public Communication(DbHandler dbHandler, ThreadHandler threadHandler) { _dbHandler = dbHandler; _threadHandler = threadHandler; } public WaitHandle[] Start() { WaitHandle[] waitHandles = new WaitHandle[1]; EventWaitHandle handle = new(false, EventResetMode.ManualReset); waitHandles[0] = handle; Thread thread = new(Server!); thread.Start(handle); return waitHandles; } private void Server(object obj) { using ResponseSocket rep = new(); rep.Bind("tcp://127.0.0.1:5556"); while (_isRunning) { byte[] message = rep.ReceiveFrameBytes(); CommunicationObject communicationObject = MessagePackSerializer.Deserialize(message); OnServerOnReceiveReady(communicationObject, rep); } ((EventWaitHandle) obj).Set(); } [RequiresDynamicCode("Calls System.Text.Json.JsonSerializer.Serialize(TValue, JsonSerializerOptions)")] [RequiresUnreferencedCode("Calls System.Text.Json.JsonSerializer.Serialize(TValue, JsonSerializerOptions)")] private void OnServerOnReceiveReady(CommunicationObject communicationObject, ResponseSocket rep) { switch (communicationObject.Command) { case CommunicationCommand.GetScanningProgress: { DatabaseSizes databaseSizes = FilesystemHelper.GetDatabaseSizes(); long discardedIndexes = _dbHandler.GetDiscardedIndexes(); ScanningStatus status = new(); // 4294967296 is all Ipv4 addresses. if (discardedIndexes != 0) { status.PercentageOfIpv4Scanned = (float)discardedIndexes / 4294967296 * 100; } else { status.PercentageOfIpv4Scanned = 0.0000000001f; } status.AmountOfIpv4Left = 4294967296 - discardedIndexes; status.TotalFiltered = DbHandler.GetFilteredIndexes(); status.TotalDiscarded = discardedIndexes; status.MyDbSize = databaseSizes.MyDbSize; status.FilteredDbSize = databaseSizes.FilteredDbSize; status.DiscardedDbSize = databaseSizes.DiscardedDbSize; byte[] serializedResult = MessagePackSerializer.Serialize(status, MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray)); rep.SendFrame(serializedResult); break; } case CommunicationCommand.DbReindex: { _dbHandler.ReIndex(); SendStringResponse(rep, "All Dbs have been reindexed."); break; } case CommunicationCommand.DbVacuum: { _dbHandler.Vacuum(); SendStringResponse(rep, "All Dbs have been vacuumed."); break; } case CommunicationCommand.GetSearches: { if (!string.IsNullOrWhiteSpace(communicationObject.SearchTerm)) { SendSearchResponse(rep, communicationObject.SearchTerm); } break; } case CommunicationCommand.StopScanning: { _isRunning = false; break; } } } private static void SendStringResponse(ResponseSocket rep, string response) { MessagePackSerializerOptions withCompression = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray); byte[] serializedResult = MessagePackSerializer.Serialize(response, withCompression); rep.SendFrame(serializedResult); } private static void SendSearchResponse(ResponseSocket rep, string searchTerm) { //SearchResults result = SearchHelper.Search(communicationObject.SearchTerm!, _dbHandler); SearchResults result = new() { Results = [] }; SearchResult lol = new() { Url = "Remember to use an actual search tearm. Like 'dotnet 9.0'", Title = "Remember to use an actual search tearm. Like 'dotnet 9.0'", }; result.Results.Add(lol); string serializedResult = JsonSerializer.Serialize(result); rep.SendFrame(serializedResult); } }