예제 #1
0
            private async void OnConnectionFailureAsync(object sender, ConnectionTimeoutEventArgs args)
            {
                await WorkerClient.CloseAsync();

                HadConnectionFailure = true;
                m_shutdownTcs.TrySetResult(false);
            }
예제 #2
0
        /// <summary>
        /// Apply new settings
        /// </summary>
        private void CheckSettings()
        {
            //Number of Clients
            while (_settings.NumOfClients > _ThreadManager.CurrentCount)
            {
                WorkerClient client   = new WorkerClient();
                Consumer     consumer = new Consumer(_settings.ConsumersleepNum, client);

                Thread thread = new Thread(consumer.Consume)
                {
                    Name         = "consumer " + Guid.NewGuid().ToString(),
                    IsBackground = false
                };
                thread.SetApartmentState(ApartmentState.MTA);

                _ThreadManager.AddThread(thread, consumer);

                thread.Start();
            }

            while (_settings.NumOfClients < _ThreadManager.CurrentCount)
            {
                _ThreadManager.KillThread();
            }

            //Consumer Sleep time
            if (_ThreadManager.CurrentCount != 0 && _settings.ConsumersleepNum != _ThreadManager.GetRunningThreads()[0].Item2._consumerSleepNum)
            {
                foreach (var item in _ThreadManager.GetRunningThreads())
                {
                    item.Item2._consumerSleepNum = _settings.ConsumersleepNum;
                }
            }
        }
예제 #3
0
 public Consumer(int consumerSleepNum, WorkerClient connection)
 {
     this._consumerSleepNum = consumerSleepNum;
     _Producer  = connection;
     _wordFound = new List <string>();
     Stop       = false;
 }
예제 #4
0
        public static async Task WakeupCall()
        {
            using var client = new WorkerClient();
            await client.GetTypeBsAsync();

            ++_clientRequests;
        }
예제 #5
0
        private void btnAddRoute_Click(object sender, EventArgs e)
        {
            Route route = new Route();

            route.id            = int.Parse(tbox_addRoute_id.Text);
            route.startingPoint = (Location)cmb_addRoute_startingPoint.SelectedItem;
            route.destination   = (Location)cmb_addRoute_destination.SelectedItem;
            route.distance      = double.Parse(tbox_addRoute_distance.Text);
            route.driver        = (Worker)cmb_addRoute_driver.SelectedItem;
            route.vehicle       = (Vehicle)cmb_addRoute_Vehicle.SelectedItem;
            route.startDate     = dtp_addRoute_startDate.Value;
            route.finished      = false;


            try
            {
                DeliveryHolder.routes.Add(route);
                DeliveryClient.InsertRoute(route);

                clearTab(tabPageRoutes);
                tbox_addRoute_id.Text = DeliveryHolder.routes.Count == 0 ? "1" :
                                        (DeliveryHolder.routes.Count + 1).ToString();

                WorkerHolder.avaliableWorkers    = WorkerClient.GetAavalibleWorkers();
                DeliveryHolder.avaliableVehicles = DeliveryClient.GetAvalibleVehicles();

                setupRouteCmb();
            }
            catch (Exception)
            {
                MessageBox.Show("Failed to add route");
            }
        }
예제 #6
0
        private void btn_addWorkere_complete_Click(object sender, EventArgs e)
        {
            Worker worker = new Worker();

            worker.id          = int.Parse(tbox_addWorker_id.Text);
            worker.name        = tbox_addWorker_name.Text;
            worker.surname     = tbox_addWorker_surname.Text;
            worker.username    = tbox_addWorker_username.Text;
            worker.dateOfBirth = dtp_addWorker.Value;
            worker.city        = tbox_addWorker_city.Text;
            worker.position    = (WorkerPosition)cmb_addWorker_position.SelectedItem;
            worker.warehouse   = (Warehouse)cmb_addWorker_warehouse.SelectedItem;

            try
            {
                WorkerHolder.workers.Add(worker);
                WorkerClient.InsertWorker(worker);

                addWorkerClearTab();
            }
            catch (Exception)
            {
                MessageBox.Show("Failed to add worker");
            }
        }
예제 #7
0
        public void CanExecute()
        {
            var    client   = new WorkerClient();
            string response = client.Execute("UpdateToolDataClean", new[] { "2018-09-01", "0" });

            Assert.IsTrue(response.StartsWith("Enqueued command UpdateToolDataClean at "));
        }
