2015-09-23 3 views
11

Я создаю приложение чата, которое позволяет пользователям делать частные и групповые чаты. Планирование использовать следующие технологии для этого приложения: -Использование Redis as PubSub поверх Socket.io

NodeJs + Socket.io + Redis + CouchDB (К истории магазина сообщений) + AngularJS

За моего первоначального исследования с использованием Redis в качестве службы PubSub лучше подход по сравнению с использованием Socket.io как pub-sub. Исходя из этого, если разные пользователи подключены к разным экземплярам сервера, то использование сокета в этом сценарии создаст проблему, поскольку передача сообщения пользователем 1 не будет передана пользователю 2 (пользователь 1, подключенный к серверу 1 и пользователя 2, подключенного к серверу 2).

Но если мы используем Redis, то при моем понимании мы должны создать новые каналы, чтобы включить частные чаты. И их предел до 10k каналов в Redis.

Мои Сомнения

  1. Мне нужно создать новый канал каждый раз, чтобы включить приватный чат между двумя пользователями ли?
  2. Если мне нужно создать отдельные каналы, то есть ли на самом деле предел 10K каналов?
  3. Мне нужен рабочий пример использования Redis в качестве pub/sub с socket.io, чтобы включить частные чаты.

С уважением, Викрам

ответ

14

После прочтения ниже статьи/блоге, используя Redis для паба/подразделам над Socket.io паб/суб поможет в масштабируемости и повышения производительности.

https://github.com/sayar/RedisMVA/blob/master/module6_redis_pubsub/README.md

https://github.com/rajaraodv/redispubsub

Далее я могу быстро создать ДОУ на привате с помощью Redis. Вот код: -

var app = require('http').createServer(handler); 
app.listen(8088); 
var io = require('socket.io').listen(app); 
var redis = require('redis'); 
var redis2 = require('socket.io-redis'); 
io.adapter(redis2({ host: 'localhost', port: 6379 })); 
var fs = require('fs'); 

function handler(req,res){ 
    fs.readFile(__dirname + '/index.html', function(err,data){ 
     if(err){ 
      res.writeHead(500); 
      return res.end('Error loading index.html'); 
     } 
     res.writeHead(200); 
     console.log("Listening on port 8088"); 
     res.end(data); 
    }); 
} 

var store = redis.createClient(); 
var pub = redis.createClient(); 
var sub = redis.createClient(); 
sub.on("message", function (channel, data) { 
     data = JSON.parse(data); 
     console.log("Inside Redis_Sub: data from channel " + channel + ": " + (data.sendType)); 
     if (parseInt("sendToSelf".localeCompare(data.sendType)) === 0) { 
      io.emit(data.method, data.data); 
     }else if (parseInt("sendToAllConnectedClients".localeCompare(data.sendType)) === 0) { 
      io.sockets.emit(data.method, data.data); 
     }else if (parseInt("sendToAllClientsInRoom".localeCompare(data.sendType)) === 0) { 
      io.sockets.in(channel).emit(data.method, data.data); 
     }  

    }); 

io.sockets.on('connection', function (socket) { 

    sub.on("subscribe", function(channel, count) { 
     console.log("Subscribed to " + channel + ". Now subscribed to " + count + " channel(s)."); 
    }); 

    socket.on("setUsername", function (data) { 
     console.log("Got 'setUsername' from client, " + JSON.stringify(data)); 
     var reply = JSON.stringify({ 
       method: 'message', 
       sendType: 'sendToSelf', 
       data: "You are now online" 
      });  
    }); 

    socket.on("createRoom", function (data) { 
     console.log("Got 'createRoom' from client , " + JSON.stringify(data)); 
     sub.subscribe(data.room); 
     socket.join(data.room);  

     var reply = JSON.stringify({ 
       method: 'message', 
       sendType: 'sendToSelf', 
       data: "Share this room name with others to Join:" + data.room 
      }); 
     pub.publish(data.room,reply); 


    }); 
    socket.on("joinRooom", function (data) { 
     console.log("Got 'joinRooom' from client , " + JSON.stringify(data)); 
     sub.subscribe(data.room); 
     socket.join(data.room);  

    }); 
    socket.on("sendMessage", function (data) { 
     console.log("Got 'sendMessage' from client , " + JSON.stringify(data)); 
     var reply = JSON.stringify({ 
       method: 'message', 
       sendType: 'sendToAllClientsInRoom', 
       data: data.user + ":" + data.msg 
      }); 
     pub.publish(data.room,reply); 

    }); 

    socket.on('disconnect', function() { 
     sub.quit(); 
     pub.publish("chatting","User is disconnected :" + socket.id); 
    }); 

    }); 

