Lo ideal es que solo use WebSockets
, pero la alternativa es ajax de largo sondeo.
Puede utilizar una técnica conocida como larga encuesta para hacer el chat. Esto significa que realiza una solicitud (ajax) al servidor y el servidor retiene esta solicitud hasta que le quedan algunos datos para enviar.
Por lo que los clientes terminan sondeando periódicamente el servidor, si el servidor no tiene nuevos mensajes, solo mantiene su solicitud. Si tiene un mensaje, lo envía de vuelta al cliente y el cliente volverá a sondear el servidor.
[[Código Pseudo]]
// Client.js
var Socket = function(ip, port, name) {
this.ip = ip;
this.port = port;
this.name = name;
this._cbs = [];
this._poll();
};
// Call the server periodically for data.
Socket.prototype._poll = function() {
var that = this;
// if the server does not return then call it again
var timer = setTimeout(function() {
this._poll();
}, 5000);
$.ajax({
type: "GET",
timeout: 5000,
data: {
name: this.name
},
url: this.ip + ":" + this.port,
success: function(data) {
// server returned, kill the timer.
clearTimeout(timer);
// send the message to the callback.
for (var i = 0; i < that._cbs.length; i++) {
that._cbs[i](data);
}
// call the server again
that._poll();
}
});
};
// Add a callback for a message event
Socket.prototype.on = function(event, cb) {
if (event === "message") {
this._cbs.push(cb);
}
};
// Send a message to the server
Socket.prototype.send = function(message) {
$.ajax({
data: {
message: message,
name: this.name
},
type: "GET",
url: this.ip + ":" + this.port
});
};
var socket = new Socket('192.168.1.1', '8081', "Raynos");
socket.on("message", function(data) {
console.log(data);
});
socket.send("Hello world!");
// server.js
var url = require("url");
var events = require("events");
// store messages for clients
var clients = {};
var emitter = new events.EventEmitter();
http.createServer(function(req, res) {
// get query string data
var data = url.parse(req.url, true).query;
// if client is not initialized then initialize it.
if (data.name && !clients[data.name]) {
clients[data.name] = [];
}
// if you posted a message then add it to all arrays
if (data.message) {
for (var k in clients) {
clients[k].push(data.name + " : " + data.message);
}
// tell long pollers to flush new data.
emitter.emit("new-data");
} else if (clients[data.name].length > 0) {
// else empty the clients array down the stream
for (var i = 0; i < clients[data.name].length; i++) {
res.write(clients[data.name].shift());
};
res.end();
// long polling magic.
} else {
var cb = function() {
for (var i = 0; i < clients[data.name].length; i++) {
res.write(clients[data.name].shift());
};
res.end();
// kill that timer for the response timing out.
clearTimeout(timer);
}
// when we get data flush it to client
emitter.once("new-data", cb);
var timer = setTimeout(function() {
// too long has passed so remove listener and end response.
emitter.removeListener(cb);
res.end();
}, 4500);
}
}).listen(8081);
Una mejor tecnología push sería Server-side events. Vea un example of it here. Esto requiere soporte del navegador (creo que Chrome y la ópera).
pero la pregunta es ¿cómo se envía el mensaje al cliente?gracias por redis, esto parece interesante, sin embargo no se relaciona con 'node.js' :), pero como programador de PHP esto parece interesante – Adam
Bueno, en pocas palabras, una vez que un cliente se suscribe al servicio, se crea una cola para contener cualquier mensaje enviado por otros clientes. Cuando un cliente envía un mensaje, se agrega a cada una de las colas de los otros suscriptores. Luego, el cliente solicita cualquier mensaje pendiente que se haya agregado a su propia cola. –
Websockets (una función de HTML5) permite a un cliente abrir un zócalo bidireccional a un servidor web que el servidor puede usar para "enviar" mensajes al cliente. En ausencia de esta característica, los clientes sondean el servidor (a través de AJAX) por cualquier mensaje pendiente. El servidor no empuja mensajes ya que (no hay websockets) no tiene ninguna función nativa para hacerlo. Esta es la razón por la cual socket.io es tan útil. Si el cliente admite websockets, los usa. Si no, intenta una cantidad de otros medios que se reducen a largas encuestas. –