检查Web服务是否在线,但不要创建实例

时间:2014-05-07 14:28:15

标签: c# web-services wcf windows-services

我有两个项目:1是WCF Web服务,1是Windows服务。

在我的网络服务的全局中,我调用了一种方法,当我启动网络服务时,该方法会向我发送电子邮件。

    protected void Application_Start(object sender, EventArgs e)
    {
        MailService mailService = new MailService();
        mailService.SendConfirmationMail();
    }

在我的Windows服务中,如果网络服务在线,我每5分钟检查一次。如果没有,我发送电子邮件。

    public void CheckWebserviceTimer()
    {
        _timer = new Timer(300000);
        _timer.Elapsed += _timer_Elapsed;
        _timer.Enabled = true;
    }

    private void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        var myRequest = (HttpWebRequest)WebRequest.Create(_url);
        var response = (HttpWebResponse)myRequest.GetResponse();

        if (response.StatusCode != HttpStatusCode.OK)
        {
             ...
        }
    }

但是当Web服务联机并启动Windows服务时,代码var myRequest = (HttpWebRequest)WebRequest.Create(_url);将创建Web服务的新实例。当var response = (HttpWebResponse)myRequest.GetResponse();被调用时,我会收到一封新电子邮件。 (这只是在计时器结束时第一次发生)但我不想要这样。我只想知道Web服务是否还活着。

这个问题有解决方案吗?

修改 有关检查多个Web服务是否在线的完整代码:请参阅我的答案!

2 个答案:

答案 0 :(得分:2)

在发出请求之前,网络服务实际上并未启动,因此您会在看门狗发出请求时收到电子邮件。请参阅ASP.NET Page Life Cycle

我要求的解决方案是在启动时没有网络服务电子邮件,而是在网络服务状态发生变化时收到监视程序电子邮件。

答案 1 :(得分:0)

我在@Sani Huttunen的帮助下做了一个非常好的解决方案

在我的Windows服务中:

public partial class NotificationStarter : ServiceBase
{
    protected override void OnStart(string[] args)
    {
        WebserviceController webserviceController = new WebserviceController();
        webserviceController.FillWebservicesList();
        webserviceController.CheckWebserviceTimer();
    }
}


public class WebserviceController : ConfigurationSection
{
    private List<WebserviceConfig> _webservicesList; 

    [ConfigurationProperty("Webservices", IsDefaultCollection = false)]
    [ConfigurationCollection(typeof(WebservicesCollection),
        AddItemName = "add",
        ClearItemsName = "clear",
        RemoveItemName = "remove")]
    public WebservicesCollection Webservices
    {
        get { return (WebservicesCollection)base["Webservices"]; }
    }

    public void FillWebservicesList()
    {
        WebserviceController contoller = ConfigurationManager.GetSection("WebservicesSection") as WebserviceController;

        if (contoller != null) 
            _webservicesList = contoller.Webservices.Cast<WebserviceConfig>().ToList();
    }

    public void CheckWebserviceTimer()
    {
        _timer = new Timer(300000);
        _timer.Elapsed += _timer_Elapsed;
        _timer.Enabled = true;
    }

    private void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        foreach (var webservice in _webservicesList)
        {
            try
            {
                var myRequest = (HttpWebRequest) WebRequest.Create(webservice.Value);
                var response = (HttpWebResponse) myRequest.GetResponse();

                if (response.StatusCode != HttpStatusCode.OK && webservice.IsOnline)
                {
                    ...
                    webservice.IsOnline = false;
                }
                else
                {
                    webservice.IsOnline = true;
                }
            }
        }
    }
}


public class WebservicesCollection : ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement()
    {
        return new WebserviceConfig();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((WebserviceConfig) element);
    }
}


public class WebserviceConfig : ConfigurationElement
{
    public WebserviceConfig()
    {
    }

    public WebserviceConfig(string name, string value, bool isOnline)
    {
        Name = name;
        Value = value;
        IsOnline = isOnline;
    }

    [ConfigurationProperty("name", DefaultValue = "", IsRequired = true, IsKey = false)]
    public string Name
    {
        get { return (string) this["name"]; }
        set { this["name"] = value; }
    }

    [ConfigurationProperty("value", DefaultValue = "", IsRequired = true, IsKey = false)]
    public string Value
    {
        get { return (string) this["value"]; }
        set { this["value"] = value; }
    }

    [ConfigurationProperty("isOnline", IsRequired = true, IsKey = false)]
    public bool IsOnline
    {
        get { return (bool) this["isOnline"]; }
        set { this["isOnline"] = value; }
    }

    public override bool IsReadOnly()
    {
        return false;
    }
}

在app.config中:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="WebservicesSection" type="NotificationDispatcher.WebserviceController, NotificationDispatcher"/>
  </configSections>
  <WebservicesSection>
    <Webservices>
      <add name="Webservice1" value="http://localhost:1234/Webservice1.svc?wsdl" isOnline="false" />
      <add name="Webservice2" value="http://localhost:4567/Webservice2.svc?wsdl" isOnline="false" />
    </Webservices>
  </WebservicesSection>
</configuration>

当我启动Windows服务时,app.config文件中指定的两个web服务将转到_webservicesList

如果我创建一个新的Web服务,那么我只需要在app.config中添加一行。每隔5分钟,Windows服务就会检查每个Web服务是否还在线。