您的位置:首页 > 数据库 > Redis

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

2013-08-03 21:48 966 查看
先看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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: