Socket.IO入门

Socket.IO + Node.js实现双工通信

基础知识介绍

WebSocket实现了B/S的全双工通信,其基本思想是保持连接持久打开
Socket.IO是Node.js的一个模块,提供WebSocket通信方式(对于不兼容的系统,使用Ajax长轮询等备选方案)
WebSocket不支持注入重新连接处理,心跳检测等功能,但Socket.IO库提供了这些特性,且解决了跨域问题。

Socket.IO侦听用户连接和断开连接

从零开始,步骤如下:

  1. 服务器端,引入Socket.IO库,并将其套在服务器(server)上:

    var server = http.createServer(function (req,res) {
        fs.readFile('./index.html',function(error,data) {
            res.writeHead(200,{ 'Content-Type': 'text/html' });
            res.end(data,'utf-8');
        });
    }).listen(80,"127.0.0.1");
    var io = require('socket.io').listen(server);
  2. 服务器端,打开connection和disconnect监听

    // 监听客户端连接事件
    io.sockets.on('connection',function (socket) {
        console.log('User connected');
        // 监听离线事件
        socket.on('disconnect',function () {
             console.log('User disconnected');
        });
    });    
  3. 客户端,引入Socket.IO的客户端js库,并连接到指定服务器

    //引入Socket.IO
    

至此,每当有客户端连接或断开连接到服务器的时候,服务器都能够感知(利用这个可做实时在线人数统计

Socket.IO实现服务器和单一客户端双向通信

基于上条功能,服务器和客户端的通信步骤如下:

  • 服务器向客户端发送事件

    1. 服务端添加发射事件代码

      io.sockets.on('connection',function (socket) {
           // 给新连接的用户发送“message”事件(该事件名称任意取),第二个参数为是js对象(不是必须),方便数据处理
           socket.emit('message',{ text: 'You have connected!'});
      
       socket.on('<a href="https://www.jb51.cc/tag/dis/" target="_blank" class="keywords">dis</a>connect',function () {
            console.log('User <a href="https://www.jb51.cc/tag/dis/" target="_blank" class="keywords">dis</a>connected');
       });

      });

    2. 客户端预定message事件

          
  • 客户端向服务器发送事件(和上面一模一样)

    1. 客户端添加发射事件代码

        chatBtn.onclick = function(){
          var value = chatText.value;
          socket.emit('chat',{ text: value});
          chatText.value = '';
        }   
    2. 服务器端预定该事件

         // 监听客户端发送聊天消息事件,并广播给所有客户端
        socket.on('chat',function(data){
          // 广播给所有客户端
          socket.broadcast.emit('getChat',data);
          // 只发给该客户端
          socket.emit('getyourChat',data);
        })
  • 服务器端的广播通信,客户端无权

       使用socket.broadcast.emit(事件名,数据);即可实现! 只要注册过该‘事件名’的客户端,都会收到消息
    

Socket.IO实现客户端之间通信(利用服务器的广播通信)

下图给出了客户端之间通信的必要过程
客户端借助服务器通信

代码汇总

  • 服务器端:

    var http = require('http'),fs = require('fs');
    // 创建服务
     var server = http.createServer(function (req,res) {
        fs.readFile('./index.html',data) {
          res.writeHead(200,{ 'Content-Type': 'text/html' });
          res.end(data,'utf-8');
        });
      }).listen(80,"127.0.0.1");
      console.log('Server running at http://127.0.0.1:3000/');
      // 创建socket服务,附加在server上
      var io = require('socket.io').listen(server);
  // 初始化网站在线人数
  var counter = 0;
  // 监听客户端连接事件
  io<a href="https://www.jb51.cc/tag/so/" target="_blank" class="keywords">.so</a>ckets.on('connection',function (socket) {
    // 使在线人数加1
    counter++;
    // 在服务器端<a href="https://www.jb51.cc/tag/shuchu/" target="_blank" class="keywords">输出</a>消息
    console.log('User connected');
    // 给新连接的<a href="https://www.jb51.cc/tag/yonghu/" target="_blank" class="keywords">用户</a>发送“已连接”<a href="https://www.jb51.cc/tag/tishi/" target="_blank" class="keywords">提示</a>
    socket.emit('message',{ text: 'You have connected!'});
    // 广播通信:给其他<a href="https://www.jb51.cc/tag/yonghu/" target="_blank" class="keywords">用户</a>发送新的在线人<a href="https://www.jb51.cc/tag/shuliang/" target="_blank" class="keywords">数量</a>
    socket.<a href="https://www.jb51.cc/tag/bro/" target="_blank" class="keywords">bro</a>adcast.emit('users',{ number: counter});
    // 还要给新进来的<a href="https://www.jb51.cc/tag/yonghu/" target="_blank" class="keywords">用户</a>单独发送<a href="https://www.jb51.cc/tag/yige/" target="_blank" class="keywords">一个</a>在线人<a href="https://www.jb51.cc/tag/shuliang/" target="_blank" class="keywords">数量</a>,因为广播消息并不会发给这个<a href="https://www.jb51.cc/tag/xinyonghu/" target="_blank" class="keywords">新用户</a>
    socket.emit('users',{ number: counter});
    // 监听离线事件
    socket.on('<a href="https://www.jb51.cc/tag/dis/" target="_blank" class="keywords">dis</a>connect',function () {
        counet--;
      console.log('User <a href="https://www.jb51.cc/tag/dis/" target="_blank" class="keywords">dis</a>connected');
    });
    // 监听客户端发送聊天消息事件,并广播给所有客户端
    socket.on('chat',function(data){
          socket.<a href="https://www.jb51.cc/tag/bro/" target="_blank" class="keywords">bro</a>adcast.emit('getChat',data);
          socket.emit('getyourChat',data);
    })
  });</code></pre>
  • 客户端