Big perfornance problem with HTTP requests

M

Mike Davies

Hi,

I'm developing an APP which pushed web content to various devices on a
LAN (these devices happen to be IP phones).

I need to broadcast a HTTP message to maybe 100 phones at a time but
this is really slow. I've tried different things but not sure what the
right way to go is. First way is to push the message to the phone but
this takes anywhere from 500ms to 1000ms to complete. Incidentally,
I'm not interested in the repsonse from the phone.

The other way I tried was to wait for the response asynchronously but
that didn't seem to work and was still quite slow at around 100ms.

I can't figure out how to push a message to all phones simultaenously
while ignoreing the repsonse. Can anyone point me in the right
direction.

Just to reiterate, I'm not interested in the response even though the
code below checks for a response. This is just because druing testing
I wanted to know if the phone received it or not. My problem is how do
I send a HTTP request to 100 phones at the same time and ignore the
response.

Cheers,


Mike



try
{
/
//Build URL to post execute command to
string pushUrl = "http://" + strDeviceIP +
"/CGI/Execute";

//The Following Creates the WebClient Object
System.Net.HttpWebRequest web =
(System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(pushUrl);
web.ProtocolVersion =
System.Net.HttpVersion.Version10;
web.KeepAlive = false;
web.Credentials = new
System.Net.NetworkCredential(strUsername, strPassword);
web.ContentType =
"application/x-www-form-urlencoded";
web.AllowAutoRedirect = true;
web.MaximumAutomaticRedirections = 5;
web.Method = "POST";
//web.Timeout = 1;

string pushxml =
"<CiscoIPPhoneExecute><ExecuteItem Priority=\"0\" URL=\"" + strURI +
"\"/></CiscoIPPhoneExecute>";
pushxml = "XML=" + HttpUtility.UrlEncode(pushxml);

//PostData is then declared as data type Byte and
populated with the post data
byte[] PostData =
System.Text.ASCIIEncoding.ASCII.GetBytes(pushxml);

//Send POST data (XML)
web.ContentLength = PostData.Length;

Stream dataStream = web.GetRequestStream();
dataStream.Write(PostData, 0, PostData.Length);
dataStream.Flush();
dataStream.Close();

//Send request
System.Net.HttpWebResponse wResponse =
(System.Net.HttpWebResponse)web.GetResponse();
//IAsyncResult r =
(IAsyncResult)web.BeginGetResponse(null, null);
//return IPPhoneReponse.Success;
//System.Net.HttpWebResponse wResponse =
(System.Net.HttpWebResponse)web.BeginGetResponse(null, null);

//Convert to XmlNode
XmlDocument doc = new XmlDocument();
doc.Load(wResponse.GetResponseStream());

//Handle Response
switch (doc.DocumentElement.Name)
{
case "CiscoIPPhoneResponse":
switch
(doc.SelectSingleNode("/CiscoIPPhoneResponse/ResponseItem").Attributes.GetNamedItem("Data").Value)
{
case "Success":
return IPPhoneReponse.Success;
case "":
return IPPhoneReponse.Success;
case "Failure":
return IPPhoneReponse.Failure;
default:
return IPPhoneReponse.Failure;
}
case "CiscoIPPhoneError":
if
(doc.SelectSingleNode("/CiscoIPPhoneError").Attributes.GetNamedItem("Number").Value
== "4")
{
return IPPhoneReponse.AccessDenied;
}
else
{
return IPPhoneReponse.Failure;
}
default:
return IPPhoneReponse.Failure;
}
}

catch (Exception e)
{
if (e.Message.IndexOf("timed-out") > 0)
{
return IPPhoneReponse.TimeOut;
}
if (e.Message.IndexOf("connect") > 0)
{
Debug.WriteLine(e.Message);
return IPPhoneReponse.TimeOut;
}
else
{
return IPPhoneReponse.Failure;
}
}
 
J

jeremiah johnson

You could use threading to talk to more than one phone at once (this
will speed things up GREATLY).

Google a bit for "ThreadPool.QueueUserWorkItem"

You could maybe also send your HTTP request to the subnet broadcast
address, which would address every network node on that subnet
simultaneously. You wouldn't be able to listen for responses, but it
might suit your needs. Talk to your friendly neighborhood networking
person for more about that.

jeremiah();


Mike said:
Hi,

I'm developing an APP which pushed web content to various devices on a
LAN (these devices happen to be IP phones).

I need to broadcast a HTTP message to maybe 100 phones at a time but
this is really slow. I've tried different things but not sure what the
right way to go is. First way is to push the message to the phone but
this takes anywhere from 500ms to 1000ms to complete. Incidentally,
I'm not interested in the repsonse from the phone.

The other way I tried was to wait for the response asynchronously but
that didn't seem to work and was still quite slow at around 100ms.

I can't figure out how to push a message to all phones simultaenously
while ignoreing the repsonse. Can anyone point me in the right
direction.

Just to reiterate, I'm not interested in the response even though the
code below checks for a response. This is just because druing testing
I wanted to know if the phone received it or not. My problem is how do
I send a HTTP request to 100 phones at the same time and ignore the
response.

Cheers,


Mike



try
{
/
//Build URL to post execute command to
string pushUrl = "http://" + strDeviceIP +
"/CGI/Execute";

//The Following Creates the WebClient Object
System.Net.HttpWebRequest web =
(System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(pushUrl);
web.ProtocolVersion =
System.Net.HttpVersion.Version10;
web.KeepAlive = false;
web.Credentials = new
System.Net.NetworkCredential(strUsername, strPassword);
web.ContentType =
"application/x-www-form-urlencoded";
web.AllowAutoRedirect = true;
web.MaximumAutomaticRedirections = 5;
web.Method = "POST";
//web.Timeout = 1;

string pushxml =
"<CiscoIPPhoneExecute><ExecuteItem Priority=\"0\" URL=\"" + strURI +
"\"/></CiscoIPPhoneExecute>";
pushxml = "XML=" + HttpUtility.UrlEncode(pushxml);

//PostData is then declared as data type Byte and
populated with the post data
byte[] PostData =
System.Text.ASCIIEncoding.ASCII.GetBytes(pushxml);

//Send POST data (XML)
web.ContentLength = PostData.Length;

Stream dataStream = web.GetRequestStream();
dataStream.Write(PostData, 0, PostData.Length);
dataStream.Flush();
dataStream.Close();

//Send request
System.Net.HttpWebResponse wResponse =
(System.Net.HttpWebResponse)web.GetResponse();
//IAsyncResult r =
(IAsyncResult)web.BeginGetResponse(null, null);
//return IPPhoneReponse.Success;
//System.Net.HttpWebResponse wResponse =
(System.Net.HttpWebResponse)web.BeginGetResponse(null, null);

//Convert to XmlNode
XmlDocument doc = new XmlDocument();
doc.Load(wResponse.GetResponseStream());

//Handle Response
switch (doc.DocumentElement.Name)
{
case "CiscoIPPhoneResponse":
switch
(doc.SelectSingleNode("/CiscoIPPhoneResponse/ResponseItem").Attributes.GetNamedItem("Data").Value)
{
case "Success":
return IPPhoneReponse.Success;
case "":
return IPPhoneReponse.Success;
case "Failure":
return IPPhoneReponse.Failure;
default:
return IPPhoneReponse.Failure;
}
case "CiscoIPPhoneError":
if
(doc.SelectSingleNode("/CiscoIPPhoneError").Attributes.GetNamedItem("Number").Value
== "4")
{
return IPPhoneReponse.AccessDenied;
}
else
{
return IPPhoneReponse.Failure;
}
default:
return IPPhoneReponse.Failure;
}
}

catch (Exception e)
{
if (e.Message.IndexOf("timed-out") > 0)
{
return IPPhoneReponse.TimeOut;
}
if (e.Message.IndexOf("connect") > 0)
{
Debug.WriteLine(e.Message);
return IPPhoneReponse.TimeOut;
}
else
{
return IPPhoneReponse.Failure;
}
}
 
J

jeremiah johnson

Vadym said:
You're using HTTP over TCP. TCP protocol doesn't support broadcasting.

?? Yes it does...

If your subnet is 10.10.10.*, then that subnet's broadcast address is
10.10.10.255.
 
J

jeremiah johnson

Actually you're right, TCP doesn't define broadcasting, IP does, because
IP defines addressing. TCP is a transmission protocol, IP is the
addressing protocol.

So yeah, neither UDP or TCP support broadcasting, its IP that supports it.

But if you're trying to say that you can't send a TCP message to a
broadcast address, you're wrong. Back in the day before broadcast
floods were common, could ping the .255 address on your network and
watch dozens and dozens of ping responses come back. Nowadays broadcast
addresses don't make it through routers at all.

jeremiah
 
V

Vadym Stetsyak

Hello, jeremiah!

jj> But if you're trying to say that you can't send a TCP message to a
jj> broadcast address, you're wrong. Back in the day before broadcast
jj> floods were common, could ping the .255 address on your network and
jj> watch dozens and dozens of ping responses come back. Nowadays
jj> broadcast addresses don't make it through routers at all.

ICMP is not TCP. Yes you can send connection request to broadcast address, but connection is an atomic thing you cannot maintain broadcast connection, so trying to connect to "xxx.xxx.xxx.255" doesn't make sense.

.NET sockets ( stream socket -> tcp socket ) will not allow you to perform connection attempt on this address.

--
Regards, Vadym Stetsyak
www: http://vadmyst.blogspot.com
 
M

Mike Davies

Thanks for all your replies. I did try the threadpool approach but it
didn't seem to work for some reason. I will try again now I know I was
on the right lines.

Thanks again,

Mike

Hi,

I'm developing an APP which pushed web content to various devices on a
LAN (these devices happen to be IP phones).

I need to broadcast a HTTP message to maybe 100 phones at a time but
this is really slow. I've tried different things but not sure what the
right way to go is. First way is to push the message to the phone but
this takes anywhere from 500ms to 1000ms to complete. Incidentally,
I'm not interested in the repsonse from the phone.

The other way I tried was to wait for the response asynchronously but
that didn't seem to work and was still quite slow at around 100ms.

I can't figure out how to push a message to all phones simultaenously
while ignoreing the repsonse. Can anyone point me in the right
direction.

Just to reiterate, I'm not interested in the response even though the
code below checks for a response. This is just because druing testing
I wanted to know if the phone received it or not. My problem is how do
I send a HTTP request to 100 phones at the same time and ignore the
response.

Cheers,


Mike



try
{
/
//Build URL to post execute command to
string pushUrl = "http://" + strDeviceIP +
"/CGI/Execute";

//The Following Creates the WebClient Object
System.Net.HttpWebRequest web =
(System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(pushUrl);
web.ProtocolVersion =
System.Net.HttpVersion.Version10;
web.KeepAlive = false;
web.Credentials = new
System.Net.NetworkCredential(strUsername, strPassword);
web.ContentType =
"application/x-www-form-urlencoded";
web.AllowAutoRedirect = true;
web.MaximumAutomaticRedirections = 5;
web.Method = "POST";
//web.Timeout = 1;

string pushxml =
"<CiscoIPPhoneExecute><ExecuteItem Priority=\"0\" URL=\"" + strURI +
"\"/></CiscoIPPhoneExecute>";
pushxml = "XML=" + HttpUtility.UrlEncode(pushxml);

//PostData is then declared as data type Byte and
populated with the post data
byte[] PostData =
System.Text.ASCIIEncoding.ASCII.GetBytes(pushxml);

//Send POST data (XML)
web.ContentLength = PostData.Length;

Stream dataStream = web.GetRequestStream();
dataStream.Write(PostData, 0, PostData.Length);
dataStream.Flush();
dataStream.Close();

//Send request
System.Net.HttpWebResponse wResponse =
(System.Net.HttpWebResponse)web.GetResponse();
//IAsyncResult r =
(IAsyncResult)web.BeginGetResponse(null, null);
//return IPPhoneReponse.Success;
//System.Net.HttpWebResponse wResponse =
(System.Net.HttpWebResponse)web.BeginGetResponse(null, null);

//Convert to XmlNode
XmlDocument doc = new XmlDocument();
doc.Load(wResponse.GetResponseStream());

//Handle Response
switch (doc.DocumentElement.Name)
{
case "CiscoIPPhoneResponse":
switch
(doc.SelectSingleNode("/CiscoIPPhoneResponse/ResponseItem").Attributes.GetNamedItem("Data").Value)
{
case "Success":
return IPPhoneReponse.Success;
case "":
return IPPhoneReponse.Success;
case "Failure":
return IPPhoneReponse.Failure;
default:
return IPPhoneReponse.Failure;
}
case "CiscoIPPhoneError":
if
(doc.SelectSingleNode("/CiscoIPPhoneError").Attributes.GetNamedItem("Number").Value
== "4")
{
return IPPhoneReponse.AccessDenied;
}
else
{
return IPPhoneReponse.Failure;
}
default:
return IPPhoneReponse.Failure;
}
}

catch (Exception e)
{
if (e.Message.IndexOf("timed-out") > 0)
{
return IPPhoneReponse.TimeOut;
}
if (e.Message.IndexOf("connect") > 0)
{
Debug.WriteLine(e.Message);
return IPPhoneReponse.TimeOut;
}
else
{
return IPPhoneReponse.Failure;
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top