使用Web API为Windows服务接收命令并通过轮询执行任务

本文关键字:执行任务 命令 API Web Windows 服务 使用 | 更新日期: 2023-09-27 17:59:47

我有一个项目,需要创建一个windows服务,当通过命令发出指令时,该服务将执行各种任务。该服务器将在多个服务器上运行,并在请求时有效地执行相同类型的任务。

例如,我希望有一个Web API服务来侦听来自服务器的请求。

在服务器上运行的服务将每隔25秒左右向Web API发送一个查询,并将其SERVERNAME传递给它。然后Web API逻辑将查找SERVERNAME并查找各种任务的任何状态更新。。。即,如果DELETE命令的状态为1,则该服务将删除包含日志文件的文件夹。。。如果ZIP命令的状态为1,则服务将压缩包含日志文件的文件夹,并将其FTP到集中位置。

这个概念看起来很简单,我想我需要一个提示来告诉我这听起来是否是一个好的设计。我正在考虑使用。NET 4.5用于Windows服务,这样我就可以使用HttpClient对象,当然还有。NET 4.5用于Web API/MVC项目。

有人能让我开始了解一个基本的Web API是什么样子的吗?它为正在运行的Windows服务提供状态更新并向它们发出命令。。。

我正在考虑建立一个简单的MVC网站,人们会有一个服务器列表(可能基于简单的XML文件或其他什么),他们可以点击各种单选按钮打开"DELETE"、"ZIP"或其他什么,以触发服务上的任务。

使用Web API为Windows服务接收命令并通过轮询执行任务

我做了类似的事情。我有一个主要的Web API(一个Windows服务),它驱动我的应用程序,并有一个名为/Heartbeat的资源。

我还有第二个Windows服务,它的计时器每30秒启动一次。每次定时器触发时,它都会调用POST /heartbeat。当处理心跳请求时,它会查找已调度的任务。

这种方法的优点是,该服务使hearbeat请求非常简单,而且永远不需要更新。与心跳发生的事情相关的所有逻辑都在主服务中。

服务的精髓在于此。这是旧代码,所以它仍然使用HttpWebRequest而不是HttpClient,但更改起来很简单。

 public partial class HeartbeatService : ServiceBase {
        readonly Timer _Timer = new System.Timers.Timer();
        private string _heartbeatTarget;

        public HeartbeatService() {
            Trace.TraceInformation("Initializing Heartbeat Service");
            InitializeComponent();
            this.ServiceName = "TavisHeartbeat";
        }
        protected override void OnStart(string[] args) {
            Trace.TraceInformation("Starting...");
            _Timer.Enabled = true;
            _Timer.Interval = Properties.Settings.Default.IntervalMinutes * 1000 * 60; 
            _Timer.Elapsed += new ElapsedEventHandler(_Timer_Elapsed);
            _heartbeatTarget = Properties.Settings.Default.TargetUrl; 
        }
        protected override void OnStop() {
            _Timer.Enabled = false;
        }
        private void _Timer_Elapsed(object sender, ElapsedEventArgs e) {
            Trace.TraceInformation("Heartbeat event triggered");
            try {
                var httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(_heartbeatTarget);
                httpWebRequest.ContentLength = 0;
                httpWebRequest.Method = "POST";
                var response = (HttpWebResponse)httpWebRequest.GetResponse();
                Trace.TraceInformation("Http Response : " + response.StatusCode + " " + response.StatusDescription); 
            } catch (Exception ex) {
                string errorMessage = ex.Message;
                while (ex.InnerException != null) {
                    errorMessage = errorMessage + Environment.NewLine + ex.InnerException.Message;
                    ex = ex.InnerException;
                }
                Trace.TraceError(errorMessage);
            }
        }

    }

您可以从中使用ServiceController.ExecuteCommand()方法来完成此操作。NET。使用该方法,您可以将自定义命令发送到windows的服务。然后,在您的服务中,您需要实现ServiceBase.OnCustomCommand()来在服务中提供单独的自定义命令事件。

const int SmartRestart = 8;
...
//APPLICATION TO SEND COMMAND
service.ExecuteCommand(SmartRestart);
...
//SERVICE
protected override void OnCustomCommand(int command)
{
    if (command == SmartRestart)
    {
        // ...
    }
}