简体   繁体   English

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

[英]Using Web API for a Windows Service to Receive Commands and Perform Tasks via Polling?

I have a project where I need to create a windows service that, when instructed via a command, will perform various tasks. 我有一个项目,我需要在其中创建一个Windows服务,该服务在通过命令指示时将执行各种任务。 This server would run on multiple servers and would effectively perform the same kind of tasks when requested. 该服务器将在多台服务器上运行,并在请求时有效执行相同类型的任务。

For example, I would like to have a Web API service that listens for requests from the servers. 例如,我想要一个Web API服务,该服务侦听来自服务器的请求。

The service running on the server would send a query to Web API every 25 secs or so and pass to it its SERVERNAME. 在服务器上运行的服务将每25秒左右向Web API发送一次查询,并将其SERVERNAME传递给它。 The Web API logic will then look up the SERVERNAME and look for any status updates for various tasks... IE, if a status for a DELETE command is a 1, the service would delete the folder containing log files... if a status for a ZIP command is a 1, the service would zip the folder containing log files and FTP them to a centralized location. 然后,Web API逻辑将查找SERVERNAME并查找各种任务的任何状态更新... IE,如果DELETE命令的状态为1,则服务将删除包含日志文件的文件夹...如果状态为如果ZIP命令为1,则服务会将包含日志文件的文件夹压缩并通过FTP将其传输到集中位置。

This concept seems simple enough, and I think I need a nudge to tell me if this sounds like a good design. 这个概念似乎很简单,我想我需要轻声告诉我这听起来像是一个好的设计。 I'm thinking of using .NET 4.5 for the Windows Service, so that I can use the HttpClient object and, of course, .NET 4.5 for the Web API/MVC project. 我正在考虑为Windows服务使用.NET 4.5,以便可以将HttpClient对象以及Web应用程序API / MVC项目使用.NET 4.5。

Can someone please get me started on what a basic Web API woudld look like provide status updates to the Windows services that are running and issue commands to them... 有人可以帮助我开始介绍基本的Web API外观,为正在运行的Windows服务提供状态更新并向其发出命令...

I'm thinking of having a simple MVC website that folks will have a list of servers (maybe based on a simple XML file or something) that they can click various radio buttons to turn on "DELETE", "ZIP" or whatever, to trigger the task on the service. 我正在考虑建立一个简单的MVC网站,人们将拥有一个服务器列表(可能基于简单的XML文件或类似的东西),他们可以单击各种单选按钮以打开“删除”,“邮政编码”或其他任何内容。触发服务上的任务。

I do something similar. 我做类似的事情。 I have a main Web API (a Windows Service) that drives my application and has a resource called /Heartbeat . 我有一个主要的Web API(Windows服务),该API驱动我的应用程序,并具有一个名为/Heartbeat的资源。

I also have a second Windows Service that has a timer fire every 30 seconds. 我还有第二个Windows服务,该服务每30秒触发一次计时器。 Each time the timer fires it calls POST /heartbeat . 每次计时器触发时,它都会调用POST /heartbeat When the heartbeat request is handled, it goes looking for tasks that have been scheduled. 处理心跳请求后,它将查找已安排的任务。

The advantage of this approach is that the service makes the hearbeat request is extremely simple and never has to be updated. 这种方法的优点是该服务使监听信号请求非常简单,并且不必更新。 All the logic relating to what happens on a heartbeat is in the main service. 与心跳发生的事情有关的所有逻辑都在主服务中。

The guts of the service are this. 服务的胆量是这个。 It's old code so it is still using HttpWebRequest instead of HttpClient, but that's trivial to change. 它是旧代码,因此仍在使用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);
            }

        }


    }

You can do it with ServiceController.ExecuteCommand() method from .NET. 您可以使用.NET中的ServiceController.ExecuteCommand()方法来实现。 With the method you can sand custom command to windows' service. 使用该方法,您可以将自定义命令打入Windows服务。 Then in your service you need to implement ServiceBase.OnCustomCommand() to serve incomming custom command event in service. 然后,在您的服务中,您需要实现ServiceBase.OnCustomCommand()来在服务中提供传入的自定义命令事件。

const int SmartRestart = 8;

...

//APPLICATION TO SEND COMMAND
service.ExecuteCommand(SmartRestart);

...

//SERVICE
protected override void OnCustomCommand(int command)
{
    if (command == SmartRestart)
    {
        // ...
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM