2017. 10. 20. 13:13
In this tutorial I will show the easiest way to retrieve users location from their browser using HTML5 Geolocation API. I will also show you a secondary way to get the user location through IP address. This is useful if users denied the HTML5 Geolocation requests.
Here is the demo. If you would like to test it, just open this link and share with your friends.
First of all we need to install Node.js to our server. We also need to install socket.io to use web sockets. To install Socket.IO simply run this command in your Node folder:
npm install socket.io
To learn more, you can find more information at the official Socket.IO website. After installing the Socket.IO we are ready to create the frontend side.
Now we should create the client side. This is the basic website source code without any JavaScript code. As you can see, we need to use the Socket.IO client side JavaScript file, the jQuery 2.1.4 library and we also need the Google Maps Api JavaScript. You have to create a new Google Maps App and replace the XXXXXXX to your own App key. Create a new html document, I called it: index.html
<!DOCTYPE html>
<html>
<head>
<title>Geolocation</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<script src="/socket.io/socket.io.js"></script>
<script src="/map/js/jquery-2.1.4.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=XXXXXXXXXXXXXXXXXXXcallback=initMap" async defer></script>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
// Scripts
</script>
</body>
</html>
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 49.037, lng: 14.974},
zoom: 2
});
}
I set up a very low zoom level to see each continent easily. The initMap function runs when the browser opens the page. Now we need to get the users’ location.
To retrieve users’ location we use the HTML5 Geolocation API. However, if the user denies the access from the HTML Geolocation API, we can get the user’s location through IP address. It is not as precise as the Geolocation detection, but it is useful. Through IP location we can detect the user’s location by city.
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition, hidePosition);
}else{
alert("Geolocation is not supported by this browser. Now we trying to get your location through your IP address.");
ipPosition();
}
}
function showPosition(position) {
pos = {
lat: parseFloat(position.coords.latitude),
lng: parseFloat(position.coords.longitude)
};
}
function hidePosition(position) {
alert('User denied the access of the position. Now we trying to get your location through your IP address.');
ipPosition();
}
function ipPosition(){
$.get("http://ipinfo.io", function (response) {
var loc = response.loc.split(',');
pos = {
lat: parseFloat(loc[0]),
lng: parseFloat(loc[1])
};
}, "jsonp");
}
getLocation();
On page load we call the getLocation function. The browser built in Geolocation ask the user to enable the current position. If the user allows it, Geolocation calls the showPosition function and we receive the position through the pos object. If the user denies the access of the position, the function calls the ipPosition function which makes an Ajax query from ipinfo.io with the user’s IP address. In the response we receive the position.
Notice: With Firefox browser you can’t recieve the IP location if you click to deny after the browser asks you to enable the Geolocation. Firefox calls the ipPosition if you click to the “never for this site” option. More information on this link: Share location- "Not Now" Doesn't fire error callback
When a user visits the page the script gets the location. Now we need to create Markers. Markers point to the position on the Map. These functions will be called after a user connected to the server.
var markers = [];
var getMarkerUniqueId= function(lat, lng) {
return lat + '_' + lng;
}
function addMarker(location) { // Adds a marker to the map and push to the array.
var markerId = getMarkerUniqueId(location.lat, location.lng); // that will be used to cache this marker in markers object.
var marker = new google.maps.Marker({
position: location,
map: map,
animation: google.maps.Animation.DROP,
id: markerId
});
markers[markerId] = marker;
}
var removeMarker = function(marker, markerId) {
marker.setMap(null); // set markers setMap to null to remove it from map
delete markers[markerId]; // delete marker instance from markers object
};
We call the socket.io, then we should use the document ready function, because we need some jQuery codes. When the user connects to the server the connect function generates a client id. This is very important in order to identify the client to the server. We also have a setInterval function called check_pos, which checks the user’s activity in every half seconds. If a position is created it sends two sockets to the server side:
socket.emit('new_user', {pos: pos});
If everything works fine, the server will receive the user’s position (pos).
var socket = io();
$(document).ready(function(){
check_pos = setInterval(function(){ //create a loop and wait for the response
if(typeof pos != 'undefined'){ //while the position is not defined the loop is checking every half seconds
socket.emit('new_user', {pos: pos});
clearInterval(check_pos);
}
}, 500);
socket.on('already', function(data){
$.each( data.visitors, function( key, pos ) {
addMarker(pos);
});
});
socket.on('connected', function(data){
$("#users_count").html("<strong>" + data.users_count +"</strong>" + " connected users");
$("#users_count").css({'visibility': 'visible'});
addMarker(data.pos);
});
socket.on('disconnected', function(data){
//we can now delete this position:
var markerId = getMarkerUniqueId(data.del.lat, data.del.lng); // get marker id by using clicked point's coordinate
var marker = markers[markerId]; // find marker
removeMarker(marker, markerId); // remove it
$("#users_count").html("<strong>" + data.users_count +"</strong>" + " connected users");
});
});
Finally, we can make the last step. You should know some basics about the Node.js to understand this code. To learn more, please check out this link: Node.js Docs
We create an object called visitors. As you can see, the new_user function is called from the client side. When the sockets arrive to the server we store them in the visitors object. After this, we send back the position to all connected clients through the connected function. If you check it, you will see that the connected function gets the latitude and the longitude of the position and send them to the marker creator function.
Lastly, if the user is disconnected, the server detects the action and removes it from the visitors object. At the same time, the client will disappear from all of the client’s map. Create a new javascript file, I called it: map.js
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(3000, function(){
console.log('MAP started on port: 3000');
});
app.get('/', function(req, res){
res.sendFile(__dirname + '/map/index.html');
app.use(express.static('.'));
});
var visitors = {};
io.on('connection', function(socket){
socket.on('new_user', function(data){
if(parseInt(Object.keys(visitors).length) > 0)
socket.emit('already', {visitors: visitors});
visitors[socket.id] = data.pos;
io.emit('connected', { pos: data.pos, users_count: Object.keys(visitors).length });
console.log('someone CONNECTED:');
console.log(visitors);
});
socket.on('disconnect', function(){
if(visitors[socket.id]){
var todel = visitors[socket.id];
delete visitors[socket.id];
io.emit('disconnected', { del: todel, users_count: Object.keys(visitors).length });
}
console.log('someone DISCONNECTED:');
console.log(visitors);
});
});
I am a Web developer. I am developing in web languages like: PHP, HTML, JavaScript, jQuery, NodeJS. In the following posts you can learn some useful techniques.
6 articles available
It's a very simple but useful way to change the server default timezone by location if you use Ubuntu 14.
2018. 01. 24. 10:33
If you use VestaCP you may got an update error in email messages. Here is the solutions to fix this problem.
2017. 10. 27. 19:35
I made a little script to generate date and time with JavaScript. It's very simple and you can easily customize it.
2017. 10. 20. 12:31
In this article I'm gonna show my new Node.js Chat application for you. It's under development and it's in BETA version, but you can try and test it.
2017. 10. 20. 12:02
You are in a show. There are three doors and you have to select one door. Behind one door there is the prize: the car. Behind the two other doors you can only find a goat. The mission is simple: find the door which hides the car.
2017. 10. 18. 20:28