nodejs+express+websocket+redis实现消息订阅系统

来源:互联网 发布:触摸查询一体机软件 编辑:程序博客网 时间:2024/06/16 00:25
 先看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>


原创粉丝点击