I'm looking to geolocate my server requests by continent.
Basically, after doing some initial research, it seems that there are 3 approaches: 1) using the geolocation provided by browsers (but I think noone seriously click "Yes" when the browser is asking permission to use geolocation); 2) getting a list of IP addresses, putting that list in a database on your server and then every time a request comes in, read from this DB; I'd hate to have have to hit the DB at every request. 3) make an HTTP call to an external server to get the location; that could even be slower than 2).
Basically, I don't really care to know exactly where the users are, I just need to know which continent they're on: North Armerica, Europe...
Is there a way to do this that doesn't require any user interaction and doesn't require reading a DB on every request? When I go to www.intel.com I get automatically rerouted to the French site; how do they do that?
Thanks for your suggestions.
There are some free and some commercial database that can tell you from the ip, where is coming from.
The free database from maxmind [*]: http://dev.maxmind.com/geoip/geolite
and two commercial:
http://www.ip2location.com
http://www.maxmind.com
In this site you can also find asp.net examples on how you can use that data, but also they have other free services that you can use and see where the use is come from.
Get api samples together with the database from: http://www.maxmind.com/download/geoip/
If only the country is what you need for then this database file
http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
contains only the country, and is small compared with the rest.
How this works in few words: The database is in format of:
"1.20.0.0","1.20.255.255","18087936","18153471","TH","Thailand"
"1.21.0.0","1.21.255.255","18153472","18219007","JP","Japan"
"1.22.0.0","1.23.255.255","18219008","18350079","IN","India"
"1.24.0.0","1.31.255.255","18350080","18874367","CN","China"
the long numbers are the translation of the ip. So you read the IP of your user and then with a function you convert it to long and then you search the database, where is this long number fits.
public long addrToNum(IPAddress Address)
{
byte[] b = BitConverter.GetBytes(Address.Address);
if (b.Length == 8)
return (long)(((long)16777216 * b[0]) + ((long)(65536 * b[1])) + ((long)(256 * b[2])) + b[3]);
else
return 0;
}
So if you add them in database then you index the database on this long numbers and look where the ip is in as:
Select TOP 1 * from GeoIPCountryWhois WITH (NOLOCK) Where @myIpToLong BETWEEN begin_num AND end_num
Its good to cache the result on a session variable and not search again and again on every page request.
[*] A big thanks to maxmind that still release the free database together with the commercial.
I've used this to geolocate IP addresses before when they requested access to my firewall. Not sure if this is what you're looking for, but it may help.
http://www.geobytes.com/iplocator.htm
It seems that you'd prefer second variant, but you don't need to hit the DB on every request - just cache the result in cookie, for example.
And a little bit of insanity - just to make you think about cost of extra DB request: you can convert some geo-DB (look for Aristos' answer) for your needs. Every IP can be converted to Int64 and you can make continent ranges, while converting DB to your format. For example, 0-10000 would be North America, 10000-20000 - Europe, 20000-30000 - North America again and so on, and the only task after such converting is to spot the IP in these ranges.
But you'll have to make a huge work to perform such converting and don't forget that it would be really big butthurt headache to renew it: IP-base isn't constant.
So, DB request + caching, probably, is the best option.