많은 pub-sub 클라이언트를 허용하는 노드 플러그인을 작성했지만 모든 단일 socketio 연결에서 새로운 연결 대신 2 개의 redis 연결 만 필요합니다. 일반적으로 작동해야합니다. 다른 사람이 사용할 수 있다고 생각했습니다. .
이 코드는 기본적으로이 예제에서 socket.io 클라이언트를 연결할 수 있고 항상 2 개의 연결 만 사용하지만 모든 클라이언트가 자신의 채널을 구독 할 수 있다고 가정합니다. 이 예에서 모든 클라이언트는 '달콤한 메시지!'라는 메시지를받습니다. 10 초 후. socket.io와
예 (레디 스 술집 서브 사용) :
var
RPubSubFactory = require('rpss.js');
var
redOne = redis.createClient(port, host),
redTwo = redis.createClient(port, host);
var pSCFactory = new RPubSubFactory(redOne);
io.sockets.on('connection', function(socket){
var cps = pSCFactory.createClient();
cps.onMessage(function(channel, message){
socket.emit('message', message);
});
io.sockets.on('disconnect', function(socket){
// Dont actually need to unsub, because end() will cleanup all subs,
// but if you need to sometime during the connection lifetime, you can.
cps.unsubscribe('cool_channel');
cps.end();
});
cps.subscribe('cool_channel')
});
setTimeout(function(){
redTwo.publish('cool_channel', 'sweet message!');
},10000);
실제 플러그인 코드 :
var RPubSubFactory = function(){
var
len,indx,tarr;
var
dbcom = false,
rPubSubIdCounter = 1,
clientLookup = {},
globalSubscriptions = {};
// public
this.createClient = function()
{
return new RPubSupClient();
}
// private
var constructor = function(tdbcom)
{
dbcom = tdbcom;
dbcom.on("message", incommingMessage);
}
var incommingMessage = function(rawchannel, strMessage)
{
len = globalSubscriptions[rawchannel].length;
for(var i=0;i<len;i++){
//console.log(globalSubscriptions[rawchannel][i]+' incomming on channel '+rawchannel);
clientLookup[globalSubscriptions[rawchannel][i]]._incommingMessage(rawchannel, strMessage);
}
}
// class
var RPubSupClient = function()
{
var
id = -1,
localSubscriptions = [];
this.id = -1;
this._incommingMessage = function(){};
this.subscribe = function(channel)
{
//console.log('client '+id+' subscribing to '+channel);
if(!(channel in globalSubscriptions)){
globalSubscriptions[channel] = [id];
dbcom.subscribe(channel);
}
else if(globalSubscriptions[channel].indexOf(id) == -1){
globalSubscriptions[channel].push(id);
}
if(localSubscriptions.indexOf(channel) == -1){
localSubscriptions.push(channel);
}
}
this.unsubscribe = function(channel)
{
//console.log('client '+id+' unsubscribing to '+channel);
if(channel in globalSubscriptions)
{
indx = globalSubscriptions[channel].indexOf(id);
if(indx != -1){
globalSubscriptions[channel].splice(indx, 1);
if(globalSubscriptions[channel].length == 0){
delete globalSubscriptions[channel];
dbcom.unsubscribe(channel);
}
}
}
indx = localSubscriptions.indexOf(channel);
if(indx != -1){
localSubscriptions.splice(indx, 1);
}
}
this.onMessage = function(msgFn)
{
this._incommingMessage = msgFn;
}
this.end = function()
{
//console.log('end client id = '+id+' closing subscriptions='+localSubscriptions.join(','));
tarr = localSubscriptions.slice(0);
len = tarr.length;
for(var i=0;i<len;i++){
this.unsubscribe(tarr[i]);
}
localSubscriptions = [];
delete clientLookup[id];
}
var constructor = function(){
this.id = id = rPubSubIdCounter++;
clientLookup[id] = this;
//console.log('new client id = '+id);
}
constructor.apply(this, arguments);
}
constructor.apply(this, arguments);
};
module.exports = RPubSubFactory;
내가 주변 청소 만하고 내가 할 수있는만큼 효율성을 개선하기 위해 노력, 그러나 다른 속도 테스트를 한 후에, 나는 이것이 내가 얻을 수있는 가장 빠른 것이라고 결론을 내렸다.
최신 버전 : https://github.com/Jezternz/node-redis-pubsub
재미있는 질문은 알고 싶습니다. 아마도이 게시물은 도움이 될 것입니다 : http://stackoverflow.com/questions/10167206/redis-pub-sub-or-socket-ios-broadcast – yuwang
링크를 보내 주셔서 감사합니다, 그 마지막 게시물 좋은 지적합니다. socket.io를 사용하려면 (프로세스) 범위가 더 제한적일 수 있기 때문에 확장 성이 떨어질 수 있습니다. –
누구나 그 차이점을 설명 할 수 있습니까? 세부 사항은 좋을 것이다. – user568109