2

我有一个项目,我需要创建一个 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”或其他任何东西,以触发服务上的任务。

4

2 回答 2

1

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

我还有第二个 Windows 服务,它每 30 秒触发一次计时器。每次计时器触发时,它都会调用 POST /heartbeat。当心跳请求被处理时,它会去寻找已经安排好的任务。

这种方法的优点是服务使 heartbeat 请求非常简单,并且永远不必更新。所有与心跳相关的逻辑都在主服务中。

服务的胆量是这样的。这是旧代码,所以它仍然使用 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);
            }

        }


    }
于 2013-02-16T02:07:47.960 回答
0

您可以使用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)
    {
        // ...
    }
}
于 2015-04-27T13:00:14.683 回答