转载自:http://deadhorse.me/nodejs/2011/12/29/socket.io_induction.html

socket.io

socket.io是一个以实现跨浏览器、跨平台的实时应用为目的的项目。针对不同的浏览器版本或者不同客户端会做自动降级处理,选择合适的实现方式(websocket, long pull..),隐藏实现只暴露统一的接口。可以让应用只关注于业务层面上。
nodejs服务器端安装:npm install socket.io
安装之后就可以require模块来使用了:

  1. var sio = require('socket.io');

在客户端的话,可以通过

  1. <script src="/socket.io/socket.io.js"></script>

或者引用socket.io的CDN服务。

  1. <script src="http://cdn.socket.io/stable/socket.io.js"></script>

在它的官方网站上有各种用法的介绍。

实际使用

这个项目是搭建在connect之上的,因此需要在connect上使用socket.io,同时,因为编辑文件有权限限制,因此还需要在socket.io中使用session和一些其他的连接信息来确认权限。
先看一下socket.io的使用, 服务端:

  1. var io = require('socket.io').listen(80);
  2. io.sockets.on('connection', function(socket){
  3. socket.emit('news', { hello: 'world' });
  4. socket.on('my other event', function(data){
  5. console.log(data);
  6. });
  7. });

浏览器端:

  1. <script src="/socket.io/socket.io.js"></script>
  2. <script>varsocket=io.connect('http://localhost');socket.on('news',function(data){console.log(data);socket.emit('my other event',{my:'data'});});</script>

在服务端收到connection的事件的时候,socket会携带一个建立连接时浏览器端传过来的握手信息socket.handshake,我们把它打印出来大概会是下面这个样子:


  1. { headers:
  2. {
  3. host: 'cnodejs.net:8080',
  4. connection: 'keep-alive',
  5. referer: 'http://cnodejs.net:8080/editor/pipe',
  6. 'user-agent': 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.124 Safari/534.30',
  7. accept: '*/*',
  8. 'accept-encoding': 'gzip,deflate,sdch',
  9. 'accept-language': 'zh-CN,zh;q=0.8',
  10. 'accept-charset': 'UTF-8,*;q=0.5',
  11. cookie: 'NAEIDE_console_hide=0; lzstat_uv=7551240663017376909|2341473@2717849; lzstat_ss=2468024318_3_1325124834_2717849; connect.sid=z5sT8ER8SIzyknF6HYnIEdWz.l6oFdxYR24fSV85JIpLcpBabQtqDPB%2BUPm1DR1wqAEU; NAE_c_location=BOTTOM; NAE_c_display=1'
  12. },
  13. address: { address: '123.157.218.120', port: 60285 },
  14. time: 'Thu Dec 29 2011 02:21:23 GMT+0800 (CST)',
  15. query: { t: '1325096038995' },
  16. url: '/socket.io/1/?t=1325096038995',
  17. xdomain: false,
  18. secure: undefined
  19. }

这些浏览器端的信息得到之后,就很容易进行权限的验证了。socket.io同时提供了


  1. io.set(authorization, callback);

方法来对每个连接进行权限限制。

session与权限验证

权限验证非常重要的一部分就是session验证了,在handshake信息中,可以获取到浏览器端的cookie信息,根据connect(express也一样)的session机制,在cookie中有一项为connect.sid,存放了session在服务器端存储容器中存放的key,通过这个key我们就可以获取到session值。


  1. var io = require('socket.io').listen(app);
  2. var ep = require('EventProxy.js').EventProxy;
  3. var parseCookie = require('connect').utils.parseCookie;
  4. io.set('authorization', function(data,accept){
  5. var proxy = new ep();
  6. //get sessionId from cookie & get session from sessionStore
  7. var parse = function(){
  8. if(data.headers.cookie){
  9. //use parseCookie in connect.utils
  10. data.cookie = parseCookie(data.headers.cookie);
  11. data.sessionId = data.cookie['connect.sid'];
  12. //getSession( by connect sessionStore.get)
  13. SessionStore.get(data.sessionId, function(err,session){
  14. if(err || !session){
  15. proxy.unbind();
  16. return accept(err.toString(), false);
  17. }else{
  18. data.session = session;
  19. proxy.fire('session_got');
  20. }
  21. })
  22. }else{
  23. proxy.unbind();
  24. return accept('No cookie transmitted.', false);
  25. }
  26. }
  27. //get auth form database
  28. var checkAuth = function(){
  29. //get info in referer
  30. data.app = getApp(data.headers.referer||'');
  31. //check auth
  32. check(data.session.user, data.app, function(err,result){
  33. if(result){
  34. accept(null, true);
  35. }else{
  36. accept(err?err.message:'permision denied.', false);
  37. }
  38. })
  39. }
  40. proxy.once('session_got', checkAuth);
  41. parse();
  42. })

通过socket.io完成时事通信

此时所有经过验证的连接的handshake信息里,已经多出了app和session的信息,我们把这些连接按照app来分类,因为所有的app相同的连接,收到的信息也将是相同的。


  1. io.sockets.on('connection', function(socket){ // some socket connect
  2. var hs = socket.handshake;
  3. //when socket connect, put this socket into room [hs.app]
  4. socket.join(hs.app);
  5. //some socket disconnect
  6. socket.on('disconnect', function(){
  7. });
  8. });
  9. var proxy = new ep();
  10. //when get stdout data, send msg to sockets in this room
  11. proxy.on('stdout', function(data){
  12. io.sockets.in(data.room).send(data.log);
  13. })
  14. getData(data){
  15. proxy.fire('stdout', data);
  16. }

