Jump to content

Best way to asynchronously call a webpage and weird bugs


Recommended Posts

Hello everyone,

 

I'm making a plugin that [Mod - Happy Thoughts]ign squawk code based on the response from a webpage, what would be the best way to call that webpage asynchronously ?

The way i'm currently doing this is making a std thread that I detach, but i'm no expert in thread management/c++ so i'm asking for your help.

 

Here is the code I tried:

 

[...]
else if (FunctionId == TAG_FUNC_SQUAWKFORCEMODEA) {

	thread m_getSqThread = std::thread(&CCAUTRA::CautraHTTPThreadedGetSq, this, FlightPlanSelectASEL());
	m_getSqThread.detach();
}
[...]
void CCAUTRA::CautraHTTPThreadedGetSq(EuroScopePlugIn::CFlightPlan fp) {

string url = "http://195.154.85.30/vCAUTRA/cautra.php";

CInternetSession session;
CHttpFile *pHttpFile = NULL;
CString response = NULL;

do {
	try
	{
		pHttpFile = (CHttpFile *)session.OpenURL(url.c_str(), 1, INTERNET_FLAG_DONT_CACHE);
	}
	catch (...)
	{
		DisplayUserMessage("vCAUTRA", "WARNING", "Impossible de se connecter au serveur, mode hors-ligne activé.", true, true, true, true, true);
		offline_mode = true;
		break;
	}

	if (pHttpFile == NULL) {
		DisplayUserMessage("vCAUTRA", "WARNING", "Impossible de se connecter au serveur, mode hors-ligne activé.", true, true, true, true, true);
		offline_mode = true;
		break;
	}
	else
	{
		CString line;
		for (long j = 0; pHttpFile->ReadString(line); j++) {
			response += line;
		}
	}
	pHttpFile->Close();
} while (IsSquawkInUse(atoi(response)) &&!offline_mode);

if (!offline_mode)
	fp.GetController[Mod - Happy Thoughts]ignedData().SetSquawk(response);	

}

 

EDIT: Pink screen bug fixed

 

I never had a problem before drawing the trails, so I think the bug comes from drawing the symbol, using the position of the aircraft. I have to specify that I use Professional Radar, and the issue seems to appear when an uncorrelated aircraft spawns. That bug occurs using EuroScope 3.2, and EuroScope 3.2 with the beta patch.

 

Another issue that I have using EuroScope 3.2, and EuroScope 3.2 with the beta patch, is that even if I have turned off the simulated traffic, it actually sometimes appear randomly, and some aircraft are showing up in my sector inbound list that are very far from my sector, eg: controlling LFPG_APP, i'll see an Aircraft that is in Greece flying from LGAV and OMDB, so yea, no way its going near my sector. I think I might have solved the problem by overriding the vatsim status URL with a blank box, but i'm not sure yet. That is using again professional mode S.

 

Thank you for your help

Link to post
Share on other sites
  • 2 weeks later...

Pierre,

 

This thread happens to be very timely and beneficial for me, as I am also working on a plugin where I need to asynchronously fetch some information from a URL and use that to modify certain aspects of the flight plan.

 

I understand you may not want to share the full code publicly. Can I please ask you to kindly send it to me by email? You can find my email on this page: http://nyartcc.org/roster/staff

 

Thanks!

 

Merik

NYARTCC Facility Engineer and Instructor

 

255qao8.png

Link to post
Share on other sites

I have no experience with std::thread as I always use the MFC version.

But be sure that EuroScope plug-in functions are not thread safe at all. So it would be a much wiser to propagate the squawk to the main thread and [Mod - Happy Thoughts]ign it to the plane there. Even it works fine at the moment.

Gergely.

EuroScope developer

Link to post
Share on other sites
If you decide to use this method I would be happy to share some of my source code from an MFC application for the communication with the web server if it helps?

 

Hi Sam,

 

If you don't mind, I would be very interested in the c++/mfc code, i've posted this thread a few weeks ago, and so far no replies: viewtopic.php?f=71&t=65956

 

That would be very nice of you.

 

Regards

Hello Pierre,

 

To communicate with a web-server I use libcurl which makes the communication process a lot easier. To set it up with MSVS follow the tutorial here:

http://quantcorner.wordpress.com/2012/04/08/using-libcurl-with-visual-c-2010/

 

