在服务器之间缩放socket.io

什么是缩放socket.io应用程序的方法? 我看到下面的问题,我不明白如何解决:

  • 一个缩放的socket.io应用程序如何播放到一个房间? 换句话说,socket.io如何知道其他服务器的邻居呢?

我很难想象它应该如何工作 – 也许是所有必要信息(如redis)的共享变体存储库,这是否有可能?

编辑:我发现这篇文章: http : //www.ranu.com.ar/2011/11/redisstore-and-rooms-with-socketio.html

基于它我做了以下几点:

var pub = redis.createClient(); var sub = redis.createClient(); var store = redis.createClient(); pub.auth("pass"); sub.auth("pass"); store.auth("pass"); io.configure( function(){ io.enable('browser client minification'); // send minified client io.enable('browser client etag'); // apply etag caching logic based on version number io.enable('browser client gzip'); // gzip the file io.set('log level', 1); // reduce logging io.set('transports', [ // enable all transports (optional if you want flashsocket) 'websocket' , 'flashsocket' , 'htmlfile' , 'xhr-polling' , 'jsonp-polling' ]); var RedisStore = require('socket.io/lib/stores/redis'); io.set('store', new RedisStore({redisPub:pub, redisSub:sub, redisClient:store})); }); 

但是我得到以下错误:

  Error: Uncaught, unspecified 'error' event. at RedisClient.emit (events.js:50:15) at Command.callback (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:232:29) at RedisClient.return_error (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:382:25) at RedisReplyParser.<anonymous> (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:78:14) at RedisReplyParser.emit (events.js:67:17) at RedisReplyParser.send_error ( /home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/lib/parser/javascript.js:265:14) at RedisReplyParser.execute (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/lib/parser/javascript.js:124:22) at RedisClient.on_data (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:358:27) at Socket.<anonymous> (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:93:14) at Socket.emit (events.js:67:17) 

我的Redis证书绝对正确。

编辑:很奇怪,但与Redis授权禁用,然后一切正常。 所以这个问题依然有效。 另外,我有一个关于如何在RedisStorage模式下获取组(房间)的所有参与者的信息(例如用户名)的问题,是否可以实现这一点? 理想情况下,这可以通过Redis Pub / Subfunction完成。

你可以使用socket.io集群来工作https://github.com/muchmala/socket.io-cluster

尝试添加此代码;

 pub.on('error', function (err) { console.error('pub', err.stack); }); sub.on('error', function (err) { console.error('sub', err.stack); }); store.on('error', function (err) { console.error('store', err.stack); }); 

它不会解决它,但它应该至less给你一个更有用的错误。

我build议你不要使用RedisStore。 由于使用pub-sub导致不可扩展(使用socket.io可以接收less于一个pure node.js实例,这是非常没用的),所以它在CPU使用上有问题。 我个人使用Redis作为数据存储来保存房间列表,并实现我自己的房间function(Redis是内存中的一个键值数据库,但具有持久的机制)。 当你想要一个房间的数据,只是从相同的redis获取数据,就是这样。 但是,为了能够在多个实例中运行Socket.io,还需要像HAProxy,Nginx这样的负载均衡器将工作分离到多个node.js端口,否则,用户仍将只使用一个node.js进程。 这是一个巨大的工作。 如果您还有其他语言的其他网页前端,那么更多的工作,因为一些networking阻塞端口80和443以外的所有端口。您可以阅读更多有关这些事情的信息:

http://book.mixu.net/node/ch13.html

另一个可能的解决scheme是使用像PubNub这样的替代方法来扩展实时交互。 在开发Mote.io时,我遇到了类似的问题,并决定采用托pipe解决scheme,而不是构build负载平衡器。 我现在为PubNub工作。

PubNub会照顾你正在谈论的数据同步问题。 通常情况下,您需要在服务器之间同步Redis,或者将您的客户端负载平衡到同一个实例,以确保获得所有相同的消息。 PubNub把这个抽象出来,所以你不需要担心。

10行代码中的实时聊天应用程序

在这里输入图像描述

 Enter Chat and press enter <div><input id=input placeholder=you-chat-here /></div> Chat Output <div id=box></div> <script src=http://cdn.pubnub.com/pubnub.min.js></script> <script>(function(){ var box = PUBNUB.$('box'), input = PUBNUB.$('input'), channel = 'chat'; PUBNUB.subscribe({ channel : channel, callback : function(text) { box.innerHTML = (''+text).replace( /[<>]/g, '' ) + '<br>' + box.innerHTML } }); PUBNUB.bind( 'keyup', input, function(e) { (e.keyCode || e.charCode) === 13 && PUBNUB.publish({ channel : channel, message : input.value, x : (input.value='') }) } ) })()</script>