先看app.js的主要部分
io.sockets.on('connection',function(socket){ var credis = redis.createClient(); credis.auth('chenqiguo'); //訂閱一個頻道的redis連結 var subscribe = redis.createClient(); subscribe.auth('chenqiguo'); //授權 //建立一個發布訊息的redis連結,向指定的頻道發送訊息 var publish = redis.createClient(); publish.auth('chenqiguo');//授權 //socket監聽發行者在某個channel上發布一條資訊 socket.on('publish',function(channel,data){ publish.publish(channel,data); }) //scoket監聽訂閱者在客訂閱一個channel socket.on('psubscribe',function(channel,username){ credis.sadd('user:'+username,channel); //這裡我們把使用者每次訂閱的channel放到了一個set中 subscribe.psubscribe(channel); }) //伺服器接受頁面斷開重新重新整理後重新載入已經訂閱的channel(redis的單串連問題) socket.on('psuballscribe',function(channelArr,username){ for(var i=0;i<channelArr.length;i++){ subscribe.psubscribe(channelArr[i]); } }) //發行者在某個channel發送訊息的時候,訂閱頻道的redis連結監聽這個訊息和該頻道 subscribe.on('pmessage',function(pattern,channel,message){ socket.emit('message',{channel:channel,data:message}) })})
下面是index.js部分:
exports.index = function(req, res){ var username = req.session.username; var redis = require('redis').createClient(); redis.auth('chenqiguo'); redis.smembers('user:'+username,function(err,results){ //取得目前使用者訂閱的所有channel給模板 res.render('index', { title: 'Express',username:username,result:results}); });};//這裡只能讓登入的使用者有發接受和發布訊息(顯示這樣做不好,但是為了實際說明,就這樣了)exports.login = function(req,res){ var username = req.body.username; if(username != ''){ req.session.username = username; res.redirect('/'); }}
下面是index.ejs部分
<!doctype html><html> <head> <meta charset="utf8" /> <title>nodejs+websocket+express+redis</title> <script src="/socket.io/socket.io.js"></script> <script> window.onload = function(){ var socket = io.connect(); var publish = document.getElementById('publish'); var pub = document.getElementById('pub'); var mess = document.getElementById('mess'); var pubmess = document.getElementById('pubmess'); var subscribe = document.getElementById('subscribe'); var content = document.getElementById('content'); var ulList = document.getElementById('ulList'); //目前使用者添加一個channel subscribe.onclick = function(){ var username = document.getElementById('username'); socket.emit('psubscribe',mess.value,username.innerHTML); } //目前使用者向某一個channel中發布訊息 publish.onclick = function(){ socket.emit('publish',pub.value,pubmess.value); } var li = ulList.getElementsByTagName('li'); var channelRes = []; for(var i=0;i<li.length;i++){ channelRes.push(li[i].innerHTML); } //使用者重新整理的時候把訂閱的所有channel再次去請求socket ,完成channel的訂閱 socket.emit('psuballscribe',channelRes,username.innerHTML); //訂閱了某個channel的所有使用者顯示訊息 socket.on('message', function(message){ var span = document.createElement('span'); span.innerHTML = 'from channel:' + message.channel + '<br />' + 'message:' + message.data; content.appendChild(span); }) ; } </script> </head> <body> <%if(username){%> welcome back <span id="username"><%=username%></span><br /> you sub <ul id="ulList"> //這裡輸出使用者一共訂閱的channel <%for(var i=0;i<result.length;i++){%> <li><%=result[i]%></li> <%}%> </ul> <input type="text" id="mess" /> <button id="subscribe">subscribe</button><br /><br /><br /> publish channel:<input type="text" id="pub" /><br /> publish message:<input type="text" id="pubmess" /><br /> <button id="publish">publish</button> <br /><br /> sed back message from channel<br /> <div id="content" style="width:200px; height:200px;background:red"></div> <%}else{%> <form action="/login" method="post"> <input type="text" name="username" /> <input type="submit" value="join" /> </form> <%}%> </body></html>