I have a relatively simple project with very little code that is giving me headaches as I don't know what is causing the problem. The idea is similar to http://tweetping.net/, but it is not showing real-time tweets, but real-time connections of users to a service.
The service uses nodejs as a UPD listener and socket.io to communicate with the web browser. Socket.io then listens to messages and when it receives one it draws a marker on a Google map.
This is the entire JavaScript on the page:
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
var map = false;
var markers = {};
var markerTimeouts = {};
$(window).load(function() {
var mapOptions = {
zoom: 3,
center: new google.maps.LatLng(30, 16),
mapTypeId: google.maps.MapTypeId.ROADMAP,
panControl: false,
streetViewControl: false,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.LARGE,
position: google.maps.ControlPosition.TOP_RIGHT
},
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
});
function createMarker(name, lng, lat) {
var circle = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
map: map,
icon: "/img/marker_red.png?v=2",
title: name
});
markers[name] = circle;
setTimeout(function() { destroyMarker(name); }, 3000);
}
function destroyMarker(name) {
markers[name].setMap(null);
delete markers[name];
}
socket.on('message', function(data){
if (!map) {
return;
}
else {
createMarker(data.name, data.lon, data.lat);
}
});
</script>
The problem happens when there are a lot of concurrent messages (100/s) coming from socket.io. The markers get created just fine via the createMarker method, but when I try removing them 3 seconds later (via setTimeout) the object markers[name] is undefined.
I would make a fiddle.js example, but it's impossible to recreate the many concurrent socket.io messages.
Did anybody have a situation where javascript was not able to push something to an object via the object[key] = something; syntax? Any other ideas?
UPDATE: Note to self: always check if you already have this key in the markers object. Adding the following code solved the issue.
if (name in markers) {
return;
}
You are probably getting the same name twice (or more) in 3 seconds.