Skip to content

Instantly share code, notes, and snippets.

@Kolesias123
Created February 2, 2013 01:08
Show Gist options
  • Save Kolesias123/4695390 to your computer and use it in GitHub Desktop.
Save Kolesias123/4695390 to your computer and use it in GitHub Desktop.
Servidor en NodeJS y Socket.IO usado para enviar votos a MTV.
/**
* MTV - Servidor de envio de votos.
*
* InfoSmart. Todos los derechos reservados.
* Copyright 2013 - Iván Bravo Bravo.
*
* http://tools.infosmart.mx/ - http://nodejs.org/ - http://socket.io/
**/
// Versión del servidor
var Version = 4;
// Puerto
var Port = 8001;
// Socket.IO
var Server = null;
// Los sockets conectados (usuarios)
var Sockets = null;
// Host para usarse en la función Post()
var Host = "http://tools.infosmart.mx/latino";
// XMLHttpRequest
var XMLHttpRequest = require("XMLHttpRequest").XMLHttpRequest;
// Lista de los Sockets online (usuarios online)
var rSockets = {};
// Conexiones entrantes.
var Connections = 0;
// Tiempo para imprimir estadisticas: cada 30 segundos
var CheckPing = 30000;
// Tiempo para actualizar el contador a los usuarios: cada 2 segundos
var UpdateCount = 2000;
// Tiempo para seleccionar un "mensaje global": cada 15 minutos
var PickMessage = 900000;
// Tiempo para hacer un voto desde del servidor: cada 3 segundos
var VoteMySelf = 3000;
// Votos realizados
var Votes = 0;
// Socket del usuario "suertudo" para el mensaje global.
var SocketGlobalMessage = 0;
// Videos
var Videos = {"6CztN_RzS68":"Solo a terceros","tTZ18m4W3gY":"Procedimientos para llegar a un comun acuerdo","xQfqhGPwacU":"Disculpa los Malos Pensamientos","AhQpZiZFdw8":"Cuando no es como deberia ser","qroJpc5GgMo":"Cita en el quirofano","83iBOdXzfrg":"Ya no jalaba","IZSmX3G-IRk":"Maracas","nTZKHn-65qg":"Si supieras","38mFtzIAE_c":"Hola!","H_uFuxBdZAI":"Buen d\u00eda","1uQG9yc-raQ":"Nuestra aflicci\u00f3n","wTriG7nx-Uo":"Adheridos separados","2e5Pm6C_BeU":"Nunca nadie nos podr\u00e1 parar","s25OFZitt0I":"Mu\u00f1eca","vhW2ImK4IxQ":"Quisiera no pensar","P1Gn5fN1k60":"Envejecido en Barril de Roble","oj5dnf9CyiM":"Romance en Re Sostenido","1LO-8-FFeFA":"Sistema sanguineo fallido","fgY6uG6xnjU":"La noche de la mesa triste","2iRHMaeXn_E":"Los Malaventurados No Lloran","cUdmWZaMad4":"Narcisista por Excelencia"};
// Video a reproducir actual.
var Video = '6CztN_RzS68';
// Votos para el siguiente video.
var VideoVotes = {};
//
var ResetVideoVotes = null;
// Leemos el archivo votes.txt para obtener los votos realizados.
require('fs').readFile('votes.txt', function(err, data)
{
if (err)
Votes = 0;
else
Votes = data;
});
WriteLog("Preparando conexión...");
Server = require("socket.io").listen(Port);
Sockets = Server.sockets;
WriteLog("Escuchando conexiones entrantes desde el puerto " + Port);
WriteLog("SERVIDOR INICIADO");
Server.set('log level', 1);
Sockets.on("connection", Connection);
Sockets.on("disconnect", Disconnect);
Sockets.on("error", Error);
setInterval(Ping, CheckPing);
setInterval(SendCount, UpdateCount);
setInterval(PickGlobalMessage, PickMessage);
setInterval(Vote, VoteMySelf);
SendCount();
/* Funciones - Servidor */
// Escribir un log en la consola.
function WriteLog(message)
{
var d = new Date();
var n = d.getDay() + "-" + (d.getMonth() + 1) + "-" + d.getFullYear() + " " + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds();
console.log("[" + n + "] - " + message);
}
// Escribir un error en la consola.
function WriteError(e)
{
console.log(">> ¡ERROR! " + e);
}
// Recibir una nueva conexión.
function Connection(Sock)
{
Connections++;
WriteLog("NUEVA CONEXIÓN ENTRANTE #" + Connections);
// Guardamos el Socket en una lista.
rSockets[Sock.id] = Sock;
// Le enviamos la versión del servidor y su SOCKET ID.
Sock.emit('SetVersion', {'version': Version, 'socket': Sock.id});
// Establecemos los Handlers
SetHandlers(Sock);
}
// Servidor desconectado.
function Disconnect()
{
Send2All("Servidor desconectado ¡Adios!");
}
// Error del servidor.
function Error(e)
{
WriteLog("Ha ocurrido un error: - " + e);
}
// Establecer los Handlers
function SetHandlers(Sock)
{
Sock.on('SendVote', Vote);
Sock.on('GlobalMessage', GetGlobalMessage);
Sock.on('SelectNextVideo', SelectNextVideo);
Sock.on('RequestNextVideo', RequestNextVideo);
}
/* Funciones - Usuarios */
// Enviar un voto.
function Vote(data)
{
//var VoteActual = Votes + 1;
//WriteLog('Enviando voto #' + VoteActual + '...');
PostLegacy('http://top-musica.mtvla.com/_ajax_votar.php',
{
'fecha': '14',
'tema': '307'
}, function(result)
{
if(result == 'ok=1')
Votes++;
else
WriteError('Error al enviar voto: ' + result);
});
//var VoteActual = Votes + 1;
//WriteLog('Enviando voto #' + VoteActual + '...');
PostLegacy('http://top-musica.mtvla.com/_ajax_votar.php',
{
'fecha': '16',
'tema': '307'
}, function(result)
{
if(result == 'ok=1')
Votes++;
else
WriteError('Error al enviar voto: ' + result);
});
}
// Seleccionamos un Socket al azar para enviar un mensaje global.
function PickGlobalMessage()
{
// Al parecer no hay nadie conectado
// o hay menos de 5 usuarios
if(rSockets == null || rSockets.length <= 5)
return;
// Obtenemos las ID's de todos los Sockets.
var ids = array_keys(rSockets);
// ¿Algo ocurrio mal?
if(ids == null || ids.length <= 0)
return;
// Seleccionamos una ID al azar.
var pick = array_rand(ids);
// Ajustamos la ID del suertudo.
SocketGlobalMessage = ids[pick];
WriteLog('Seleccionando a alguien para el mensaje global...');
// Al suertudo le enviamos el paquete para que abra la ventana de mensaje global.
Send2ID(SocketGlobalMessage, '', 'TurnGlobalMessage');
}
// Obtenemos el mensaje global.
function GetGlobalMessage(data)
{
WriteLog('Recibiendo mensaje global...');
// ¿Olvido poner su nombre?
if(data.name == undefined || data.name == '')
return WriteError('El mensaje global no tenia nombre');
// ¿Olvido poner el mensaje?
if(data.message == undefined || data.message == '')
return WriteError('El mensaje global no tenia ningun mensaje');
// Hey... la ID no coincide.
// Ha expirado su tiempo o un gracioso intentando enviar SPAM.
if(data.socket != SocketGlobalMessage)
return Send2ID(data.socket, '', 'NoTurnGlobalMessage');
// Filtramos malas palabras...
Post('/actions/server/filter.php', {'message': data.message}, function(message)
{
// Le enviamos el paquete de mensaje global a todos los Sockets (usuarios)
Send2All(
{
'name': data.name,
'message': message,
'owner': data.socket
}, 'GlobalMessage');
});
}
// Recibimos un voto para "el siguiente video"
function SelectNextVideo(data)
{
// Inicializamos la variable.
if(VideoVotes[data] == undefined)
VideoVotes[data] = 0;
// Un voto más
VideoVotes[data]++;
// Actualizamos el video con más votos.
PickNextVideo();
}
// Actualizar el vídeo con más votos.
function PickNextVideo()
{
// Valor más alto
var higher = 0;
var actual_video = Video;
for(key in VideoVotes)
{
// Si los votos de este video son más altos que el anterior.
if(VideoVotes[key] > higher)
{
higher = VideoVotes[key];
Video = key;
}
}
// ¡Nadie voto!
if(Video == actual_video)
{
// Obtenemos las ID's de todos los Videos.
var ids = array_keys(Videos);
// ¿Algo ocurrio mal?
if(ids == null || ids.length <= 0)
return;
// Seleccionamos una ID al azar.
var pick = array_rand(ids);
// Ajustamos un video al azar.
Video = ids[pick];
}
}
// Solicitar el video más votado.
function RequestNextVideo(data)
{
// Regresamos el video más votado.
Send2ID(data.socket, Video, 'SetNextVideo');
// No hay ningún contador para reiniciar los votos.
if(ResetVideoVotes == null)
{
ResetVideoVotes = setTimeout(function()
{
VideoVotes = {};
ResetVideoVotes = null;
}, 60000);
}
}
// Enviar un paquete a todos los Sockets.
function Send2All(data, type)
{
if(type == undefined)
type = "SendData";
Sockets.emit(type, data);
}
// Enviar un paquete a un Socket.
function Send2ID(id, data, type)
{
var Sock = rSockets[id]
if(Sock == undefined || Sock == null)
return;
if(type == undefined)
type = "SendData";
Sock.emit(type, data);
}
/* Funciones - Estadisticas */
// Calculamos los usuarios usuario y el uso de memoria.
function Ping()
{
var i = Count();
var mem = process.memoryUsage();
WriteLog("Actualmente hay " + i + " conexiones activas con un uso de " + parseInt(mem.rss / 1024) + " KB Memoria.");
WriteLog("Se han hecho " + Votes + " votos.");
require('fs').writeFile('votes.txt', Votes, function(err)
{
if(err)
WriteError('Al guardar el archhivo de votos: ' + err);
});
}
// Se obtiene el numero de usuarios online y refresca la lista de Sockets.
function Count()
{
var conn = Sockets.manager.connected;
var i = 0;
var backup = rSockets;
rSockets = {};
for(id in conn)
{
rSockets[id] = backup[id];
i++;
}
return i;
}
// Enviar los usuarios online a todos los Sockets.
function SendCount()
{
Send2All(
{
'online': Count(),
'votes': Votes
}, 'UpdateCount');
}
/* Funciones - ETC */
function Post(site, post, callback, type)
{
var http = new XMLHttpRequest();
var topost = "";
var i = 0;
for(p in post)
{
if(i > 0)
topost += "&";
i++;
topost += p + "=" + post[p];
}
http.onreadystatechange = function()
{
if(this.readyState == 4 && callback != undefined)
{
if(type == "JSON")
http.responseText = Json_decode(http.responseText);
callback(http.responseText);
}
}
http.open("POST", Host + site);
http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-legth", topost.length);
http.setRequestHeader("Connection", "close");
http.send(topost);
}
function PostLegacy(site, post, callback, type)
{
var http = new XMLHttpRequest();
var topost = "";
var i = 0;
for(p in post)
{
if(i > 0)
topost += "&";
i++;
topost += p + "=" + post[p];
}
http.onreadystatechange = function()
{
if(this.readyState == 4 && callback != undefined)
{
if(type == "JSON")
http.responseText = Json_decode(http.responseText);
callback(http.responseText);
}
}
http.open("POST", site);
http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-legth", topost.length);
http.setRequestHeader("Connection", "close");
http.send(topost);
}
function Time()
{
return Math.round((new Date()).getTime() / 1000);
}
function InArray(find, array)
{
return eval(array).join().indexOf(find) >= 0;
}
function Json_decode(str_json)
{
var json = JSON;
if (typeof json === 'object' && typeof json.parse === 'function')
{
try
{ return json.parse(str_json); }
catch (err)
{
console.error("Ha sucedido un error al descodificar '" + str_json + "' de JSON.");
return str_json;
}
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
var j;
var text = str_json;
cx.lastIndex = 0;
if (cx.test(text))
{
text = text.replace(cx, function (a) {
return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
if ((/^[\],:{}\s]*$/).
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, '')))
{
j = eval('(' + text + ')');
return j;
}
return str_json;
}
function round(value,precision,mode){var m,f,isHalf,sgn;precision|=0;m=Math.pow(10,precision);value*=m;sgn=(value>0)|-(value<0);isHalf=value%1===0.5*sgn;f=Math.floor(value);if(isHalf){switch(mode){case'PHP_ROUND_HALF_DOWN':value=f+(sgn<0);break;case'PHP_ROUND_HALF_EVEN':value=f+(f%2*sgn);break;case'PHP_ROUND_HALF_ODD':value=f+!(f%2);break;default:value=f+(sgn>0);}}
return(isHalf?value:Math.round(value))/m;}
function array_rand(input,num_req){var indexes=[];var ticks=num_req||1;var checkDuplicate=function(input,value){var exist=false,index=0,il=input.length;while(index<il){if(input[index]===value){exist=true;break;}
index++;}
return exist;};if(Object.prototype.toString.call(input)==='[object Array]'&&ticks<=input.length){while(true){var rand=Math.floor((Math.random()*input.length));if(indexes.length===ticks){break;}
if(!checkDuplicate(indexes,rand)){indexes.push(rand);}}}else{indexes=null;}
return((ticks==1)?indexes.join():indexes);}
function array_keys(input,search_value,argStrict){var search=typeof search_value!=='undefined',tmp_arr=[],strict=!!argStrict,include=true,key='';if(input&&typeof input==='object'&&input.change_key_case){return input.keys(search_value,argStrict);}
for(key in input){if(input.hasOwnProperty(key)){include=true;if(search){if(strict&&input[key]!==search_value){include=false;}
else if(input[key]!=search_value){include=false;}}
if(include){tmp_arr[tmp_arr.length]=key;}}}
return tmp_arr;}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment