• SSE及相关技术(web sockets, long polling等)


    server-sent events--One Way Messaging

      

      


      

      允许网页获得来自服务器的更新,并且自动更新

    • Server-Sent Events: allow a web page to get updates from a server 
    • This was also possible before, but the web page would have to ask if any updates were available. With server-sent events, the updates come automatically.
    • Examples: Facebook/Twitter updates, stock price updates, news feeds, sport results, etc.

      原理如下:

    1. client利用regular http请求webpage
    2. 请求的webpage 执行javascript脚本,open a connection to server.
    3. 当有新的信息时服务器将信息发送给client

    HTML5 SSE

    浏览器支持情况:

    desktop:

    mobile:

    使用入门:


    receive Server-Sent Event Notifications: (接收Server-sent事件通知)

    利用EventSource的onmessage获取消息

    EventSource事件如下:

    onopen   当服务器连接被打开时   When a connection to the server is opened
    
    onmessage   当接收到消息       When a message is received
    
    onerror

    创建和关闭

    var source = new EventSource();
    
    source.close();

     数据格式:

    data: My message
    
    

     如果数据比较长时,可以采用多行data:然后使用event.data.split(' ').join('')组合数据

    data: first line
    
    data: second line
    
    

     简单例子:

    eg:html页面:

    <!DOCTYPE html>
    <html>
    <head>
    <style>
    div{
        border-radius: 10px;
        border: 2px solid pink;
    }
    </style>
    </head>
    <body>
    <h1></h1>
    <div id="result"></div>
    
    <script>
    if(typeof(EventSource)!=="undefined")   //监测是否支持EventSource
      {
      var source=new EventSource("sseServer.jsp");
      source.onmessage=function(event)
        {
        document.getElementById("result").innerHTML+=event.data + "<br />";
        };
      }
    else
      {
      document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
      }
    </script>
    
    </body>
    </html>

    服务器sseServer.jsp代码:

    <%@ page language="java" contentType="text/event-stream; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ page import="java.util.Date"%>
    <%@ page import="java.io.*"%>
    <%
        Date date = new Date();
        System.out.println(date);
        response.setContentType("text/event-stream");      //设置contentType
        response.setHeader("Cache-Control", "no-cache");   //设置不缓存
        response.setHeader("Pragma","no-cache"); 
        response.setDateHeader("Expires",0);
        PrintWriter pw = response.getWriter();    
        pw.print("data: today is "+date.toString()+" wish you happy~~~");  //注意必须以data:开头
        pw.flush();
    %>

    结果:

     


    eg2:传送多行数据:

    if(typeof(EventSource)!=="undefined"){
      var source=new EventSource("multiLineServer.jsp");
      source.onmessage=function(event)
      {
            document.getElementById("result").innerHTML+=event.data.split('
    ').join('') + "<br />";
      };
     
     }else{
      document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
      }
        Date date = new Date();
        System.out.println(date);
        response.setContentType("text/event-stream");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma","no-cache");
        response.setDateHeader("Expires",0);
        PrintWriter pw = response.getWriter();    
        pw.println("data: today is "+date.toString()+" wish you happy~~~");
        pw.println("data: have a nice day");
        pw.flush();

    结果如下:


    eg3:以json格式封装数据:

    if(typeof(EventSource)!=="undefined"){
      var source=new EventSource("jsonServer.jsp");
      source.onmessage=function(event)
      {
          
          var data = JSON.parse(event.data);
          document.getElementById("result").innerHTML+="date:"+data.date + "<br />";
          document.getElementById("result").innerHTML+="name:"+data.name + "<br />";
      };
     
     }else{
      document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
      }

    server:

    Date date = new Date();
    System.out.println(date);
    response.setContentType("text/event-stream");
    response.setHeader("Cache-Control", "no-cache");
    response.setHeader("Pragma","no-cache");
    response.setDateHeader("Expires",0);
    PrintWriter pw = response.getWriter();    
    pw.println("data: {");
    pw.println("data: "date":""+date.toString()+"",");
    pw.println("data: "name":"wish"");
    pw.println("data:}");
        
    pw.flush();

    结果如下:

     添加监听事件:

    事件如下:

    message
    
    open
    
    error

    eg:

    if(typeof(EventSource)!=="undefined"){
      var source=new EventSource("sseServer.jsp");
      source.addEventListener('message',function(event){
          //Connection was opended
            document.getElementById("result").innerHTML+=event.data + "<br />";
    
      },false);
     }else{
      document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
      }

    服务器端代码相同,结果与上例相同:

    open和error事件如下:

    source.addEventListener('open', function(event) {
      // Connection was opened.
    }, false);
    
    source.addEventListener('error', function(event) {
      if (event.readyState == EventSource.CLOSED) {
        // Connection was closed.
      }
    }, false);

     注意:当连接关闭时,浏览器会自动在3秒后重新连接,可以在服务器端设置时间

     

     设置事件id和reconnect time


    设置id

    在stream前加上id:, 可以让浏览器跟踪最后一次触发的事件,如果服务器死掉时,可以在新的请求设置HTTP header,通过event.lastEventId可以获取该值

    eg:

    id: 1222
    
    data: ...
    

    设置reconnection time

    默认是在连接关闭3秒后reconnect,可以通过设置stream更改

    eg:设置5秒

    retry: 50000
    
    data: ......
    

    自定义事件名称

     eg:设置update事件

    stream:

    event: update
    
    data: {"username": "wish", "emotion": "happy"}
    

     js:

    source.addEventListener('update', function(event) {
      var data = JSON.parse(event.data);
      console.log(data.username + ' is now ' + data.emotion);
    }, false);

    Security

    在stream中增加origin

    source.addEventListener('message', function(event) {
      if (event.origin != 'http://cnblogs.com') {
        //................
        return;
      }
      ...
    }, false);

     其他请参考:Cross-document messaging security

     polling相关技术比较


    Regular http:

    1. client发送请求.
    2. server计算
    3. server sends the response to the client.

    HTTP


    AJAX Polling:

    1. client利用regular http请求webpage
    2. 请求的webpage 执行javascript脚本以一定间隔向服务器请求file
    3. server计算每个reqponse,发送给client

    AJAX Polling


    AJAX Long-Polling:

    1. client利用regular http请求webpage
    2. 请求的webpage 执行javascript脚本向服务器请求file
    3. 服务器并不立即响应,而是等到有新的信息时才响应
    4. client收到response后立即发送新的请求,重复上面过程

    AJAX Long-Polling


    HTML5 Websockets:

    1. client利用regular http请求webpage
    2. 请求的webpage 执行javascript脚本,open a connection to server.
    3. 有新的信息时服务器和客户端可以相互发送信息(Real-time traffic from the server to the client and from the client to the server)

    4. 使用请查看:https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_client_applications

    HTML5 WebSockets

     


    Comet:

    Comet 是HTML5技术之前使用streaming 和long-polling来实现实时应用程序的技术(Streaming and long polling for responsive communication between your server and client)更多了解 http://www.ibm.com/developerworks/web/library/wa-reverseajax1/index.html

    Comet is a web application model where a request is sent to the server and kept alive for a long time, until a time-out or a server event occurs. When the request is completed, another long-lived Ajax request is sent to wait for other server events. With Comet, web servers can send the data to the client without having to explicitly request it. 

    相关博文:HTML5 Web socket和socket.io

     参考:http://www.w3schools.com/html/html5_serversentevents.asp

        http://jaxenter.com/tutorial-jsf-2-and-html5-server-sent-events-42932.html

          http://www.html5rocks.com/en/tutorials/eventsource/basics/

          http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#authors

          http://stackoverflow.com/questions/11077857/what-are-long-polling-websockets-server-sent-events-sse-and-comet

        http://www.ibm.com/developerworks/web/library/wa-reverseajax1/index.html

  • 相关阅读:
    Kivy / Buildozer VM Ubuntu不能连接到网络的问题解决
    创建PHP组件(composer)
    uniapp基础
    标准js和浏览器js的区别(uniapp)
    swagger api工具 PHP组件 ---- 1
    阿里云视频点播--事件通知
    直接网页打印出现a标签的地址解决办法
    阿里云视频直播--直播转点播--实践2
    阿里云视频直播--直播转点播--实践1
    阿里云视频直播--直播转点播
  • 原文地址:https://www.cnblogs.com/wishyouhappy/p/3733570.html
Copyright © 2020-2023  润新知