此时只要获取到了输出信息,就会通过socket.io传递到页面,触发页面的'message'事件,渲染页面。

关闭debug信息

在socket.io启用的时候,会不停的打出debug和心跳等信息,在生产环境下我们不想要这么详细的输出,可以通过

  1. io.set('log level', 1);

来关闭调试信息的输出。

总结

socket.io是nodejs实现实时web系统的不二选择,特别是非常符合nodejs的事件驱动特性,不需要绕弯就能够完成实时系统。

socket.io 入门教程的更多相关文章

  1. socket.io入门整理教程

    socket.io入门整理  发布于 5 年前  作者 dtrex  124983 次浏览  最后一次编辑是 1 年前 我自己在用socket.io开发,对官方网站上的文档,进行简单的整理,然后自己写 ...

  2. 最基础的Python的socket编程入门教程

    最基础的Python的socket编程入门教程 本文介绍使用Python进行Socket网络编程,假设读者已经具备了基本的网络编程知识和Python的基本语法知识,本文中的代码如果没有说明则都是运行在 ...

  3. Socket.io 入门 - Renyi的博客

    Socket.io Vue 中使用 NPM 安装 npm install vue-socket.io --save npm install --save socket.io-client 引用 详情 ...

  4. Node.js、Express、Socket.io 入门

    前言 周末断断续续的写了第一个socket.io Demo.初次接触socket.io是从其官网看到的,看着get started做了一遍,根据官网的Demo能提供简单的服务端和客户端通讯. 这个De ...

  5. 转载:socket.io 入门

    原文链接:http://cnodejs.org/topic/50a1fcc7637ffa4155b5a264 我自己在用socket.io开发,对官方网站上的文档,进行简单的整理,然后自己写了一个简单 ...

  6. socket.io 入门篇(三)

    本文原文地址:https://www.limitcode.com/detail/5926e3a056fba70278bf2044.html 前言 上篇我们介绍了 socket.io 中room的概念和 ...

  7. socket.io 入门篇(二)

    本文原文地址:https://www.limitcode.com/detail/5922f1ccb1d4fe074099d9cd.html 前言 上篇我们介绍了 socket.io 基本使用方法,本篇 ...

  8. socket.io 入门篇(一)

    本文原文地址:https://www.limitcode.com/detail/591b114bb1d4fe074099d9c9.html 前言 本篇介绍使用node.js模块组件socket.io实 ...

  9. socket.io入门整理

    我自己在用socket.io开发,对官方网站上的文档,进行简单的整理,然后自己写了一个简单的聊天程序. 最最开始 先安装socket.io: 1 npm install socket.io 利用Nod ...

随机推荐

  1. hdu----(1671)Phone List(Trie带标签)

    Phone List Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. 张艾迪(创始人):拥抱单身与自由的Eidyzhang

    拥抱单身与自由(Single+Freedom) 拥抱伟大的梦想与理想.年轻一代的张扬与自信 拥抱AOOOiA.Global.224C的一切是我对这个世界的态度 +AOOOiA.Global.224C创 ...

  3. DB、ETL、DW、OLAP、DM、BI关系结构图

    DB.ETL.DW.OLAP.DM.BI关系结构图 在此大概用口水话简单叙述一下他们几个概念: (1)DB/Database/数据库——这里一般指的就是OLTP数据库,在线事物数据库,用来支持生产的, ...

  4. struts2视频学习笔记 24-27(国际化)

    课时24 配置国际化全局资源文件.输出国际化信息 1.准备资源文件,添加到src目录下,资源文件的命名格式如下:baseName_language_country.propertiesbaseName ...

  5. echart饼状图的学习

    一.引入js文件 <!--Step:1 引入一个模块加载器,如esl.js或者require.js--> <script src="~/Scripts/esl.js&quo ...

  6. 快速将excel数据保存到Oracle数据库中【转】

    我们在工作中,也许会碰到以下情况,客户或者同事发来需要调查的数据,并不是dmp文件,而是excel文件,此时通常是一张表,少量几条记录.最近我恰好碰到了这种情况,所以做了些调查,不敢藏私,拿出来跟大家 ...

  7. 如何提取HTML代码中img的src地址?

    答案:专门的代码 使用专门的正则表达式 /// <summary> /// 获得HTML中所有图片的src地址[比较稳定的一个版本] /// </summary> /// &l ...

  8. vim命令/压缩和解压命令

    gzip命令 -d 解压 -#  1 为最快 但容量问题 . 9为最好 .6为默认 gzip install.log 比较好理解,windows里面类似的,记住zip 和unzip是可以目录或者文件解 ...

  9. mark 一下

    Android资源管理框架(Asset Manager)简要介绍和学习计划 http://www.cnblogs.com/hjtdlx/p/4332060.html

  10. python 爬虫

    import urllib2 as url import re urls = 'http://www.php100.com/html/it/' headers = {'User-Agent':'Moz ...