Jivex5k
Jivex5k

Reputation: 121

Sending the server time as a response to HTTP GET via c# service

Alright, I think I have it working 100% now! Here's the code, any critique is welcome, this was my first attempt at c#, coming from a mostly JS background. Ended up using thread.abort, not sure if that is the best way to end this. I put in a _shouldStop bool as well.

public partial class TimeReporterService : ServiceBase
{
    private Thread worker = null;
    private bool _shouldStop = false;

    public TimeReporterService()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        _shouldStop = false;
        worker = new Thread(SimpleListenerExample);
        worker.Name = "Time Reporter";
        worker.IsBackground = false;
        worker.Start();
    }

    protected override void OnStop()
    {
        _shouldStop = true;
        worker.Abort();
    }

    void SimpleListenerExample()
    {
        string[] prefixes = new[] { "http://*:12227/" };
        // URI prefixes are required, 
        // for example "http://contoso.com:8080/index/".
        if (prefixes == null || prefixes.Length == 0)
            throw new ArgumentException("prefixes");

        // Create a listener.
        HttpListener listener = new HttpListener();
        // Add the prefixes. 
        foreach (string s in prefixes)
        {
            listener.Prefixes.Add(s);
        }
        listener.Start();
        while (!_shouldStop)
        {
            // Note: The GetContext method blocks while waiting for a request. 
            HttpListenerContext context = listener.GetContext();
            HttpListenerRequest request = context.Request;
            // Obtain a response object.
            HttpListenerResponse response = context.Response;
            // Construct a response. 
            string responseString = "{\"systemtime\":\"" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\"}";
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
            // Get a response stream and write the response to it.
            response.ContentLength64 = buffer.Length;
            System.IO.Stream output = response.OutputStream;
            output.Write(buffer, 0, buffer.Length);
            output.Close();
        }
        listener.Stop();
    }
}

Upvotes: 0

Views: 2656

Answers (1)

Diego C Nascimento
Diego C Nascimento

Reputation: 2801

Something you could use in the HTTPListener request method.

public void HttpListenerCallback(IAsyncResult result)
{
    HttpListener listener = (HttpListener)result.AsyncState;
    HttpListenerContext context = listener.EndGetContext(result);
    HttpListenerResponse Response = context.Response;

    String dateAsString = DateTime.Now.ToString(@"MM\/dd\/yyyy h\:mm tt");

    byte[] bOutput = System.Text.Encoding.UTF8.GetBytes(dateAsString);
    Response.ContentType = "text/plain";
    Response.ContentLength64 = bOutput.Length;

    Stream OutputStream = Response.OutputStream;
    OutputStream.Write(bOutput, 0, bOutput.Length);
    OutputStream.Close();
}

For this you should use HTTPListener in asynchronous (non-blocking) mode. Ex:

public void NonblockingListener()
{
    HttpListener listener = new HttpListener();
    listener.Prefixes.Add("http://*:8081/");
    listener.Start();
    IAsyncResult result = listener.BeginGetContext(
        new AsyncCallback(HttpListenerCallback), listener);
    Console.WriteLine("Waiting for request to be processed asyncronously.");
    result.AsyncWaitHandle.WaitOne(); //just needed to don't close this thread, you can do other work or run in a loop
    Console.WriteLine("Request processed asyncronously.");
    listener.Close();
}

More info: http://msdn.microsoft.com/en-us//library/system.net.httplistener.aspx

Upvotes: 1

Related Questions