上次说到关于socket链接受权的问题,有好心人提示说到session-socket开源项目,能够在创建链接后进行session相关操做,操做挺方便,很感谢这位朋友。个人目的是在握手阶段,经过会话断定权限,暨是否创建链接,因此只能本身查阅中间件代码,而后COPY须要的。javascript
Connect相关的会话存储我知道四种,cookie-based,memory-store,redis,mongodb.java
cookie-based方案数据直接存储在cookie里面,解析以后便可得到。node
memory-store方案,使用内存作容器,来存储数据,因为中间件使用了闭包特性,若是不对中间件动手脚的话,是没法访问这些数据,并且我是Express和socket.io分离的,更不可能拿到数据,因此此路不通。redis
connect-redis方案,将数据放入redis数据库,这样不一样进程均可以获取到session数据。Cookie解析以后获取sessionId,经过sessionId从redis获取数据。mongodb
mongodb方案,跟redis机理相同,再也不赘述。数据库
var express =require('express'); var app = express(); var RedisStore = require('connect-redis')(express); app.use(express.cookieParser('love')); app.use(express.session({key: 'lovestory', secret: 'lovestory', store: new RedisStore({ host: '127.0.0.1', port: 6379}) }));
var io = require('socket.io').listen(1338); var utils = require('connect/lib/utils.js'); var cookie = require('connect/node_modules/cookie-parser/node_modules/cookie'); var redis = require('redis'); var client = redis.createClient(6379,'127.0.0.1'); //链接受权断定,相关参数须要跟启用Session的参数相同 io.sockets.authorization(function (handshakeData, callback) { //cookie解析,获取sessionId var cookies = handshakeData.headers.cookie; var secret = 'lovestory'; var key = 'lovestory'; var prefix = 'sess:'; var sessionId = null; if (cookies) { cookies = cookie.parse(cookies); cookies = utils.parseSignedCookies(cookies, secret); cookies = utils.parseJSONCookies(cookies); if(cookies[key]) { sessionId = cookies[key]; } } //从redis获取数据 var sid = prefix + sessionId; client.get(sid,function(err,data){ var result = JSON.parse(data); if (result.user){ for (var i in handshakeData) { delete handshakeData[i]; } handshakeData.user = result.user; callback(null,true); }else{ callback(null,false); } }); }); //存储user,socketId键值对,须要单点推送的时候经过user获取对应的socketId便可。 io.sockets.on('connection', function (socket) { client.set(socket.handshake.user,socket.id); io.sockets.socket(socket.id).send('Do you love this girl!!!'); });
var express =require('express'); var app = express(); app.use(express.cookieParser('lovestory')); app.use(express.cookieSession({key: 'lovestory', secret : 'lovestory'});
var io = require('socket.io').listen(1338); var utils = require('connect/lib/utils.js'); var cookie = require('connect/node_modules/cookie-parser/node_modules/cookie'); //链接受权断定,相关参数须要跟启用Session的参数相同 io.sockets.authorization(function (handshakeData, callback) { //cookie解析,获取cookie中的session数据 var cookies = handshakeData.headers.cookie; var secret = 'lovestory'; var key = 'lovestory'; if (cookies) { cookies = cookie.parse(cookies); cookies = utils.parseSignedCookies(cookies, secret); cookies = utils.parseJSONCookies(cookies); if(cookies[key]) { session = JSON.parse(cookies[key]); } } });
上述代码比较原始,由于基本上是COPY出来的,不过能够实现我最初的想法。可是新问题也冒出来了,我如何得知,何时,须要向哪些用户,推送什么消息。例如SNS,一位用户更新了状态,须要推送给他的朋友,就是须要主动向浏览器端推送消息的时候,如何通知到这个进程。。。。。。。express
Websocket握手阶段是经过HTTP协议完成的,socket.io负责监听upgrade,connection事件,能够与普通HTTP server共存。经过HTTP模块监听普通http请求,当业务逻辑进程完成相应工做,断定须要向其余用户推送消息时,向推送进程发出http请求,附带需推送内容便可。json
业务逻辑进程与推送进程创建socket链接,当业务逻辑进程完成相应工做,断定须要向其余用户推送消息时,经过socket发送消息便可。浏览器
var http = require('http'); var app = http.createServer(function(req,res){}); var io = require('socket.io').listen(app); app.listen(1338);
HTTP请求body部分目测须要包含如下信息。
服务器
字段 | 功能 |
---|---|
type |
必需。single ,room ,或all ,对应单点推送,群组推送,全局推送 |
pointer |
必需。指明须要推送的目标,若type 为all ,显式声明true |
content |
必需。指明须要推送的内容 |
事件监听函数(请原谅个人大嵌套~~|||)
function(req,res){ jsonBody(req,res,function(err,data){ if(err) { res.statusCode = 400; res.end('Bad request, json body only'); }else{ if (data.type && data.pointer && data.content) { switch (data.type) { case 'all' : io.sockets.send(data.content); res.end('success'); break; case 'room' : io.sockets.in(data.pointer).send(data.content); res.end('success'); break; case 'single' : client.get(data.pointer, function(err,result){ if(result) { io.sockets.socket(result).send(data.content); res.end('success'); } }) default : res.end('unexpected type'); break; } }else{ res.end('Bad request!'); } } }) }
代码还欠缺不少打磨,不过基本功能已经出来了。
到此为止,socket.io常规使用已经所有over,涉及到的相关代码私下继续打磨。