`
wb284551926
  • 浏览: 539197 次
文章分类
社区版块
存档分类
最新评论

Socket.io 学习笔记三(转载)

 
阅读更多

前言

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

Connect Session

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

  • cookie-based方案数据直接存储在cookie里面,解析之后即可获得。

  • memory-store方案,使用内存做容器,来存储数据,由于中间件使用了闭包特性,如果不对中间件动手脚的话,是无法访问这些数据,而且我是Express和socket.io分离的,更不可能拿到数据,所以此路不通。

  • connect-redis方案,将数据放入redis数据库,这样不同进程都可以获取到session数据。Cookie解析之后获取sessionId,通过sessionId从redis获取数据。

  • mongodb方案,跟redis机理相同,不再赘述。

Connect-redis

  • 启用connect-redis session。
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})
}));
  • socket.io部分
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!!!');
});

Cookie-based更加简单一些

  • Express部分
var express =require('express');
var app = express();
app.use(express.cookieParser('lovestory'));
app.use(express.cookieSession({key: 'lovestory', secret : 'lovestory'});
  • socket.io部分
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,一位用户更新了状态,需要推送给他的朋友,就是需要主动向浏览器端推送消息的时候,如何通知到这个进程。。。。。。。

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

  • Websocket握手阶段是通过HTTP协议完成的,socket.io负责监听upgrade,connection事件,可以与普通 HTTP server共存。通过HTTP模块监听普通http请求,当业务逻辑进程完成相应工作,判定需要向其他用户推送消息时,向推送进程发出http请求,附 带需推送内容即可。

  • 业务逻辑进程与推送进程建立socket连接,当业务逻辑进程完成相应工作,判定需要向其他用户推送消息时,通过socket发送消息即可。

简易实现

  • socket.io与普通HTTP服务同时存在
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 必需。指明需要推送的目标,若typeall,显式声明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连接,基本理念是相同的,就不再往坑里跳。

个人总结

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

原文地址:http://segmentfault.com/blog/bornkiller/1190000000449888

分享到:
评论

相关推荐

    node.js + socket.io 实现点对点随机匹配聊天

    真心佩服那些可以经常发布笔记的人,其实我也想经常发来的,奈何技术不够加上懒,要向大神们多多学习了,前段时间有用bomb平台自带的socket写一个聊天室,其实基本就是改了改它的demo,这次想实现一个随机私聊,所以...

    JAVA网络编程

    Java网络编程---IO部分学习笔记整理 .doc Java网络编程基础 Datagram类使用方法 (1) .doc Java网络编程基础 InetAddress类的使用.doc Java网络编程基础 ServerSocket类使用.doc 《JAVA编程规范》.doc Java基础 三...

    08-java基础汇总学习笔记

    javaSE基础汇总学习笔记整理,javaSE基础、面向对象、IO、反射、常用的类、正则、Socket基础编程等

    J2SE学习笔记(学习源码)

    J2SE学习实例 1、Java的基础知识 2、Java面向对象 3、集合Collection的使用 4、IO使用 5、Socket编程 6、Thread线程技术 7、Subject反射技术 8、GUI图形编程

    java多线程tcpsocketserver源码-netty-learning:网络学习

    socket server源码@Netty 笔记 1. 内蒂 网络应用框架 特征 设计 支持多种传输类型 事件模型 高度可定制的线程模型 表现 高吞吐量,低延迟 更少的资源消耗 最小化内存拷贝 安全SSL/TLS 支持 建筑学 核 事件模型 通用...

    整理后java开发全套达内学习笔记(含练习)

    注意:默认类型转换(自动类型提升)会丢失精度,但只有三种情况: int>float; long>float; long>double. 看一下他们的有效位就明白。 二进制是无法精确的表示 0.1 的。 进行高精度运算可以用java.math包中...

    jsChat:一个简单的进行中的nodewebsockets聊天

    进入jschat目录并通过运行以下命令安装依赖项: npm install (依赖项:express,socket.io,sqlite3) 启动聊天服务器,运行npm start 将您的浏览器定向到localhost:3000 。 如果要使用非本地主机,请在/public/...

    JavaSE笔记.rar

    学习JavaSE做的一些笔记,包括Java基础知识(关键字,语句,常量,变量,运算符,数组,方法),Java面向对象(static,final,封装,继承,多态,内部类等)以及JavaAPI(String,正则,集合,映射,IO,Socket,反射,线程等技术)

    (牛客网C++课程)Linux 高并发Web服务器项目实战(带定时检测代码)

    2. 用 epoll 事件检测技术实现 IO 多路复用,提高运行效率; 3. 采用模拟 Proacto r的事件处理模式,利用线程池实现多线程机制,实现高并发通信,减少频繁创建和销毁线程带来的开销;(信号和互斥锁) 4. 主进程负责...

    java7hashmap源码-network_program:学习java网络编程

    用于存放学习java网络编程过程遇见的重难点笔记和相关代码 附带代码大部分是《java网络编程 第四版》的课程代码 对运算字符串进行识别的作业 @since2020.11.26 IO流 - 多线程 @since2020.11.26 internet地址 @since...

    蔡氏电路matlab仿真代码-taixiu:taixiu

    实时使用socket.io。 该服务器可以处理大量用户。 使用开源HTML,NodeJS设计的代码 易于编辑,无需对编码了解太多 尽量减少使用插件和模块,以避免影响页面加载速度。 清除代码,确保没有恶意代码。 该代码简单,...

    中美 IT 培训 C# Asp.net 全套笔记1

    价值一万八的中美 IT 培训笔记一万多培训费的资料,北京权威的.NET培训机构】 【认真学习后你一定能成为优秀的.net程序员】 学习对象:1.大专及大专以上理工科学历,或有相当学历的理工科教育背景  2.热爱...

    node-tutorial:一些节点教程-《节点学习笔记》

    Node.js教程目录 Node.js API及常用第三方模块 Node.js基础应用 Express及其他服务器框架 Node.js操作数据库 MongoDB基础 MySql基础 Redis基础 会话与令牌 插座 其他 其他教程和笔记

    中美 IT 培训 C# Asp.net 笔记3

    学习流(stream)的概念和IO操作、文件的读写和传输。 掌握多线程编程、文件的操作和程序集的相关概念,学习反射和属性。 第二阶段教学内容安排(400课时) 课程名称 课程内容 培训目的 ASP.Net2.0、ADO.Net2.0和...

    中美 IT 培训 C# Asp.net 笔记2

    学习流(stream)的概念和IO操作、文件的读写和传输。 掌握多线程编程、文件的操作和程序集的相关概念,学习反射和属性。 第二阶段教学内容安排(400课时) 课程名称 课程内容 培训目的 ASP.Net2.0、ADO.Net2.0和...

    值类型与引用类型理论内容.part01.rar

    ASP.NET培训资料(笔记版)(AJAX,C#,JavaScript,SQL) 详细的资料 三个月的课程录像+资料笔记(花了一万六千块的培训资料超值【19G的经典内容】 认真学习后包你能成为优秀的.net程序员 <br>(注明:不是...

    值类型与引用类型理论内容.part05.rar

    C#,JavaScript,SQL) <br>我将不定期发布,直至所有课程完毕 <br>详细的资料 三个月的课程录像+资料笔记(花了一万六千块的培训资料超值【19G的经典内容】 认真学习后包你能成为优秀的.net程序员 ...

    Java复习笔记/Java知识点总结

    同时附赠一份我学习的资料,是github上的一位大神写的,非常棒的笔记,力荐!总结了Java知识、IO、http、socket、redis、git、docker,设计层次比较全,大家可以下载看看,注意文档格式是markdown的。

    Java编程复习代码

    大四学期复习Java基础所产生的代码笔记,着重回顾了字符串、IO、线程以及socket套接字编程,在每一分代码中都附带了自己编程时的一些认识、笔记。适合Java基础不够踏实的童鞋。

    安卓java读取网页源码-JavaAyo:java的学习和测试工程,纯java工程,直接运行main方法

    java的测试项目,可以看做是java的ApiDemo,主要用于学习,也经常用来测试极光,七牛等服务器api, 实际上有什么好代码都可以加进来,直到这个工程不堪其重 目录: 目录 [java高级] [Ayo库] 集合 ConcurrentMap原理...

Global site tag (gtag.js) - Google Analytics