2015-09-23 71 views
11

我正在創建一個聊天應用程序,使用戶可以進行私人聊天和羣聊。計劃使用以下技術爲這個應用程序: - 使用Redis的作爲PubSub的服務通過Socket.io使用Redis作爲PubSub

+的NodeJS + Socket.io Redis的+ CouchDB的(存儲消息歷史)+ AngularJS

按我最初的研究是在用更好的方法Socket.io作爲pub-sub。原因是如果不同的用戶連接到不同的服務器實例,那麼在這種情況下使用套接字將產生問題,因爲用戶1發送的消息不會傳遞給用戶2(用戶1連接到服務器1和用戶2連接到服務器2)。

但是,如果我們使用Redis,那麼根據我的理解,我們必須創建新的頻道以啓用私人聊天。它們是Redis 10k頻道的限制。

我的疑惑是

  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的快速POC。下面是代碼: -

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的pub/sub。

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(節點。 js)
  • Redis
  • Socket.IO

該應用程序由用戶可以加入並啓動對話的聊天室組成。 Socket.IO負責在更新聊天計數/消息時發出事件,並使用jQuery在UI中刷新這些事件。

對於完整的文章和源代碼,請查看以下鏈接:https://scalegrid.io/blog/using-redis-with-node-js-and-socket-io/