예제 #8
0
            private async void OnConnectionFailureAsync(object sender, ConnectionFailureEventArgs args)
            {
                await WorkerClient.CloseAsync();

                ClientConnectionFailure = args.Type;
                args.Log(LoggingContext, "TestWorker");
                m_shutdownTcs.TrySetResult(false);
            }
예제 #9
0
 private void cmdreset_Click(object sender, EventArgs e)
 {
     if (_Client == null)
     {
         _Client = new WorkerClient();
     }
     _Client.Reset();
 }
예제 #10
0
            public Task <RpcCallResult <Unit> > SendBuildRequestAsync()
            {
                var pipRequest = GrpcMockData.PipBuildRequest(m_nextPipSequenceNumber++, (0, PipExecutionStep.CacheLookup));

                return(WorkerClient.ExecutePipsAsync(pipRequest.ToOpenBond(), new List <long> {
                    0
                }));
            }
예제 #11
0
 static void Main(string[] args)
 {
     Console.WriteLine("Creating proxy");
     var client = new WorkerClient();
     Console.WriteLine("Calling method on proxy");
     client.DoWork();
     Console.WriteLine("Press any key to exit");
     Console.ReadKey();
 }
예제 #12
0
            public override async Task StopAllServicesAsync()
            {
                if (WorkerClient != null)
                {
                    await WorkerClient.CloseAsync();

                    m_shutdownTcs.TrySetResult(true);
                }
            }
