• SSE与WebSocket


      Ajax是一种从页面向服务器请求数据的技术,Comet则是一种服务器向页面推送数据的技术,它能够让信息近乎实时地被推送到页面上。

      有两种实现Comet的方式:长轮询和流。

      长轮询是浏览器定时向服务器发送请求,然后服务器一直保持连接打开,直到有数据可发送。发送完数据后,浏览器关闭连接,随即发起一个新的请求。

      短轮询与长轮询的区别是,服务器接收到请求后,是否立即发送响应。短轮询是服务器会立即发送响应,无论数据是否有效。而长轮询是等待发送响应。所有浏览器都支持轮询,使用xhr对象和setTimeOut()就能实现。

       HTTP流,浏览器向服务器发送一个请求,而服务器保持连接打开,然后周期性地向浏览器发送数据。

      在FirefoxSafariOperaChrome中,通过侦听readystatechange事件及检测readyState属性的值是否为3,就可以实现HTTP流。当readyState值变为3时,responseText属性中就会保存就收到的所有数据,此时,就需要比较此前接收到的数据,决定从什么位置开始取得最新的数据。代码如下:

     1 function createStreamingClient(url,progress,finished){
     2     var xhr = new XMLHttpRequest(),received = 0;
     3     xhr.open("get",url,true);
     4     xhr.onreadystatechange = function(){
     5         var result;
     6         if(xhr.readyState == 3){
     7             result = xhr.responseText.substring(received);
     8             received += result.length;
     9             
    10             progress(result);
    11             
    12         }else if(xhr.readyState == 4){
    13             finished(xhr.responseText);
    14         }
    15         
    16     };
    17     xhr.send(null);
    18 
    19     return xhr;    
    20 }
    21 
    22 var client = createStreamingClient("streaming.php",function(data){
    23                 alert("received:"+data);
    24             },function(data){
    25                 alert("done!");
    26             });
    View Code

      SSE(Server-Sent Events,服务器发送事件)用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据。服务器响应的MIME类型必须是text/even-stream,而且是浏览器中的JavaScript API能解析格式输出。SSE支持短轮询、长轮询和HTTP流,而且能在断开连接时自动确定何时重新连接。

      支持SSE的浏览器有Firefox 6+、Safari5+、Opera11+、Chrome和iOS4+版Safari。

      1、SSE API,创建EventSource对象,并传入一个入口点。传入的url必须与创建对象的页面同源(相同的URL模式、域及端口)。

    var source = new EventSource("myevents.php");

      EventSource的实例有个readyState属性,值为0表示正连接到服务器,为1表示打开了连接,为2表示关闭了连接。

      包含三个事件,open:在建立连接时触发,message:在从服务器接收到新事件时触发,error:在无法建立连接时触发。

    source.onmessage = function(event){
       var data = event.data;//服务器返回的数据以字符串形式保存在event.data中
       //...      
    };

      默认情况下,EventSource对象会保持与服务器的活动连接。如果连接断开,还会重新连接,适合长轮询和HTTP流。立即断开不再重新连接,使用close()。

    source.close();

      2、事件流,服务器事件会通过一个持久的HTTP响应发送,这个响应的MIME类型为text/event-stream。响应的格式是纯文本。

      WebSocket,是一种与服务器进行全双工、双向通信的信道。在JavaScript中创建了WebSocket之后,会有一个HTTP请求发送到浏览器以发起连接。在取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为Web Socket协议。

      websocket使用了自定义的协议,使用的URL模式也有所改变。未加密的连接不再是http://,而是ws://;加密的连接不是https://,而是wss://。

      使用自定义的协议好处是,能够在客户端和服务器之间发送非常少量的数据,而不必担心HTTP那样字节级的开销。比较适合移动应用。缺点是安全性和协议的一致性,目前支持的浏览器有Firefox6+、Safari5+、Chrome和iOS4+版Safari。

      1、websocket API,创建一个实例,传入绝对路径的url。同源策略对websocket不适用。

    var socket = new WebSocket("ws://www.example.com/server.php");

      实例化websocket对象后,浏览器就会马上尝试创建连接。readyState属性表示当前状态,值如下:

    • WebSocket.OPENING(0),正在建立连接
    • WebSocket.OPEN(1),已经建立连接
    • WebSocket.CLOSING(2),正在关闭连接
    • WebSocket.CLOSE(3),已经关闭连接

      2、发送和接收数据,只能发送纯文本数据,对复杂的数据结构需要进行序列化。服务器发来消息时,就会触发message事件。 

    socket.send("hello!"); 
    socket.onmessage = function(event){
       var data = event.data;
       //...  
    };

      3、其他事件,open:成功建立连接时触发,error:在发生错误时触发,连接不能持续,close:关闭连接时触发。

        WebSocket不支持DOM2级事件侦听器,必须使用DOM0级语法分别定义每个事件处理程序。

    socket.onopen = function(){
       console.log("Connection established") ;
    };
    socket.onerror = function(){
       console.log("Connection error");
    };
    socket.onclose = function(){
      console.log("Connection closed");
    };

      考虑使用SSE还是Websocket时,首先看是否有自由度建立和维护WebSocket服务器,因为WebSocket协议不同于HTTP协议,现有服务器不能用于WebSocket通信。SSE则可以通过常规HTTP通信。其次,是否需要双向通信。如果只需要读取服务器数据,SSE比较容易实现。如果需要双向通信,WebSocket更好一些。组合XHR和SSE也是能实现双向通信的。

    摘自《JavaScript高级程序设计》  

  • 相关阅读:
    [转]VMware-Transport(VMDB) error -44:Message.The VMware Authorization Service is not running解决方案
    [转]DNS服务器原理详解与Centos6.x下搭建DNS服务器
    [转]美国最大婚恋交友网站eHarmony的机器学习实践
    [转]Algolia的分布式搜索网络架构
    预测建模、监督机器学习和模式分类概览
    Java正则表达式
    Ajax入门
    JSON入门
    JSTL与EL表达式
    Servlet与JSP进阶
  • 原文地址:https://www.cnblogs.com/Youngly/p/7510549.html
Copyright © 2020-2023  润新知