HTML код

<html> 
<head> 
    <title>Socket and Redis in Node.js</title> 
    <script src="/socket.io/socket.io.js"></script> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script> 
</head> 
<body> 
<div id="username"> 
    <input type="text" name="usernameTxt" /> 
    <input type="button" name="setUsername" value="Set Username" /> 
</div> 
<div id="createroom" style="display:none;">> 
    <input type="text" name="roomNameTxt" /> 
    <input type="button" name="setRooomName" value="Set Room Name" /> 
    <input type="button" name="joinRooomName" value="Join" /> 
</div> 
<div id="sendChat" style="display:none;"> 
    <input type="text" name="chatTxt" /> 
    <input type="button" name="sendBtn" value="Send" /> 
</div> 
<br /> 
<div id="content"></div> 
<script>  
    $(document).ready(function() { 
     var username = "anonymous"; 
     var roomname = "anonymous"; 
     $('input[name=setUsername]').click(function(){ 
      if($('input[name=usernameTxt]').val() != ""){ 
       username = $('input[name=usernameTxt]').val(); 
       //var msg = {type:'setUsername',user:username}; 
       socket.emit('setUsername',{user:username}); 
      } 
      $('#username').slideUp("slow",function(){ 
       $('#createroom').slideDown("slow"); 
      }); 
     }); 
     $('input[name=setRooomName]').click(function(){ 
      if($('input[name=roomNameTxt]').val() != ""){ 
       roomname = $('input[name=roomNameTxt]').val(); 
       socket.emit('createRoom',{user:username,room:roomname}); 
      } 
      $('#createroom').slideUp("slow",function(){ 
       $('#sendChat').slideDown("slow"); 
      }); 
     }); 
     $('input[name=joinRooomName]').click(function(){ 
      if($('input[name=roomNameTxt]').val() != ""){ 
       roomname = $('input[name=roomNameTxt]').val(); 
       socket.emit('joinRooom',{room:roomname}); 
      } 
      $('#createroom').slideUp("slow",function(){ 
       $('#sendChat').slideDown("slow"); 
      }); 
     }); 

     var socket = new io.connect('http://localhost:8088'); 
     var content = $('#content'); 

     socket.on('connect', function() { 
      console.log("Connected"); 
     }); 

     socket.on('message', function(message){ 
      //alert('received msg=' + message); 
      content.append(message + '<br />'); 
     }) ; 

     socket.on('disconnect', function() { 
      console.log('disconnected'); 
      content.html("<b>Disconnected!</b>"); 
     }); 

     $("input[name=sendBtn]").click(function(){ 
      var msg = {user:username,room:roomname,msg:$("input[name=chatTxt]").val()} 
      socket.emit('sendMessage',msg); 
      $("input[name=chatTxt]").val(""); 
     }); 
    }); 
</script> 
</body> 
</html> 
+1

, что sub.on («сообщение», функция (канал данных) {это делает здесь, есть ли необходимость в этом в этом коде –

+0

Я вижу, что вы используете socketio-комнату. Будет ли он масштабироваться до нескольких экземпляров? – Mubbashar

+0

Почему вы создаете переменную 'store'? Я вижу это в:' var store = redis.createClient(); ' – Stephane

3

Это все основные код REDIS паб/суб.

var redis = require("redis"); 
 

 
var pub = redis.createClient(); 
 
var sub = redis.createClient(); 
 

 
sub.on("subscribe", function(channel, count) { 
 
    console.log("Subscribed to " + channel + ". Now subscribed to " + count + " channel(s)."); 
 
}); 
 

 
sub.on("message", function(channel, message) { 
 
    console.log("Message from channel " + channel + ": " + message); 
 
}); 
 

 
sub.subscribe("tungns"); 
 

 
setInterval(function() { 
 
    var no = Math.floor(Math.random() * 100); 
 
    pub.publish('tungns', 'Generated Chat random no ' + no); 
 
}, 5000);

1

Если вам нужно, чтобы получить ваши ноги мокрые и создать простое приложение чата, то следующий стек горнопроходческие работы очень хорошо вместе:

  • Express.js (Node. js)
  • Redis
  • Socket.IO

Приложение состоит из чата, в который пользователи могут присоединиться и начать разговор. Socket.IO отвечает за излучение событий, когда количество/сообщения чатов обновляется, и они обновляются в пользовательском интерфейсе с помощью jQuery.

Для полной статьи и исходного кода, проверить по следующей ссылке:. https://scalegrid.io/blog/using-redis-with-node-js-and-socket-io/

Смежные вопросы