Exemplo n.º 1
0
        static async Task Main(string[] args)
        {
            // Get an optional filter string
            string filter;

            if (args.Length > 0 && args[0] != "-")
            {
                filter = args[0];
            }
            else
            {
                Console.WriteLine("Please enter a filter expression or press RETURN to receive partial model updates:");
                filter = Console.ReadLine().Trim();
            }

            // Connect to DCS
            using SubscribeConnection connection = new SubscribeConnection();
            if (args.Length < 2)
            {
                await connection.Connect(SubscriptionMode.Patch, filter);
            }
            else
            {
                await connection.Connect(SubscriptionMode.Patch, filter, args[1]);
            }
            Console.WriteLine("Connected!");

            // In Patch mode the whole object model is sent over after connecting. Dump it (or call connection.GetMachineModel() to deserialize it)
            _ = await connection.GetSerializedMachineModel();

            // Then keep listening for (filtered) patches
            while (connection.IsConnected)
            {
                using JsonDocument patch = await connection.GetMachineModelPatch();

                if (patch == null)
                {
                    break;
                }
                Console.WriteLine(GetIndentedJson(patch));
            }
        }
Exemplo n.º 2
0
        private static async Task Main(string[] args)
        {
            // Parse the command line arguments
            string lastArg = null, socketPath = Defaults.FullSocketPath, filter = null;
            bool   quiet = false;

            foreach (string arg in args)
            {
                if (lastArg == "-s" || lastArg == "--socket")
                {
                    socketPath = arg;
                }
                else if (lastArg == "-f" || lastArg == "--filter")
                {
                    filter = arg;
                }
                else if (arg == "-q" || arg == "--quiet")
                {
                    quiet = true;
                }
                else if (arg == "-h" || arg == "--help")
                {
                    Console.WriteLine("Available command line arguments:");
                    Console.WriteLine("-s, --socket <socket>: UNIX socket to connect to");
                    Console.WriteLine("-f, --filter <filter>: UNIX socket to connect to");
                    Console.WriteLine("-q, --quiet: Do not display when a connection has been established");
                    Console.WriteLine("-h, --help: Display this help text");
                    return;
                }
                lastArg = arg;
            }

            // Get an optional filter string
            if (string.IsNullOrWhiteSpace(filter))
            {
                Console.WriteLine("Please enter a filter expression or press RETURN to receive partial model updates:");
                filter = Console.ReadLine().Trim();
            }

            // Connect to DCS
            using SubscribeConnection connection = new SubscribeConnection();
            await connection.Connect(SubscriptionMode.Patch, filter, socketPath);

            if (!quiet)
            {
                Console.WriteLine("Connected!");
            }

            // In Patch mode the whole object model is sent over after connecting.
            // Dump it (or call connection.GetMachineModel() to deserialize it)
            _ = await connection.GetSerializedMachineModel();

            // Then keep listening for (filtered) patches
            do
            {
                try
                {
                    using JsonDocument patch = await connection.GetMachineModelPatch();

                    Console.WriteLine(GetIndentedJson(patch));
                }
                catch (SocketException)
                {
                    if (!quiet)
                    {
                        Console.WriteLine("Server has closed the connection");
                    }
                    break;
                }
            }while (true);
        }
        /// <summary>
        /// Synchronize all registered endpoints and user sessions
        /// </summary>
        public async Task Execute()
        {
            string unixSocket = _configuration.GetValue("SocketPath", DuetAPI.Connection.Defaults.FullSocketPath);
            int    retryDelay = _configuration.GetValue("ModelRetryDelay", 5000);

            MachineModel model;

            try
            {
                do
                {
                    try
                    {
                        // Establish connections to DCS
                        using SubscribeConnection subscribeConnection = new SubscribeConnection();
                        using CommandConnection commandConnection     = new CommandConnection();
                        await subscribeConnection.Connect(DuetAPI.Connection.SubscriptionMode.Patch, "directories/www|httpEndpoints/**|userSessions/**", unixSocket);

                        await commandConnection.Connect(unixSocket);

                        _logger.LogInformation("Connections to DuetControlServer established");

                        // Get the machine model and keep it up-to-date
                        model = await subscribeConnection.GetMachineModel(_stopRequest.Token);

                        lock (Endpoints)
                        {
                            foreach (HttpEndpoint ep in model.HttpEndpoints)
                            {
                                string fullPath = $"{ep.EndpointType}/machine/{ep.Namespace}/{ep.Path}";
                                Endpoints[fullPath] = ep;
                                _logger.LogInformation("Registered HTTP {0} endpoint via /machine/{1}/{2}", ep.EndpointType, ep.Namespace, ep.Path);
                            }
                        }

                        // Keep track of the web directory
                        _commandConnection = commandConnection;
                        model.Directories.PropertyChanged += Directories_PropertyChanged;
                        string wwwDirectory = await commandConnection.ResolvePath(model.Directories.WWW);

                        OnWebDirectoryChanged?.Invoke(wwwDirectory);

                        do
                        {
                            // Wait for more updates
                            using JsonDocument jsonPatch = await subscribeConnection.GetMachineModelPatch(_stopRequest.Token);

                            DuetAPI.Utility.JsonPatch.Patch(model, jsonPatch);

                            // Check if the HTTP sessions have changed and rebuild them on demand
                            if (jsonPatch.RootElement.TryGetProperty("httpEndpoints", out _))
                            {
                                _logger.LogInformation("New number of custom HTTP endpoints: {0}", model.HttpEndpoints.Count);


                                lock (Endpoints)
                                {
                                    Endpoints.Clear();
                                    foreach (HttpEndpoint ep in model.HttpEndpoints)
                                    {
                                        string fullPath = $"{ep.EndpointType}/machine/{ep.Namespace}/{ep.Path}";
                                        Endpoints[fullPath] = ep;
                                        _logger.LogInformation("Registered HTTP {0} endpoint via /machine/{1}/{2}", ep.EndpointType, ep.Namespace, ep.Path);
                                    }
                                }
                            }

                            // Rebuild the list of user sessions on demand
                            if (jsonPatch.RootElement.TryGetProperty("userSessions", out _))
                            {
                                lock (UserSessions)
                                {
                                    UserSessions.Clear();
                                    foreach (UserSession session in model.UserSessions)
                                    {
                                        UserSessions[session.Origin] = session.Id;
                                    }
                                }
                            }
                        }while (!!_stopRequest.IsCancellationRequested);
                    }
                    catch (Exception e) when(!(e is OperationCanceledException))
                    {
                        _logger.LogWarning(e, "Failed to synchronize machine model");
                        await Task.Delay(retryDelay, _stopRequest.Token);
                    }
                }while (!_stopRequest.IsCancellationRequested);
            }
            catch (Exception e)
            {
                if (!(e is OperationCanceledException))
                {
                    _logger.LogError(e, "Failed to synchronize object model");
                }
            }
        }