node.js - ¿Cómo reutilizar la conexión de redis en socket.io?
(5)
Aquí está mi código usando socket.io como WebSocket y back-end con pub / sub redis.
var io = io.listen(server),
buffer = [];
var redis = require("redis");
var subscribe = redis.createClient(); **<--- open new connection overhead**
io.on(''connection'', function(client) {
console.log(client.request.headers.cookie);
subscribe.get("..", function (err, replies) {
});
subscribe.on("message",function(channel,message) {
var msg = { message: [client.sessionId, message] };
buffer.push(msg);
if (buffer.length > 15) buffer.shift();
client.send(msg);
});
client.on(''message'', function(message){
});
client.on(''disconnect'', function(){
subscribe.quit();
});
});
Cada nueva solicitud io creará una nueva conexión redis. Si alguien abre el navegador con 100 pestañas, el cliente redis abrirá 100 conexiones. No se ve bien
¿Es posible reutilizar la conexión redis si las cookies son las mismas? Por lo tanto, si alguien abre muchas pestañas del navegador también se considera abierta 1.
Debe eliminar el oyente cuando el cliente se desconecta.
var io = io.listen(server),
buffer = [];
var redis = require("redis");
var subscribe = redis.createClient();
io.on(''connection'', function(client) {
console.log(client.request.headers.cookie);
subscribe.get("..", function (err, replies) {
});
var redis_handler = function(channel,message) {
var msg = { message: [client.sessionId, message] };
buffer.push(msg);
if (buffer.length > 15) buffer.shift();
client.send(msg);
};
subscribe.on("message", redis_handler);
client.on(''message'', function(message){
});
client.on(''disconnect'', function(){
subscribe.removeListerner(''message'', redis_handler)
//subscribe.quit();
});
});
Consulte Redis, Node.js y Socket.io: autenticación cruzada del servidor y comprensión de node.js
En realidad, solo está creando un nuevo cliente redis para cada conexión si crea una instancia del cliente en el evento de "conexión". Lo que prefiero hacer cuando creo un sistema de chat es crear tres clientes redis. Uno para publicar, suscribirse y otro para almacenar valores en redis.
por ejemplo:
var socketio = require("socket.io")
var redis = require("redis")
// redis clients
var store = redis.createClient()
var pub = redis.createClient()
var sub = redis.createClient()
// ... application paths go here
var socket = socketio.listen(app)
sub.subscribe("chat")
socket.on("connection", function(client){
client.send("welcome!")
client.on("message", function(text){
store.incr("messageNextId", function(e, id){
store.hmset("messages:" + id, { uid: client.sessionId, text: text }, function(e, r){
pub.publish("chat", "messages:" + id)
})
})
})
client.on("disconnect", function(){
client.broadcast(client.sessionId + " disconnected")
})
sub.on("message", function(pattern, key){
store.hgetall(key, function(e, obj){
client.send(obj.uid + ": " + obj.text)
})
})
})
Redis está optimizado para un alto nivel de conexiones simultáneas . También se discussion sobre las conexiones de bases de datos múltiples y la implementación del conjunto de conexiones en el módulo node_redis .
¿Es posible reutilizar la conexión redis si las cookies son las mismas? Por lo tanto, si alguien abre muchas pestañas del navegador también se considera abierta 1.
Puede utilizar, por ejemplo, el almacenamiento HTML5 en el lado del cliente para mantenerse conectado activamente solo una pestaña y otros gestionarán las comunicaciones / mensajes a través de eventos de almacenamiento. Está relacionado con this pregunta.
Tenía este problema exacto, con un requisito adicional de que los clientes deben poder suscribirse a canales privados, y publicar en esos canales no debe enviarse a todos los oyentes. Intenté resolver este problema escribiendo un complemento en miniatura. El complemento:
- Utiliza solo 2 conexiones redis, una para pub, una para sub
- Solo se suscribe a "mensaje" una vez total (no una vez cada conexión Redis)
- Permita que los clientes se suscriban a sus propios canales privados, sin que se envíen mensajes a todos los otros clientes que escuchan.
Especialmente útil si su creación de prototipos en un lugar donde tiene un límite de conexión redis (como redis-to-go). SO enlace: https://.com/a/16770510/685404
Usar redis como una tienda se ha vuelto mucho más simple ya que esta pregunta fue hecha / respondida. Está construido ahora .
Tenga en cuenta que si está utilizando redis porque está utilizando las nuevas capacidades de clúster de nodos (utilizando múltiples CPU), debe crear el servidor y adjuntar los oyentes dentro de cada una de las bifurcaciones del clúster (esto nunca se explica en realidad en ninguna parte de la documentación ;) ). El único ejemplo de código bueno en línea que he encontrado está escrito en CoffeeScript y veo a mucha gente diciendo que este tipo de cosas "simplemente no funciona", y definitivamente no lo hace si lo haces mal . Aquí hay un ejemplo de "hacerlo bien" (pero está en CoffeeScript)