I’ve an application running on FEZ Cobra II (G120) and it seems that HttpListener doesn’t work correctly as expected.
void TcpThreadManager()
{
HttpListener listener = null;
Debug.Print("HttpListener starting ...");
HttpListenerContext wctx = null;
HttpListenerRequest req;
//Program.LCD_Disp.PrintString(2, 0, "HttpListener started ...");
Thread.Sleep(200);
while (true)
{
// wait for call from client:
try
{
if (listener == null)
{
listener = new HttpListener("http", 80);
listener.MaximumResponseHeadersLength = 8192;
}
listener.Start(); // Why I need to Start() each loop ?
Debug.Print("HttpListener started ....");
wctx = listener.GetContext();
// got call:
if (wctx == null )
continue;
req = wctx.Request;
Debug.Print("->wctx remote addr: " + req.RemoteEndPoint.Address.ToString());
wctx.Response.ContentType = "text/plain";
wctx.Response.SendChunked = false;
Debug.Print("URL: " + wctx.Request.RawUrl);
}
catch (SocketException sex)
{
Debug.Print("HttpListener stopped and cleared ... thread end ! ->" + sex.Message );
if (listener != null)
{
listener.Stop();
listener.Close();
Thread.Sleep(300);
listener = null;
}
continue;
}
// Process request
//ProcessHttpRequest(wctx); // multi threaded version
HttpContextServiceThread(wctx); // single thread version service routine
//listener.Stop(); <- get exception if I call Stop() (SocketException)
}
}
As you can see in the code, If I don’t call HttpListener.Start() after every service requested, the underlying socket crash after a while (may be till 10hours) and no way to recreate again the listener. If I call HttpListener.Stop() I get an exception, but Start() still work and listner comes up again correctly.
The code above works correctly and create no problem, although I think this is not the correct way to use HttpListner. On the MS framewk it’s not needed to close/open each service request.
The service request are like this:
void HttpContextServiceThread(HttpListenerContext wctx)
{
Queue qTx, qRx;
qTx = Program.qSmsTx;
qRx = Program.qSmsRx;
string _resp;
HttpListenerRequest wreq = wctx.Request;
string[] s = wreq.RawUrl.Trim().Split(new char[] { '?' });
switch(s[0])
{
case "/":
case "/test":
string ONLINE = "ONLINE";
wctx.Response.OutputStream.Write(Encoding.UTF8.GetBytes(ONLINE), 0, ONLINE.Length );
wctx.Response.Close();
break;
case "/sms":
if (wctx.Request.HttpMethod == "POST")
{
//Program.GoSendSms = false;
// Get post messages
GetHttpPostSms(qRx, wctx.Request);
}
SendHttpResponse(qTx, wctx.Response);
Program.GoSendSms = true;
break;
case "/status":
//DebugPrintHeaders(wctx);
if (wctx.Request.Headers["ServerDateTime"] != null)
{
string svrdate = wctx.Request.Headers["ServerDateTime"];
DateTime t = ParseInitDate(svrdate);
GHI.Premium.Hardware.RealTimeClock.SetTime(t);
Microsoft.SPOT.Hardware.Utility.SetLocalTime(t);
}
SendHttpInfoResponse(qRx.Count, qTx.Count, wctx.Response);
break;
...
//.... here there are other case...
...
default:
wctx.Response.OutputStream.Write(new byte[] { 49 }, 0, 1);
wctx.Response.OutputStream.Close();
wctx.Response.Close();
break;
}
}
May be I’m doing something wrong …
???