[关闭]
@bornkiller 2014-10-10T08:32:42.000000Z 字数 4097 阅读 3368

Socket.io 学习笔记三

socket.io nodejs

前言

上次说到关于socket连接授权的问题,有好心人提示说到session-socket开源项目,可以在建立连接后进行session相关操作,操作挺方便,很感谢这位朋友。我的目的是在握手阶段,通过会话判定权限,暨是否建立连接,所以只能自己查阅中间件代码,然后COPY需要的。

Connect Session

Connect相关的会话存储我知道四种,cookie-based,memory-store,redis,mongodb.

Connect-redis

  1. var express =require('express');
  2. var app = express();
  3. var RedisStore = require('connect-redis')(express);
  4. app.use(express.cookieParser('love'));
  5. app.use(express.session({key: 'lovestory', secret: 'lovestory',
  6. store: new RedisStore({ host: '127.0.0.1', port: 6379})
  7. }));
  1. var io = require('socket.io').listen(1338);
  2. var utils = require('connect/lib/utils.js');
  3. var cookie = require('connect/node_modules/cookie-parser/node_modules/cookie');
  4. var redis = require('redis');
  5. var client = redis.createClient(6379,'127.0.0.1');
  6. //连接授权判定,相关参数需要跟启用Session的参数相同
  7. io.sockets.authorization(function (handshakeData, callback) {
  8. //cookie解析,获取sessionId
  9. var cookies = handshakeData.headers.cookie;
  10. var secret = 'lovestory';
  11. var key = 'lovestory';
  12. var prefix = 'sess:';
  13. var sessionId = null;
  14. if (cookies) {
  15. cookies = cookie.parse(cookies);
  16. cookies = utils.parseSignedCookies(cookies, secret);
  17. cookies = utils.parseJSONCookies(cookies);
  18. if(cookies[key]) {
  19. sessionId = cookies[key];
  20. }
  21. }
  22. //从redis获取数据
  23. var sid = prefix + sessionId;
  24. client.get(sid,function(err,data){
  25. var result = JSON.parse(data);
  26. if (result.user){
  27. for (var i in handshakeData) {
  28. delete handshakeData[i];
  29. }
  30. handshakeData.user = result.user;
  31. callback(null,true);
  32. }else{
  33. callback(null,false);
  34. }
  35. });
  36. });
  37. //存储user,socketId键值对,需要单点推送的时候通过user获取对应的socketId即可。
  38. io.sockets.on('connection', function (socket) {
  39. client.set(socket.handshake.user,socket.id);
  40. io.sockets.socket(socket.id).send('Do you love this girl!!!');
  41. });
  1. var express =require('express');
  2. var app = express();
  3. app.use(express.cookieParser('lovestory'));
  4. app.use(express.cookieSession({key: 'lovestory', secret : 'lovestory'});
  1. var io = require('socket.io').listen(1338);
  2. var utils = require('connect/lib/utils.js');
  3. var cookie = require('connect/node_modules/cookie-parser/node_modules/cookie');
  4. //连接授权判定,相关参数需要跟启用Session的参数相同
  5. io.sockets.authorization(function (handshakeData, callback) {
  6. //cookie解析,获取cookie中的session数据
  7. var cookies = handshakeData.headers.cookie;
  8. var secret = 'lovestory';
  9. var key = 'lovestory';
  10. if (cookies) {
  11. cookies = cookie.parse(cookies);
  12. cookies = utils.parseSignedCookies(cookies, secret);
  13. cookies = utils.parseJSONCookies(cookies);
  14. if(cookies[key]) {
  15. session = JSON.parse(cookies[key]);
  16. }
  17. }
  18. });

问题引申

上述代码比较原始,因为基本上是COPY出来的,不过可以实现我最初的想法。但是新问题也冒出来了,我如何得知,什么时候,需要向哪些用户,推送什么消息。例如SNS,一位用户更新了状态,需要推送给他的朋友,就是需要主动向浏览器端推送消息的时候,如何通知到这个进程。。。。。。。

粗略构想(“进程”只为叙述方便,略有不妥)

简易实现

  1. var http = require('http');
  2. var app = http.createServer(function(req,res){});
  3. var io = require('socket.io').listen(app);
  4. app.listen(1338);
字段 功能
type 必需。single,room,或all,对应单点推送,群组推送,全局推送
pointer 必需。指明需要推送的目标,若typeall,显式声明true
content 必需。指明需要推送的内容
  1. function(req,res){
  2. jsonBody(req,res,function(err,data){
  3. if(err) {
  4. res.statusCode = 400;
  5. res.end('Bad request, json body only');
  6. }else{
  7. if (data.type && data.pointer && data.content) {
  8. switch (data.type) {
  9. case 'all' :
  10. io.sockets.send(data.content);
  11. res.end('success');
  12. break;
  13. case 'room' :
  14. io.sockets.in(data.pointer).send(data.content);
  15. res.end('success');
  16. break;
  17. case 'single' :
  18. client.get(data.pointer, function(err,result){
  19. if(result) {
  20. io.sockets.socket(result).send(data.content);
  21. res.end('success');
  22. }
  23. })
  24. default :
  25. res.end('unexpected type');
  26. break;
  27. }
  28. }else{
  29. res.end('Bad request!');
  30. }
  31. }
  32. })
  33. }

代码还欠缺很多打磨,不过基本功能已经出来了。

个人总结

到此为止,socket.io常规使用已经全部over,涉及到的相关代码私下继续打磨。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注