I am currently working on integrating a prototype product I made into a larger program. What I did in the prototype was create a HTTP server on a microcontroller, and then wrote some HTML to call .cgi functions on the web-server. This was so I could control I/O on the micro controller via an ethernet.
My html seems very straight forward, to call a cgi function on the microcontroller I have made buttons with the following syntax:
<script type="text/javascript">
function my_confirm(a){
var r=confirm("Are you sure you'd like to run "+a+"?");
if (r==true)
location.href = a;
}
</script>
<button type = "button" onclick=" my_confirm('started.cgi')" >Started</button>
additionally, if i were to type in “169.254.129.12/started.cgi” into a web browser, the microcontroller would respond appropriately. Now that the prototype is completed ahead of schedule, my new task is to integrate my controls into a C++/CLI program. GREAT. I have never written in C++…
Rather than re-doing all of the backend stuff, I would like to add a menu to send similiar requests. Over the last 4-5 days I have gotten a menu in VS2005 and have had limited success, with the code below:
int sendHttpRequestAndRespond(System::Uri^ url){
if(url->Scheme == System::Uri::UriSchemeHttp){
HttpWebRequest^ request = dynamic_cast<HttpWebRequest^>(WebRequest::Create(url));
request->Method = System::Net::WebRequestMethods::Http::Get;
return 0;
}
//HttpWebResponse^ response = dynamic_cast<HttpWebResponse^> (request->GetResponse());
//RequestState^ state = gcnew RequestState();
//state->request = request;
//try{
// IAsyncResult^ response = dynamic_cast<IAsyncResult^> (request->BeginGetResponse(gcnew AsyncCallback( responseReceived),state));
//}
//catch(WebException^ e){}
else
return -1;
}
With the code written as shown above(with comments present) the I/O control of the microcontroller does not operate properly. Oddly, if I put in the HttpWebResponse line, things (sometimes) go properly, and other times, nothing seems to happen. Lastly, if I use the AsyncResponse, things are similiar to if I use the HttpWebResponse portion.
Now my thought/understanding was that merely putting in the request via the GET method I am using in the code shown above would initiate the I/O control on the microcontroller, but it seems the response plays a role in it as well.
Do any of you have a better route to go with this? At this point I am highly confused/frustrated and open to any advice! Thank you,
EDIT 1: UPDATED CODE:
int sendHttpRequestAndRespond(System::Uri^ url){
if(url->Scheme == System::Uri::UriSchemeHttp){
HttpWebRequest^ request = dynamic_cast<HttpWebRequest^>(WebRequest::Create(url));
request->Method = System::Net::WebRequestMethods::Http::Get;
RequestState^ state = gcnew RequestState();
state->request = request;
try{
IAsyncResult^ response = dynamic_cast<IAsyncResult^> (request->BeginGetResponse(gcnew AsyncCallback( responseReceived),state));
}
catch(WebException^ e){}
return 0;
}
With this code I get into my callback function (responseReceived) the first two times I call the function, but never on the 3rd or further time. I am testing this with http://www.facebook.com, as this seems to work for my CGI calling, but only the first two times as well.
Thanks,
EDIT 2: Resolution and new problems!
Okay, I figured out my problem was due mostly to not ending the requests. In the callBack function I wasn’t ending the request, and HTTP protocol has a 2 connections/ip restriction, making the first two calls work, but future ones wouldn’t.
Now my new issue is that on the asyc call I a using, it first does synchronous DNS resolution. Since I am sending these commands to an embedded computer with an IP, there’s no DNS inbetween, and the function blocks for a long time. Once my computer realizes there’s been a DNS resolution error, it fires off the request any ways, and it works! Subsequent requests work instantly, as there’s a cache that remembers the failure.
So im about 99% of the way there, but I need to fix this first time lockup some how. My current ideas are:
Somehow disable dns resolution before the request
Shorten the dns resolution timeout from 60+ seconds to 1ish seconds
trick my comptuer/the computer the program runs on into thinking that http://169.254.129.12 has an ip address of 169.254.129.12 (local host file??)
I am not sure how to accomplish those, or if there are better ideas??
Thank you,
Any better ideas?
I’m not very familiar with the HttpWebRequest class and related classes, but as I understand it the request doesn’t get sent to the server until you either (a) send it explictly by writing to the request stream, or (b) retrieve the response by calling GetResponse. So for starters I think you need to uncomment all that stuff.
I wonder why you return on line 5 before doing anything with the request. I know this code is a work in progress. But surely you don’t want to return before doing anything?
And finally, you’re using async comms, which is probably extra complexity that you can do without right now. I suggest you do everything synchronously first to get it working, and then switch to async if you really need to.