XPENH's Note

做生活的高手。

Xpenh's avatar Xpenh

WebSocket与Socket.io的理解

WebSocket protocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

scoket

HTTP设计的时候,比如浏览器直接发出请求,服务器才能响应。如果浏览器不发出request请求,服务器是不能主动找到浏览器,传输一些数据的。也就是说:浏览器必须主动请求,服务器才会发出响应。

但是现在的web页面,对实时的要求很高:web看股票、篮球比赛图文直播、聊天室、站内信等等。
现在的做法基本都是长轮询,用通俗易懂的话来说,就是客户端不停的(setInterval)向服务器发送请求以获取最新的数据信息。这里的“不停”其实是有停止的,只是我们人眼无法分辨是否停止,它只是一种快速的停下然后又立即开始连接而已。浏览器每隔比如20秒都问一下服务器,有没有人给我发站内信。服务器是不能有新消息就主动通知浏览器的。

HTML5有了一个叫做websocket的协议,允许服务器主动发出通知。
在 WebSocket API,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。在此WebSocket 协议中,为我们实现即时服务带来了两大好处:

  1. Header
    互相沟通的Header是很小的-大概只有 2 Bytes
  2. Server Push
    服务器的推送,服务器不再被动的接收到浏览器的request之后才返回数据,而是在有新数据时就主动推送给浏览器。
    websocket需要浏览器足够新,IE10+。服务器也要足够新,NodeJS天生就支持。

为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息”Upgrade: WebSocket”表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。

接下来谈谈socket.io。它是一个NodeJS用的npm包,简化了websocket的程序开发。不用socket.io也能开发websocket但是极其复杂,比如要设置HTTP头等等。下面是简单的demo。

app.js:

var express = require('express');
var app = express();
var http = require('http').Server(app);
//服务器端存在了一个io对象:
var io = require("socket.io")(http);

app.use(express.static("public"));

app.get('/', function(req, res){
  res.sendFile(__dirname + "/index.html");
});

//增加了一个中间件:
io.on("connect",function(socket){
  //服务器端出现了一个socket对象
  console.log("有人connect了!~~");

  socket.on("ltxx",function(info){
      console.log(info);
  });
});

http.listen(3000, function(){
  console.log('监听3000端口');
});

index.html:

<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>
  </head>
  <body>
    <ul id="messages">
    </ul>
    <form action="">
      <input id="m"  />
      <button>发布</button>
    </form>

    <script type="text/javascript" src="/socket.io/socket.io.js"></script>
    <script src="/jquery-1.12.3.min.js"></script>
    <script>
      var socket = io();
      $("button").click(function(){
        //socket.emit(信息名字,信息值)
        socket.emit('ltxx', $('#m').val());

        //清空文本框
        $('#m').val('');
        return false;
      })
    </script>
  </body>
</html>

浏览器emit了信息,服务器就能listen到。服务器listen使用on函数。

服务器要把自己收到的信息,再次broadcast出去,然后让所有的html页面都能够收听服务器的广播即可。

scoket