express redis socket 消息提醒方案:本地emit 轮循服务器获取redis 再推送
来源:互联网 发布:天下x天下 人祸和知彼 编辑:程序博客网 时间:2024/06/16 22:00
在做项目时,需要实现消息提醒,因为现在有多个项目,都需要实现。
为了实现多项目公用,和以后项目也可以使用。
单独开了个项目,起了个node 服务来实现消息提醒。
用express redis socket.io来实现的。
session 都存在redis里,所有的服务都一样。这样实现了,sessio共享
只要其他项目登录了,消息服务也就登录了。
因为要多个项目共用,所以会在项目中引用socket.io js 然后创建
var socket=io('http://localhost:8007');
链接到8007也就是消息服务器。
消息服务io connection 链接上后,通过socket.request.headers.sookie 来获取请求的cookie 找到connect.sid 得到sid。
再从redis上查找对应的用户信息。保存到链接socket上。然后发送emit open ,表示链接成功。
本地接收到后轮循向服务器发请message 请求来获取消息。
服务器查询redis获取消息,并emit 返回。
以下是服务端代码:
/*star 2016-8-20socket 从请求中获取cookie 也就是token 再从redis里取到token对应的user 信息。这后向socket页面emit(open) 表示当前登录用户链接socket成功。本地轮循发起emit message 事件,获取用户的提示条数。服务器根据 userid 从redis里读取提示条数并返回。----此为node socket 消息服务器第一种解决方案*/var express = require('express');var path = require('path');var cookieParser = require('cookie-parser');var bodyParser = require('body-parser');var session = require('express-session');var RedisStore = require('connect-redis')(session);var http = require('http');var redis_api=require('./redis_api.js')var port=8007;var app = express();// view engine setupapp.use(bodyParser.json());app.use(bodyParser.urlencoded({ extended: false }));app.use(cookieParser());app.use(express.static(path.join(__dirname, 'public')));// 设置 Sessionapp.use(session({ store: new RedisStore({ host: "127.0.0.1", port: 6379, db: 0 //pass: 'yu' }), resave:false, saveUninitialized:false, secret: 'keyboard cat'}))app.use(function(req,res,next){ console.log(req.url); next();})app.get('/socket',function(req,res){res.header("Access-Control-Allow-Origin", "*");//console.log(req.session.username)res.send(req.session)})var server = http.createServer(app);server.listen(port);server.on('error', onError);server.on('listening', onListening);var io=require('socket.io')(server);var users=[]io.on('connection',function(socket){console.log('open')//获取请求cookievar cookie_string=decodeURIComponent(socket.request.headers.cookie)//正则匹配 获取sidvar s=/connect.sid=([^\.]+)/g.exec(cookie_string);var sid='';if(s && s.length>1){sid=s[1].split(':')[1];//console.log(sid);var user;redis_api.getsid(sid,function(err,res){if(!err){user=res;socket.emit('open',{sid:sid,user:user.user})socket.sid=sid;socket.user=user.user;//链接数测试/*var n=9000000;while(n--){users.push(socket);}*/}})}socket.on('message',function(res){console.log(res);switch(res.action){case "read":read();break;}})function read(){redis_api.getmessage(socket.user.id,function(err,reply){if(!err){socket.emit('message',{type:1,action:'message',data:reply,number:users.length})}})}socket.on('disconnect',function(){console.log('close')})})function onError(error) { if (error.syscall !== 'listen') { throw error; } var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); break; default: throw error; }}/** * Event listener for HTTP server "listening" event. */function onListening() { console.log('localhost:'+port)}以下是redis_api代码
var redis = require('redis');var client = redis.createClient('6379', '127.0.0.1');exports.getsid=function(sid,call){//client.select('0',function(err){//if(!err){//console.log('select 0',err)client.get('sess:'+sid ,function(err,reply){console.log('------sess:'+sid)console.log('sess:',sid,err,reply)console.log('end ------sess:'+sid)if(err){call(err)}else{//console.log('sess:'+sid+'=',reply)call(0,JSON.parse(reply))}})//}//})}//根据userid 获取消息数exports.getmessage=function(userid,call){client.select('0',function(err){if(!err){client.get('message:'+userid,function(err,reply){if(!err){console.log('message:'+userid+'='+reply)call(0,JSON.parse(reply))}// 关闭链接 //client.quit();})}})}
以下是页面代码:
var socket=io('http://localhost:8007');socket.on('open',function(res){console.log('开了',res)time();//socket.emit('message',{id:1,type:1,action:'read'})})socket.on('message',function(res){console.log(res,new Date());})//以下为轮循发请emit 获取消息数function time(){setInterval(function(){socket.emit('message',{type:1,action:'read'})//socket.emit('message',{type:1,action:'read'})},3000)}
当然这种实现是有问题 的,并不是时时消息提醒。
而且当链接数大时不断轮循会给服务器和带宽带来很大压力。
0 0
- express redis socket 消息提醒方案:本地emit 轮循服务器获取redis 再推送
- express redis socket 消息提醒方案2:订阅redis,推送消息
- Node.Js+Redis+Socket.IO 实现 聊天室或推送消息
- redis 实现消息提醒与历史消息
- redis创建消息推送队列
- 本地搭建redis服务器笔记
- 使用socket接收服务器推送的消息
- android后台线程轮询服务器获取推送消息
- 添加本地消息提醒
- nodejs+express+websocket+redis实现消息订阅系统
- TWaver HTML5 + Node.js + express + socket.io + redis(一)
- TWaver HTML5 + Node.js + express + socket.io + redis(二)
- TWaver HTML5 + Node.js + express + socket.io + redis(三)
- TWaver HTML5 + Node.js + express + socket.io + redis(四)
- TWaver HTML5 + Node.js + express + socket.io + redis(五)
- windows下安装nodejs、 express +、socket.io和redis
- Redis方案
- windows下搭建本地redis服务器
- Java程序员开发参考资源
- CodeForces 687A
- OSG 3.0 Beginners Guide DEC.2010
- Til the Cows Come Home
- 装饰者设计模式
- express redis socket 消息提醒方案:本地emit 轮循服务器获取redis 再推送
- Java高级工程师面试题目汇集
- 关于input type=file 获取文件的路径问题
- Fibsieve`s Fantabulous Birthday
- Python新手学习基础之函数-return语句与函数调用
- 特殊日历计算
- 各种排序算法的总结与比较
- C#自己写的报错机制
- Java中的匿名对象