예제 #13
0
        static void Main(string[] args)
        {
            Console.WriteLine("Creating proxy");
            var client = new WorkerClient();

            Console.WriteLine("Calling method on proxy");
            client.DoWork();
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
예제 #14
0
        public StartingForm()
        {
            InitializeComponent();

            try
            {
                //Get all Products
                DataHolders.ProductsHolder.products = ProductClient.GetProducts();

                //Get all connections
                DataHolders.ButtonConnectionHolder.connections      = ButtonsClient.GetButtonConnections();
                DataHolders.UnitProductConnectionHolder.Connections = ButtonsClient
                                                                      .GetUnitPorductConnections();

                //Documents
                DataHolders.DocumentConnectionHolder.documentProductConnections = DocumentClient
                                                                                  .GetAllDocumnetProductConnections();

                //Warehouse
                DataHolders.WarehouseHolder.warehouses = DatabaseManagers.WarehouseClient.GetWarehouses();


                //DatabaseManagers.WarehouseManager.GetWarehouses();
                DataHolders.WarehouseHolder.warehouseProductConnections = DatabaseManagers.WarehouseClient
                                                                          .GetWarehouseProductConnection();

                //workers
                DataHolders.WorkerHolder.workers          = WorkerClient.GetWorkers();
                DataHolders.WorkerHolder.avaliableWorkers = WorkerClient.GetAavalibleWorkers();

                //Delivery
                DataHolders.DeliveryHolder.partners          = DeliveryClient.GetPartners();
                DataHolders.DeliveryHolder.locations         = DeliveryClient.GetLocations();
                DataHolders.DeliveryHolder.vehicles          = DeliveryClient.GetVehicles();
                DataHolders.DeliveryHolder.routes            = DeliveryClient.GetRoutes();
                DataHolders.DeliveryHolder.avaliableVehicles = DeliveryClient.GetAvalibleVehicles();

                //properties
                if (PropertiesClient.GetProperties().Exists((e) => e.name == Enums.PropertyName.distance))
                {
                    DataHolders.PropertiesHolder.distanceUnit = PropertiesClient.GetProperties()
                                                                .Find((e) => e.name == Enums.PropertyName.distance).value;
                }
                if (PropertiesClient.GetProperties().Exists((e) => e.name == Enums.PropertyName.weight))
                {
                    DataHolders.PropertiesHolder.weightUnit = PropertiesClient.GetProperties()
                                                              .Find((e) => e.name == Enums.PropertyName.weight).value;
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Error connecting to database, initial data couldn't be load");
                Environment.Exit(1);
            }
        }
예제 #15
0
            public async Task <RpcCallResult <Unit> > ExitAsync(bool exitWithFailure = false)
            {
                var buildEndData = new global::BuildXL.Engine.Distribution.OpenBond.BuildEndData()
                {
                    Failure = exitWithFailure ? "Some failure" : null
                };

                var result = await WorkerClient.ExitAsync(buildEndData, CancellationToken.None);

                m_shutdownTcs.TrySetResult(exitWithFailure);
                return(result);
            }
예제 #16
0
 public static void Main(string[] args)
 {
     Task.Run(async() =>
     {
         var wk = new WorkerClient();
         while (true)
         {
             await wk.PingBack("http://localhost:62033/healthcheck/myworker/ping");
             await Task.Delay(1000);
         }
     });
     BuildWebHost(args).Run();
 }
예제 #17
0
        /// <summary>
        /// Unassigns work from client and stops any ongoing file transfers.
        /// Unassigned works are added back to the backlog.
        /// </summary>
        void unassignWorkFromClient(WorkerClient wc)
        {
            // take assigned work from client, remove it, add back to backlog
            var w = wc.AssignedUrl;

            wc.AssignedUrl = null;

            // stop any transfer that might be going on
            wc.StopTransfer();

            if (w != null)
            {
                manager.AddToBacklog(w);
            }
        }
예제 #18
0
        /// <summary>
        /// Validate settings and sends it to server.
        /// </summary>
        private void sendSettings()
        {
            //Check settings if valid
            Settings newSettings;

            try
            {
                int clients       = Convert.ToInt32(nClients.Value);
                int producer      = Convert.ToInt32(nProducers.Value);
                int bufferSize    = Convert.ToInt32(nBufferSize.Value);
                int ConsumerSleep = Convert.ToInt32(nConsumerSleep.Value);
                int producerSleep = Convert.ToInt32(nProducerSleep.Value);
                int word          = Convert.ToInt32(nWordCount.Value);
                newSettings = new Settings(clients, producer, bufferSize, ConsumerSleep, word, producerSleep);
            }
            catch (Exception e)
            {
                MessageBox.Show("Please have digit numbers");
                return;
            }

            try
            {
                _Client = new WorkerClient();
                //Send Settings
                var result = _Client.Post(newSettings);
                if (result == HttpStatusCode.OK)
                {
                    tpSettings.Name = "Settings";
                    _settings       = newSettings;

                    //Apply settings on Consumer Monitor end.
                    bkWorker.RunWorkerAsync();
                    MessageBox.Show("Setting posted successfully");
                }
                else
                {
                    MessageBox.Show("Setting NOT successful.");
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("Setting not successful for some reason.  Probably Service is not active");
            }
        }
예제 #19
0
 private void cmdTestConnection_Click(object sender, EventArgs e)
 {
     try
     {
         WorkerClient client = new WorkerClient();
         if (client.Test())
         {
             MessageBox.Show("Found service");
         }
         else
         {
             MessageBox.Show("Service not found");
         }
     }
     catch (Exception exception)
     {
         MessageBox.Show("Service not found");
     }
 }
예제 #20
0
        private static void CompositeExample()
        {
            var workersComposition = new List <IWorker>()
            {
                new Worker(),
                new Worker(),
                new Worker()
            };

            var compositeWorker = new CompositeWorker(workersComposition);
            var worker          = new Worker();

            // The client will treat a single a worker and a composition of workers
            // the same way, through a single interface method call.
            var client = new WorkerClient();

            // Use collection of workers.
            client.UseWorker(compositeWorker);
            // Use a single worker.
            client.UseWorker(worker);
        }
예제 #21
0
        private void btnAddRouteTab_Click(object sender, EventArgs e)
        {
            tabControlPartners.SelectedTab = tabControlPartners.TabPages[1];
            btnAddRoute.Visible            = true;
            btnSaveRoute.Visible           = false;
            btnSearchRoute.Visible         = false;

            try
            {
                WorkerHolder.avaliableWorkers    = WorkerClient.GetAavalibleWorkers();
                DeliveryHolder.avaliableVehicles = DeliveryClient.GetAvalibleVehicles();
            }
            catch (Exception)
            {
                MessageBox.Show("Failed to get avaliable vehicles or workers");
            }


            clearTab(tabPageRoutes);
            tbox_addRoute_id.Text = DeliveryHolder.routes.Count == 0 ? "1" :
                                    (DeliveryHolder.routes.Count + 1).ToString();
            setupRouteCmb();
        }
예제 #22
0
 private void NotifyClientUpdatedEvent(WorkerClient pClient)
 {
     ClientUpdatedEvent?.Invoke(pClient);
     //NotifyNewLogMessageEvent($"CONNECT: {pClient.ID}");
 }
예제 #23
0
        private void CWCMessageArrived(WorkerClient sender, byte[] b, int len)
        {
            Message.Message msg = new Message.Message(b);

            try
            {
                if (curMsg == null)
                {
                    Logger.MajorVerbose("Client: " + sender.ClientIP() + System.Environment.NewLine + "Request: " + msg.MessageData);
                    Logger.MajorDebug("Searching for implementor of " + msg.MessageData + "...");

                    ConsoleCommands.ConsoleCommandClass CC = CCE.GetLoadedCommand(msg.MessageData);

                    if (CC == null)
                    {
                        Logger.MajorError("No implementor for " + msg.MessageData + ".");
                        sender.send("Command not found" + System.Environment.NewLine);
                    }
                    curMsg = (ConsoleCommands.AConsoleCommand)Activator.CreateInstance(CC.CommandType);
                    curMsg.InitializeStack();
                }
                else
                {
                    string returnMsg = null;

                    try
                    {
                        returnMsg = curMsg.AcceptMessage(msg.MessageData);
                    }
                    catch (Exception ex)
                    {
                        returnMsg = ex.Message;
                    }

                    if ((returnMsg != null) && (curMsg.CommandFinished))
                    {
                        sender.send(returnMsg + System.Environment.NewLine);
                        curMsg = null;
                    }
                    else
                    {
                        sender.send(curMsg.GetClientMessage());
                    }
                    return;
                }

                if (curMsg.IsNoinputCommand())
                {
                    try
                    {
                        sender.send(curMsg.ProcessMessage() + System.Environment.NewLine);
                    }
                    catch (Exception ex)
                    {
                        sender.send(ex.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.MajorError("Exception while parsing message or creating implementor instance" + System.Environment.NewLine + ex.ToString());
                Logger.MajorError("Disconnecting client.");
                sender.TermClient();
                curMsg = null;
            }
        }
예제 #24
0
 private void WCDisconnected(WorkerClient sender)
 {
     throw new NotImplementedException();
 }
예제 #25
0
        void clientDisconnected(WorkerClient wc, object data)
        {
            plugins?.Invoke(x => x.OnClientDisconnect(wc.Client, wc.Id));

            unassignWorkFromClient(wc);
        }
예제 #26
0
 void clientRemoved(WorkerClient wc, object data) => unassignWorkFromClient(wc);
예제 #27
0
        /// <summary>
        /// Handles messages received from clients
        /// </summary>
        void ClientMessageReceived(WorkerClient client, NetworkMessage message)
        {
            if (!client.HandshakeCompleted)
            {
                return;
            }

            // do not log status checks because they happen too frequently

            /*
             * if (message.MessageType != NetworkMessageType.StatusCheck)
             *  Logger.Log($"Received message from '{client.Id}' -> {message.MessageType}", Logger.LogSeverity.Debug);
             */

            switch (message.MessageType)
            {
            case NetworkMessageType.StatusCheck:

                #region Handle new Cient Status
                var status = JsonConvert.DeserializeObject <JObject>((string)message.Data);

                var isBusy       = (bool?)status["IsBusy"];
                var hostMode     = (bool?)status["IsHost"];
                var isActive     = (bool?)status["IsActive"];
                var workCount    = (long?)status["WorkCount"];
                var crawledCount = (long?)status["CrawledCount"];

                // update client information
                client.IsBusy       = isBusy ?? client.IsBusy;
                client.IsHost       = hostMode ?? client.IsHost;
                client.IsActive     = isActive ?? client.IsActive;
                client.WorkCount    = workCount ?? client.WorkCount;
                client.CrawledCount = crawledCount ?? client.CrawledCount;
                #endregion

                break;

            case NetworkMessageType.ResultsReady:
                // worker has results ready. Send request to retrieve results.
                client.MesssageHandler.SendMessage(new NetworkMessage(NetworkMessageType.SendResults));

                break;

            case NetworkMessageType.Work:
                // retrieve results from worker

                #region Handle Received Works
                // do not retrieve if work not assigned
                if (client.AssignedUrl != null)
                {
                    var works = (object[])message.Data;
                    Logger.Log($"({client.Id}) - Retrieved {works.Length} results...", Logger.LogSeverity.Debug);

                    var added = 0;

                    // only add to backlog if not yet crawled
                    foreach (var url in works)
                    {
                        var u = (string)url;

                        // do not add if already crawled
                        if (manager.IsUrlCrawled(u))
                        {
                            continue;
                        }

                        // do not add if already in backlog
                        if (manager.IsUrlInBacklog(u))
                        {
                            continue;
                        }

                        // add to backlog
                        manager.AddToBacklog(u);
                        added++;
                    }

                    Logger.Log($"({client.Id}) - Added {added} items to backlog", Logger.LogSeverity.Debug);

                    // unassign work
                    client.AssignedUrl = null;

                    // confirm that all results have been received
                    client.MesssageHandler.SendMessage(
                        new NetworkMessage(NetworkMessageType.ResultsReceived));
                }
                #endregion

                break;

            case NetworkMessageType.CrawledWorks:
                // retrieve crawled items from worker

                #region Handle Receieved Crawled Works

                // do not retrieve if work not assigned
                if (client.AssignedUrl != null)
                {
                    var works = (object[])message.Data;
                    Logger.Log($"({client.Id}) - Retrieved {works.Length} cached crawled items...", Logger.LogSeverity.Debug);

                    // only add to crawled if it doesn't exist yet
                    foreach (var url in works)
                    {
                        var u = (string)url;

                        // do not add if already crawled
                        // if (manager.IsUrlCrawled(u)) continue;
                        // Check is not necessary because database upserts it anyway (will update existing ones automatically)

                        manager.AddToCrawled(u);
                    }
                }
                #endregion

                break;

            case NetworkMessageType.FileTransfer:
                // client wants to initiate file transfer

                #region Initiate File Transfer
                // use semaphore for starting file transfer - we don't want multiple threads creating same file and accessing it
                string destination_path = null;
                string temp_path        = null;

                try
                {
                    var transferInfo = ((Dictionary <object, object>)message.Data)
                                       .Deserialize <FileTransferInfo>();

                    destination_path = TranslateWorkerFilePathToHost(transferInfo.Location, WorkerConfig.DontCreateSubfolders);

                    temp_path = Extensions.GetTempFile(ConfigManager.TemporaryFileTransferDirectory);

                    if (client.TransferringFile)
                    {
                        if (transferInfo.Url == client.TransferringUrl &&
                            transferInfo.Size == client.TransferringFileSize &&
                            transferInfo.Location == client.TransferringFileLocation)
                        {
                            // same file requested, ignore it
                            Logger.Log($"({client.Id}) - New file transfer same as existing one. Ignoring request. ({transferInfo.Location})", Logger.LogSeverity.Debug);
                            break;
                        }

                        // new file transfer is initiated, old one is canceled
                        Logger.Log($"({client.Id}) New file transfer ({transferInfo.Location}) canceled old one. " +
                                   $"({client.TransferringFileLocation})", Logger.LogSeverity.Debug);

                        client.StopTransfer();
                    }

                    transferSemaphore.Wait();
                    // Logger.Log("Starting transfer...");

                    // start transferring file
                    client.TransferringFile = true;
                    client.TransferringFileSizeCompleted = 0;
                    client.TransferringUrl              = transferInfo.Url;
                    client.TransferringFileSize         = transferInfo.Size;
                    client.TransferringFileLocation     = transferInfo.Location;
                    client.TransferringFileLocationHost = destination_path;

                    // create necessary directories and use proper location
                    Directory.CreateDirectory(Path.GetDirectoryName(destination_path));

                    // transfer file to temporary file first and later check MD5 hashes for duplicates
                    client.TransferringFileStream = new FileStream(temp_path,
                                                                   FileMode.Create, FileAccess.ReadWrite);

                    // accept file transfer
                    client.MesssageHandler.SendMessage(
                        new NetworkMessage(NetworkMessageType.FileAccept));
                }
                catch (Exception ex)
                {
                    client.StopTransfer();

                    // make sure file is deleted
                    if (temp_path != null && File.Exists(temp_path))
                    {
                        Logger.Log($"({client.Id}) Deleted canceled file due to file transfer exception.", Logger.LogSeverity.Debug);
                        File.Delete(temp_path);
                    }

                    Logger.Log($"({client.Id}) Failed to accept file! " + ex.GetDetailedMessage(), Logger.LogSeverity.Warning);
                }
                finally
                {
                    transferSemaphore.Release();
                }
                #endregion

                break;

            case NetworkMessageType.FileChunk:
                // client sent a chunk of file

                #region Accept File Chunk
                if (client.TransferringFile == false)
                {
                    // Logger.Log("Client is NOT transferring anything...");
                    // reject file transfer until previous file finishes transferring
                    client.MesssageHandler.SendMessage(
                        new NetworkMessage(NetworkMessageType.FileReject));
                }
                else
                {
                    try
                    {
                        var chunk = ((Dictionary <object, object>)message.Data)
                                    .Deserialize <FileChunk>();

                        // if location doesn't matches, reject it
                        if (client.TransferringFileLocation != chunk.Location)
                        {
                            client.MesssageHandler.SendMessage(
                                new NetworkMessage(NetworkMessageType.FileReject));

                            throw new InvalidOperationException("Invalid file chunk received!");
                        }

                        // write to stream
                        client.TransferringFileStream.Write(chunk.Data, 0, chunk.Size);
                        client.TransferringFileSizeCompleted += chunk.Size;

                        // check if all chunks transferred
                        if (client.TransferringFileSize <= client.TransferringFileSizeCompleted)
                        {
                            try
                            {
                                // close file stream as we don't need it anymore
                                client.TransferringFileStream.Close();

                                // attempt to copy file to destination while checking for duplicates
                                var spath = Extensions.CopyToAndGetPath(
                                    client.TransferringFileStream.Name,
                                    client.TransferringFileLocationHost);

                                // delete old temporary file
                                File.Delete(client.TransferringFileStream.Name);

                                // transfer completed
                                Logger.Log($"({client.Id}) - File transferred ({Path.GetFileName(spath)}).",
                                           Logger.LogSeverity.Debug);

                                // create work and upsert it to Crawled
                                var w = new Work(client.TransferringUrl)
                                {
                                    Transferred      = false,
                                    IsDownloaded     = true,
                                    DownloadLocation = Extensions.GetRelativeFilePath(spath, WorkerConfig)
                                };

                                manager.AddToCrawled(w);
                                RecentDownloads.Add(new DownloadedWork(
                                                        Path.Combine(WorkerConfig.DownloadsPath, w.DownloadLocation),
                                                        client.TransferringFileSize));

                                // mark as done
                                client.TransferringFile = false;

                                client.MesssageHandler.SendMessage(new NetworkMessage(NetworkMessageType.FileTransfer, new FileTransferInfo
                                {
                                    Url      = w.Url,
                                    Size     = -1,
                                    Location = ""
                                }));
                            }
                            catch
                            {
                                // client.MesssageHandler.SendMessage(new NetworkMessage(NetworkMessageType.FileReject));
                            }
                            finally
                            {
                                client.StopTransfer();
                            }
                        }

                        // host accepted file chunk
                        client.MesssageHandler.SendMessage(
                            new NetworkMessage(NetworkMessageType.FileChunkAccept));
                    }
                    catch (Exception ex)
                    {
                        client.StopTransfer();

                        // make sure file is deleted if it exists!
                        if (client.TransferringFileLocationHost != null &&
                            File.Exists(client.TransferringFileLocationHost))
                        {
                            Logger.Log($"({client.Id}) - Deleted canceled file due to chunk transfer exception.", Logger.LogSeverity.Debug);
                            File.Delete(client.TransferringFileLocationHost);
                        }

                        if (!IgnoreError(ex))
                        {
                            Logger.Log($"({client.Id}) - Failed to transfer chunk! " + ex.GetDetailedMessage() + ex.StackTrace, Logger.LogSeverity.Debug);
                        }
                    }
                }
                #endregion

                break;
            }
        }
예제 #28
0
        /// <summary>
        /// Client connected. Establish SSL, do handshake and validate client before accepting it.
        /// </summary>
        /// <param name="r"></param>
        void ClientAccepted(IAsyncResult r)
        {
            // Continue listening
            try
            {
                listener.BeginAcceptTcpClient(ClientAccepted, null);
            }
            catch (Exception ex)
            {
                if (IsListening)
                {
                    Logger.Log($"Failed to continue listening... " + ex.GetDetailedMessage(), Logger.LogSeverity.Debug);
                }
                return;
            }

            // Start accepting client
            var client = listener.EndAcceptTcpClient(r);

            Logger.Log($"Client connecting from {client.Client.RemoteEndPoint}...", Logger.LogSeverity.Debug);

            if (plugins?.Invoke(p => p.OnClientConnecting(client), true) == false)
            {
                // reject client
                Logger.Log("Client rejected by plugin.", Logger.LogSeverity.Debug);
                client.ProperlyClose();
                return;
            }

            // Create client object
            var wc = new WorkerClient(client);

            // Start handshake
            try
            {
                var stream = client.GetStream();

                Logger.Log($"Establishing secure connection to {client.Client.RemoteEndPoint}...", Logger.LogSeverity.Debug);
                // setup SSL here
                var sslstream = SecurityUtils.ServerEstablishSSL(stream, certificate);

                wc.MesssageHandler = new NetworkMessageHandler <NetworkMessage>(sslstream, m => ClientMessageReceived(wc, m));
                wc.MesssageHandler.ExceptionThrown += (a, b) =>
                {
                    wc.MesssageHandler.Dispose();

                    if (wc.Online)
                    {
                        wc.Online = false;
                        ClientLeft?.Invoke(wc, null);

                        Logger.Log($"Client disconnected from {wc.RemoteEndpoint}! ({wc.Id})");

                        // ignore certain common errors
                        if (!IgnoreError(b))
                        {
                            Logger.Log(b.GetDetailedMessage(), Logger.LogSeverity.Debug);
                        }
                    }
                };

                Logger.Log($"Validating {client.Client.RemoteEndPoint}...", Logger.LogSeverity.Debug);

                wc.Id = SecurityUtils.DoHandshake(wc.MesssageHandler, passwordHash, false, null,
                                                  id => Clients.Count(x => x.Id == id) > 0,
                                                  id =>
                {
                    var c = Clients.Where(x => x.Id == id).FirstOrDefault();
                    if (c == null)
                    {
                        return(false);               // generate new Id if client doesn't exist
                    }
                    if (c.Online == true)
                    {
                        return(false);                      // worker already online with this Id, generate new Id
                    }
                    // worker with this Id is offline, assume this is that worker
                    return(true);
                });

                wc.HandshakeCompleted = true;
            }
            catch (Exception ex)
            {
                Logger.Log($"Rejected client from {wc.RemoteEndpoint}. " + ex.Message, Logger.LogSeverity.Warning);
                Logger.Log(ex.GetDetailedMessage(), Logger.LogSeverity.Debug);

                try
                {
                    wc.MesssageHandler.SendMessage(new NetworkMessage(NetworkMessageType.Reject));
                }
                catch { }

                client.ProperlyClose();
                return;
            }

            wc.Online        = true;
            wc.LastConnected = DateTime.Now;

            // try get existing client
            var ewc = Clients.Where(x => x.Id == wc.Id).FirstOrDefault();

            // Accept valid client
            Logger.Log($"Accepted {(ewc == null ? "new" : "existing")} client from {client.Client.RemoteEndPoint}. ({wc.Id})");
            lock (Clients)
            {
                // if client doesn't exist yet, add it - otherwise replace existing client
                if (ewc == null)
                {
                    Clients.Add(wc);
                }
                else
                {
                    var index = Clients.IndexOf(ewc);

                    Clients[index] = wc;
                }
            }

            plugins?.Invoke(p => p.OnClientConnect(wc.Client, wc.Id));

            // send configuration
            wc.MesssageHandler.SendMessage(new NetworkMessage(NetworkMessageType.ConfigUpdate, WorkerConfig));

            // send client limit
            wc.MesssageHandler.SendMessage(new NetworkMessage(
                                               NetworkMessageType.WorkLimitUpdate, config.ClientWorkLimit));

            ClientJoined?.Invoke(wc, ewc != null);
        }
예제 #29
0
 public WorkerHub(WorkerClient workerClient)
 {
     _workerClient = workerClient;
 }
예제 #30
0
            public Task <RpcCallResult <Unit> > AttachAsync()
            {
                var buildStartData = GrpcMockData.BuildStartData;

                return(WorkerClient.AttachAsync(buildStartData.ToOpenBond(), CancellationToken.None));
            }
예제 #31
0
 public void Create(out IWorkerClient @object, IClientLink link) => @object = new WorkerClient(link);