Please be aware that the following code is lifted from another file I have created and may have some errors where I have accidentally deleted needed lines of code! If you get any errors that may be down to this please say, and I will look into it for you! In the same respect some of the includes libraries may not actually be needed and may be needed for other code I have written. Please also note that not all of this code is my own and the vast majority is from the example source code here:

http://curl.haxx.se/libcurl/c/getinmemory.html

and here:

http://curl.haxx.se/libcurl/c/http-post.html

 

Here is the source code, I have tried to annotate it with comments in key places:

// Generic post and response

#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>	//not sure if needed
#include <sstream>		//not sure if needed

struct MemoryStruct {
 char *memory;
 size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
 size_t realsize = size * nmemb;
 struct MemoryStruct *mem = (struct MemoryStruct *)userp;

 mem->memory = (char*)realloc(mem->memory, mem->size + realsize + 1);
 if(mem->memory == NULL) {
printf("not enough memory (realloc returned NULL)\n");	// out of memory!

   return 0;
 }

 memcpy(&(mem->memory[mem->size]), contents, realsize);
 mem->size += realsize;
 mem->memory[mem->size] = 0;

 return realsize;
}

void SendData()
{
CURL *curl_handle;
CURLcode res;
struct MemoryStruct chunk;
chunk.memory = (char*)malloc(1);  // will be grown as needed by the realloc above
chunk.size = 0;    //no data at this point
curl_global_init(CURL_GLOBAL_ALL);
curl_handle = curl_easy_init();	//init curl
curl_easy_setopt(curl_handle, CURLOPT_URL, "http://example.com/data.php");	//URL to send data to
std::string param1("data1=");	//Name of first field in the POST form
std::string param2("&data2=");	//Name of second field in the POST form
CString data1("datatosend1");	//Data to send to first field in the POST form
CString data2("datatosend2");	//Data to send to second field in the POST form
param1.append(data1);
param2.append(data2);
param1.append(param2);
const char* parameters;
parameters=param1.c_str();	//combines the data to send to the webpage into a single variable which can be used by CURLOPT_POSTFIELDS
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, parameters);	//add data to be sent
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, 1);
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);	//all data sent to this function 
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);	//p[Mod - Happy Thoughts] buffer to writeback func
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");	//useragent
res = curl_easy_perform(curl_handle);	//perform request
if(res != CURLE_OK)	//error check
{
	fprintf(stderr, "curl_easy_perform() failed: %s\n",
	curl_easy_strerror(res));
}
else 
{
	//At this stage the data retrieved from the webpage is in chunk.memory
	//The code below might be useful for copying data out of chunk.memory and into more usable variables
	//It presumes the data is returned in the format: "<string>,<int>,<int>" where each value is separated by ',' as a delimiter
	CString int1temp;
	CString int2temp;
	CString fullcpy;
	CString string;	//the string
	int int1(0);	//first integer
	int int2(0);	//second integer
	char result[254];	//buffer to copy data to
	strcpy(result, chunk.memory);	//copies chunk.memory into result
	char *p = std::strtok (result,",");	//delimiter is ','
	string=p;	//the string is stored here
	p = std::strtok(NULL,",");
	int1temp=p;
	int1=atoi(int1temp);	//first integer is stored here
	p = std::strtok(NULL,",");
	int2temp=p;
	int2=atoi(int2temp);	//second integer is stored here
}
curl_easy_cleanup(curl_handle);	//clean up curl
if(chunk.memory)
	free(chunk.memory);
curl_global_cleanup();	//clean up libcurl


}

The PHP script it interacts with has a basic structure like this:

<?php
if (!isset($_POST['data1']))
{
echo '
<form method="post" action="' . $_SERVER["PHP_SELF"] . '">
<input type="text" name="data1">
<input type="text" name="data2">
<input type="hidden" name="Sent" value="1">
<input type="submit" value="Submit Data">
</form>';
}
else
{
//Do something with the sent data and then give a result to be returned to the application using either 'echo' or 'die'
//e.g.
echo "Sam White,100,90";	//the result that the application will return
}
?>

There is no 'proper' HTML in this like starting with then e.c.t. as otherwise that will also be sent back to the client.

 

I hope this helps you!

Sam

VATSIM UK S2 Rated (Essex RTS)

Sam%20White.jpg

Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...