首页 > 代码库 > Socket.IO学习日志

Socket.IO学习日志

说到学习Socket.IO,就不得不先说说WebSocket。

  WebSocket可以说是一种协议,它建立在无状态的HTTP协议基础之上。从字面的意思来理解,就是将TCP的Socket(套接字)应用在了HTTP中,从而使通信双方建立起一个保持在活动状态连接通道,并且是一个全双工(两个设备之间同时进行双向通信)。

与Ajax不同,它并非面向请求和响应,而是可以直接通过send方法进行消息传递。WebSocket可以说是Socket.IO的一个子集,Socket.IO的底层实现其实有5种方式,WebSocket只是其中一种。在默认的情况下,我们建立的socket.io连接,底层也是调用websocket的实例。当我们io.connect()建立一个socket连接的时候,返回的是namespace实例,namespace实例中又有个socket实例,当新建一个连接,或者发送一条消息的时候,namespace->socket->transport->websocket(xhrpolling...),其实发送一条消息真正的发送者还是底层的websocket或是xhrpolling或其他的几种,而socket.io只是一个组织者,当我们需要建立连接的时候,它自己会在其内部挑选一种连接方式,然后实现连接。

WebSocket的工作方法:

  • 服务器端:初始化服务器并将websocket.io绑定到上面,然后监听事件,把消息send到客户端。
  • 客户端:初始化WebSocket并和服务器建立连接,发送信息。

Socket.IO和WebSocket的比较:

  1. Socket.IO 消息的传递是基于传输的,但不全部依靠 WebSocket,支持绝多的浏览器和设备,包括 IE6 和 iOS ,而 WebSocket 属于 HTML5 的范畴,早期的浏览器不支持。
  2. Socket.IO 提供了可靠的事件机制,它监听的是 connect 和 disconnect 事件,而不是 open 和 close 事件。
  3. Socket.IO 连接丢失时默认自动重连,WebSocket 一般要刷新浏览器。
  4. Socket.IO 支持你像WebSocket那样传输简单文本信息,还可以通过分发(emit) 和监听(listen)事件来进行JSON数据的分发。
  5. Socket.IO 支持在单个连接中利用命名空间来区分各种消息。 
  6. Socket.IO 可以方便地进行广播,不用自己定义广播机制。

Socket.IO的工作方法:socket.io最主要的是emit和on两个函数

  1. socket.emit提交(发出)一个事件,事件名称可以自定义,也有一些默认的事件(connection,message,disconnect),紧接着是一个对象,表示向该socket发送的内容。
  2. socket.on接收一个事件,紧接着是收到事件调用的回调函数,其中data是收到的数据。
  3. 内置默认的事件名例如,io.on函数接受"connection"作为客户端发起连接的事件,当连接成功后,调用带有socket参数的回调函数,“disconnect”表示客户端连接断开,“message”表示收到消息等等。自定义的事件名称,尽量不要跟Socket.IO中内置的默认事件名重名,以免造成不必要的麻烦。
  • 服务器端:将socket.io绑定到常规的http.Server上,
    var app = require(‘express‘)();var server = require(‘http‘).Server(app);var io = require(‘socket.io‘)(server);server.listen(80);

    设置监听器

    io.on(‘connection‘, function (socket) {  socket.emit(‘news‘, { hello: ‘world‘ });  socket.on(‘my other event‘, function (data) {    console.log(data);  });});
  • 客户端:当Socket.IO被绑定到http.Server上时,会自动拦截以 /socket.io 开头的URL,并重定向。socket.io.js实际放在了服务器端的node_modules文件夹中。你也可以把这个文件拷贝到本地,使它成为客户端的js文件,这样就不用每次都向Node服务器请求,增强稳定性。
    <script src="http://www.mamicode.com/socket.io/socket.io.js"></script><script>  var socket = io(); // TIP: io() with no args does auto-discovery  socket.on(‘connect‘, function () { // TIP: you can avoid listening on `connect` and listen on events directly too!    socket.emit(‘ferret‘, ‘tobi‘, function (data) {      console.log(data); // data will be ‘woot‘    });  });</script>

常用API:

  • 向所有客户端发送消息:io.emit

    // the following two will emit to all the sockets connected to `/`io.sockets.emit(‘hi‘, ‘everyone‘); // v0.9的,v1.0还支持io.emit(‘hi‘, ‘everyone‘); // 简短形式,推荐用这个
  • 进入一个房间,向房间发送消息(自己也能收到),离开房间:socket.join, io.to, socket.leave

    io.on(‘connection‘, function(socket){  socket.join(‘some room‘);  io.to(‘some room‘).emit(‘some event‘): // in和to实现相同效果,io.in().emit();
    socket.leave(‘some room‘);});
  • 向一个房间广播消息(自己收不到消息):socket.broadcast.to(‘some room‘).emit(‘message‘); room换成id

    io.on(‘connection‘, function(socket){  socket.on(‘say to someone‘, function(id, msg){    socket.broadcast.to(id).emit(‘my message‘, msg); // id为socket#id  });});
  • 当成WebSocket来用:(客户端)socket.send(‘hi‘),(服务器)用socket.on(‘message‘, function(data){})来接收。

参考资料:http://socket.io/docs/

http://raytaylorlin.com/Tech/web/Nodejs/socket-io-tutorial/

http://blog.csdn.net/jiangcs520/article/details/17287531