Pregunta

I have two projects: 1 is a WCF web service and 1 is a Windows Service.

In the global of my web service I call a method which will send a email to me when I start the web service.

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

In my Windows Service I check every 5 minutes if the web service is online. If not I send a email.

    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)
        {
             ...
        }
    }

But when the web service is online and I start the Windows Service then the code var myRequest = (HttpWebRequest)WebRequest.Create(_url); makes a new instance of the web service. And when var response = (HttpWebResponse)myRequest.GetResponse(); is called, I get a new email. (This happens only the first time when the timer is elapsed) But I don't want that. I only want to know if the web service is still alive or not.

Is there a solution for this problem?

EDIT: For the complete code to check if multiple webservices are online: See my answer!

¿Fue útil?

Solución

The webservice isn't actually started before a request is made hence you get the email when the watchdog makes the request. See ASP.NET Page Life Cycle.

The solution I'd go for is to NOT have the webservice email when it starts but instead have the watchdog email when the status of the webservice changes.

Otros consejos

I have made a very good solution with help from @Sani Huttunen

In my Windows Service:

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;
    }
}

And in the 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>

The two webservices named in the app.config file will go to the _webservicesList when I start the Windows Service.

If I make a new webservice then I only have to do is add one row in the app.config. And every 5 minutes the Windows Service will check every webservice if it is still online.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top