如何在socket.io中重用redis连接?

这里是我的代码使用socket.io作为WebSocket和后端pub /子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(); }); }); 

每个新的IO请求都将创build新的Redis连接。 如果有人用100个标签打开浏览器,则Redis客户端将打开100个连接。 这看起来不错。

如果cookie相同,是否可以重用redis连接? 所以如果有人打开许多浏览器标签,也视为打开1连接。

其实你只是为每个连接创build一个新的redis客户端,如果你在“连接”事件实例化客户端。 创build聊天系统时我喜欢做的是创build三个redis客户端。 一个用于发布,订阅,另一个用于将值存储到redis中。

例如:

 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 针对高级并发连接进行了优化 。 还讨论了node_redis模块中的多个数据库连接和连接池实现。

如果cookie相同,是否可以重用redis连接? 所以如果有人打开许多浏览器标签,也视为打开1连接。

您可以在客户端使用例如HTML5存储来保持仅主动连接一个选项卡,而其他人将通过存储事件处理通信/消息。 这与这个问题有关。

我有这个确切的问题,有额外的要求,客户必须能够订阅私人频道,发布到这些频道不应该被发送到所有的听众。 我试图通过编写一个微型插件来解决这个问题。 插件:

  • 只使用2个redis连接,一个用于pub,一个用于sub
  • 一次只订阅“消息”(不是每次redis连接一次)
  • 允许客户订阅他们自己的私人频道,而没有消息被发送到所有其他聆听客户端。

特别有用的,如果你在一个地方,你有一个redis连接限制(如redis-to-go)的原型。 所以链接: https : //stackoverflow.com/a/16770510/685404

客户端断开连接时,您需要删除侦听器。

 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(); }); }); 

请参阅Redis,Node.js和Socket.io:了解跨服务器身份validation和node.js

因为这个问题被问及/回答,使用redis作为商店变得更加简单。 它现在build成 。

请注意,如果您使用的是Redis,因为您正在使用新的节点群集function(利用多个CPU),则必须创build服务器并在每个群集叉子中附加侦听器(这实际上从来没有在任何地方文档;))。 我find的唯一一个很好的在线代码示例是用CoffeeScript编写的,我看到很多人说这种types的东西“不pipe用”,而且如果你做错了 ,它绝对不会。 下面是一个“正确的做法”的例子(但在CoffeeScript中)