精华内容
下载资源
问答
  • Web实时通信技术

    千次阅读 2016-08-19 21:11:41
    本周在应用宝前端分享会上分享了Web实时通信技术,分享内容整理如下。一、传统Web数据更新传统的Web数据更新,必须要刷新网页才能显示更新的内容。这是浏览器采用的是B/S架构,而B/S架构是基于HTTP协议的。HTTP协议...

    本周在应用宝前端分享会上分享了Web实时通信技术,分享内容整理如下。

    一、传统Web数据更新

    传统的Web数据更新,必须要刷新网页才能显示更新的内容。这是浏览器采用的是B/S架构,而B/S架构是基于HTTP协议的。HTTP协议的工作模式就是客户端向服务器发送一个请求,服务器收到请求后返回响应。所以这种工作模式是基于请求显示数据的。

    这样的工作方式有其自身的好处,但是也会导致很多问题。在Web应用越来越火的今天,经常会遇到需要服务器主动发送数据到客户端的需求,比如事件推送、Web聊天等。这些需求使用传统的Web数据更新工作模式是无法实现的,因此就需要一项新的技术:Web实时通信技术。

    二、短轮询

    第一种解决方法思路很简单,既然需要客户端发送请求服务器才能发送数据,那么就可以让客户端不断的向服务器发送数据,这样就能实时的获取服务器端的数据更新了。具体的实现方法很简单,客户端每隔一定时间就发送一个请求到服务器端。下面的图可以清晰的反映出短轮询过程中客户端和服务器的工作流程:

    下面看一下实现方法。

    在服务器端我们模拟数据的发送,生成1-1000的随机数,当数值小于800的时候模拟没有数据的情况,大于800的时候模拟有数据的情况,并返回数据:

    <?php
    $arr = array('title'=>'推送!','text'=>'推送消息内容');
    $rand = rand(1,999);
    if(rand < 800){
    echo “”
    }else{
      echo json_encode($arr);
    }
    ?>

    客户端部分,定义了一个函数用来发送ajax请求到客户端,然后每隔2s就发送以此请求:

    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>短轮询ajax实现</title>
    <script type="text/javascript" src="../jquery.min.js"></script>
    </head>
    <body>
    <form id="form1" runat="server">
         <div id="news"></div>
        </form>
    </body>
    <script type="text/javascript">
      function showUnreadNews()
        {
            $(document).ready(function() {
                $.ajax({
                    type: "GET",
                    url: "setInterval.php",
                    dataType: "json",
                    success: function(msg) {
                        $.each(msg, function(id, title) {
                            $("#news").append("<a>" + title + "</a><br>");
                        });
                    }
                });
            });
        }
        setInterval('showUnreadNews()',2000);
    </script>
    </html>

    运行程序我们可以在Chrome的network工具看到,每隔两秒都会有一个请求从客户端发往服务器,不管当时的服务器有没有数据,都会立即返回请求。、

    短轮询虽然简单,但是它的缺点也是显而易见的。首先短轮询建立了很多HTTP请求,而且其中绝大部分的请求是没有用处的。而HTTP连接数过多过多会严重影响Web性能。其次,客户端设置的请求发送时间间隔也不好掌控,时间间隔太短会造成大量HTTP的浪费,而时间间隔过长会使得客户端不能即时收到服务器端的数据更新,失去了即时通信的意义。

    三、长轮询

    针对上面短轮询的种种问题,我们自然而然想到要减少HTTP请求的数量,才能让实时通信性能更高。而长轮询就能有效的减少HTTP请求的数量。

    长轮询的逻辑是,首先客户端向服务器端发送一个请求,服务器端在收到请求后不马上返回该请求,而是将请求挂起。一段时间后服务器端有数据更新时,再将这个请求返回客户端,客户端收到服务器端的响应数据后渲染界面,同时马上再发送一个请求到服务器,如此循环,下面的图描述了这个过程:

    长轮询有效的减少了HTTP连接。服务器端在有数据更新时才返回数据,客户端收到数据再请求这一机制,较少了之间许多的无用HTTP请求。下面通过一个Demo来演示长轮询的工作模式。

    服务器端模拟数据更新,在客户端发来请求后先挂起6s,模拟6s后才有数据的情况:

    <?php
    $arr = array('title'=>'推送','text'=>'推送消息内容');
    $flag = 0;
    for($i=1;$i<=6;$i++){
      if($i>5){   //i = 6时表示有数据了
        echo json_encode($arr);
      }else{
        sleep(1);
      }
    }
    ?>

    这里为了演示的更清楚,添加了一个for循环,其实就是先将请求挂起6s。

    客户端发送一个ajax请求,并当收到服务器端数据后自动再发送一个请求到服务器:

    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>长轮询ajax实现</title>
    <script type="text/javascript" src="../jquery.min.js"></script>
    </head>
    <body>
    <input type="button" id="btn" value="click">
    <div id="msg"></div>
    </body>
    <script type="text/javascript">
    $(function(){
            $("#btn").bind('click',{btn:$('#btn')},function(e){
                $.ajax({
                    type: 'POST',
                    dataType: 'json',               
                    url: 'do.php',
                    timeout: '20000',
                    success: function(data,status){
                        $("#msg").append(data.title + ':' + data.text + "</br>");
                        e.data.btn.click(); 
                    }
                });
            });
        });
    </script>
    </html>

    长轮询虽然有效的减少了HTTP请求,但是HTTP请求相比之下还是很多的,因为每次数据的更新都需要建立一个HTTP请求。下面的技术就可以实现建立以此HTTP连接,服务器可以源源不断的向客户端发送数据。

    四、SSE

    MessageEvent是HTML5中新定义的一种事件基类,和原先的MouseEvent、UIEvent一样。MessageEvent是专门为数据传输定义的事件,HTML5中的SSE和WebSocket都利用了这个事件。MessageEvent在HTML5协议中的接口如下:

    除了继承了Event事件具有的属性外,MessageEvent还定义了其他属性。其中data属性所包含的内容就是传输的数据内容。而lastEventId可以存放一个事件标识符,当客户端和服务器传输数据过程中断开连接需要重连时,客户端会将上一次传输数据的lastEventId作为请求头中的一个特殊字段发送到服务器,从而让服务器可以继续上次断开连接的部分发送消息。

    SSE是HTML5规范中定义的,它可以实现维持一个HTTP连接,服务器端单向向客户端不断发送数据。这个技术真正意义上实现了服务器主动推送数据到客户端。除此之外,SSE的客户端和服务器端代码都特别简洁,使用起来十分方便。

    SSE的逻辑就是首先客户端发送请求,建立一个HTTP连接,之后服务器端和客户端一直保持这个连接,服务器端可以单向向客户端发送数据,见下图:

    SSE的实现方法很简单,SSE是以事件流的形式发送数据的。在服务器端要先进行如下配置:

    Content-Type:text/event-stream
    Cache-Control:no-cache
    Connections:keep-alive

    如果还需要进行跨域,配置里再添加:

    Access-Control-Allow-Origin: *

    其中text/event-stream是HTML5规范中为SSE的事件流传输定义的一种流格式。

    做好配置后,服务器第二个要做的事就是维护一个清单,清单内容就是要向客户端发送的数据,下面是一段例子:

    data: first event  
     
    event: push
    data: second event

    每一组事件流传输对应的数据,每个事件流之间使用换行符进行分割。这种格式发送过去之后会被进行解析,最后将各个部分进行组装,客户端按需进行读取。每一个事件流可以为其指定四个字段。

    (1)retry字段

      SSE有一个自动重连机制,即客户端和服务器之间的连接断开后,隔一段时间客户端就会自动重连。retry指定的就是这个重连时间,单位为ms。

    (2)event字段

    SSE中有三个默认的事件,它们都继承自MessageEvent事件类。其中open事件在连接建立时触发,message事件在从客户端接收到数据时触发,close事件在连接关闭时触发。如果传输事件时一个事件流没有设定event字段的值,那么客户端就会监听message默认事件;如果指定了event事件,那么就会生成自定义的event事件,客户端可以监听自定义的event进行数据读取。

    (3)data字段

    data字段包含的内容就是服务器要传送给客户端的数据,SSE只能传送文本数据,且必须是UTF-8编码的。由于这些事件都继承自MessageEvent基类,因此可以通过event.data获取服务器传输的数据。

    (4)id字段

    id字段是事件的唯一标识符,解析后会被传入MessageEvent对应的lastEventId属性字段中,从而记录上次数据传输的位置。如果不指定id字段lastEventId字段就是一个空字符串。

    至此服务器端任务完成,下面介绍客户端的实现方法。

    客户端首先需要实例化一个EventSource对象。EventSource对象在HTML5中的接口定义如下:

    首先需要为EventSource对象传入一个url,表明要请求的服务器地址。该对象有三个readyState状态值,其中CONNECTING表示正在建立连接,OPEN表示连接处于打开状态可以传输数据,CLOSED状态表示连接中断,并且客户端并没有尝试重连。EventSource定义的默认事件句柄为onopen、onmessage、onerror。其中的方法只有close(),用来关闭连接。

    实例化好EventSource对象后,我们需要对事件进行监听,从而获取数据,最后可以通过close()方法关闭连接,整体逻辑的代码如下:

    var es = new EventSource(url);  
    es.addEventListener("message", function(e){
        console.log(e.data);
    })
    es.close();

    下面是一个实现SSE的例子。

    服务器使用node,代码及注释如下:

    var http = require("http");
    var fs = require("fs");
    //创建服务器
    http.createServer(function (req, res) {
      var index = "./index.html";
      var fileName;
      var interval;
      var i = 1;
      //设置路由
      if (req.url === "/"){
        fileName = index;
      }else{
        fileName = "." + req.url;
      }
      if (fileName === "./stream") {
        //配置头部信息:注意类型为专门为sse定义的event-stream,并且不使用缓存
        res.writeHead(200, {"Content-Type":"text/event-stream", "Cache-Control":"no-cache", "Connection":"keep-alive"});
        /*
          下面的代码的输出结果等价于:
          retry: 10000
          event: title
          data: News Begin
     
          data: ...
     
          ...
        */
        //上面可以看出,只有第一段是触发事件connecttime,其他都是触发默认事件message
        res.write("retry: 10000\n");    //定义连接断开后客户端重新发起连接的时间,ms制
        res.write("event: title\n");   //自定义的事件title
        res.write("data: News Begin! \n\n");
        //每隔1s就在协议中新写入一段数据来模拟服务器向客户端发送数据
        interval = setInterval(function() {
          res.write("data: News" + i +"\n\n");
          i++;
        }, 1000);
        //监听close事件,当服务器关闭时停止向客户端传送数据
        req.connection.addListener("close", function () {
          clearInterval(interval);
        }, false);
      } else if (fileName === index) {
        fs.exists(fileName, function(exists) {
          if (exists) {
            fs.readFile(fileName, function(error, content) {
              if (error) {
                res.writeHead(500);
                res.end();
              } else {
                res.writeHead(200, {"Content-Type":"text/html"});
                res.end(content, "utf-8");
              }
            });
          } else {
            res.writeHead(404);
            res.end();
          }
        });
      } else {
        res.writeHead(404);
        res.end();
      }
    }).listen(8888);
    console.log("Server running at http://127.0.0.1:8888/");

    服务器端自定义了title事件,用来发送标题数据,其他的数据使用默认事件发送。

    客户端部分代码及注释如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>Server-Sent Events Demo</title>
      <meta charset="UTF-8" />
      <script>
        window.onload = function() {
          var button = document.getElementById("connect");
          var status = document.getElementById("status");
          var output = document.getElementById("output");
          var connectTime = document.getElementById("connecttime");
          var source;
          function connect() {
            source = new EventSource("stream");
            //messsage事件:当收到服务器传来的数据时触发
            source.addEventListener("message", function(event) {
              output.textContent = event.data;  //每次收到数据后都更新时间
            }, false);
            //自定义的事件title
            source.addEventListener("title", function(event) {
              connectTime.textContent = event.data;
            }, false);
            //open事件:当客户端和服务器完成连接时触发
            source.addEventListener("open", function(event) {
              //每次连接成功后更新按钮功能和文本提示,再次点击按钮应为关闭连接
              button.value = "Disconnect";
              button.onclick = function(event) {
                //调用eventsource对象的close()方法关闭连接,并且为其绑定新的事件connect建立连接
                source.close();
                button.value = "Connect";
                button.onclick = connect;
              };
            }, false);
            //异常处理
          }
          //调用,如果支持EVentSource则执行connect()方法仅从sse连接
          connect();
        }
      </script>
    </head>
    <body>
      <input type="button" id="connect" value="Connect" /><br />
      <span id="status"></span><br />
      <span id="connecttime"></span><br />
      <span id="output"></span>
    </body>
    </html>

    客户端监听事件,不同的事件收到的数据进行不同的渲染。同时,都过为按钮绑定事件,调用close()等方法,实现SSE连接的打开与断开。

    SSE技术简单方便,且是HTML5中定义内容,实现了服务器推送数据的技术,下图是SSE的浏览器兼容性列表:

    但是SSE只能实现服务器到客户端单向的数据传输。有时我们的需求需要使用双向数据传输,这时就需要使用WebSocket。

    五、WebSocket

    WebSocket也是HTML5中定义的。它是一个新的协议,实现了全双工的通信模式,即客户端和服务器端可以互相发送消息。WebSocket的实现首先需要客户端和服务器端进行一次握手,此后就会建立起一个数据传输通道,通道存在期间客户端和服务器端可以平等的互相发送数据。具体的逻辑图如下:

    WebSocket的服务器端实现比较复杂,但是各个后台语言都已经有实现好的WebSocket库。比如Node.js中的nodejs-websocket模块和socket.io模块。使用WebSocket技术可以实现很多功能,附件中就是借助nodejs-websocket模块编写的弹幕效果。

    WebSocket的客户端实现比较便捷,首先需要实例化一个WebSocket对象,传入要请求的服务器的url。这里需要注意,协议名要指定为ws或wss,如:

    ws = new WebSocket("ws://localhost:8080");

    客户端可以通过调用send()方法进行数据的发送,通过调用close()方法关闭WebSocket连接。WebSocket也使用了MessageEvent接口,因此可以对消息事件进行监听,默认的可以通过监听message事件获取数据。下面是WebSocket在HTML5规范中定义的接口:

    WebSocket的服务器端实现可以分为两个部分,第一个部分是握手部分,主要负责HTTP协议的升级,第二个部分是数据传输部分。

    WebSocket协议可以说是一个HTTP协议的升级版,这个升级过程需要通过客户端和服务器的一次握手来实现。下面是建立握手时客户端向服务器发送的请求报文头实例:

    字段Upgrade:websocket和Connection:Upgrade部分完成了协议的升级,服务器可以触发响应事件,获取这两个字段的内容,匹配符合要求后服务器端进行握手处理。客户端需要向服务器端发送一个Sec-WebSocket-Key字段,这个字段的内容是客户端产生的,相当于一个私钥。服务器端收到客户端的请求头后,如果确定是要使用WebSocket协议,就开始进行握手。服务器端使用客户端传来的Sec-WebSocket-Key的值,与服务器端存储的一个全局唯一标识符进行拼接,之后做SHA1处理和BASE64加密,并作为响应头返回给客户端。服务器端的GUID相当于公钥。

    下面是服务器端返回的响应报文头,处理后的字符串在Sec-WebSocket-Accept字段中给出。客户端必须受到101状态码,这个状态码表示切换协议,从而完成对协议的升级。

    总的来看,WebSocket只有在建立握手连接的时候借用了HTTP协议的头,连接成功后的通信部分都是基于TCP的连接,可以说WebSocket协议是HTTP协议的升级版。

    WebSocket的数据帧格式如下:

    opcode存储的是传输数据的类型,诸如文本、二进制数据等。数据传输时首先会对该部分的值进行判断,然后进行对应的数据操作。数据存储在Payload Data字段中。最后将帧结构解析为一个键值对的对象。

    下面是浏览器对WebSocket的支持情况:

    展开全文
  • Web实时通信技术的几个发展阶段

    千次阅读 2015-03-20 18:16:11
    随着web技术的发展和硬件的革新,web应用已逐渐在侵占着C/S软件的领域。不得不说,B/S模式的应用将是未来的主流,当然这只是本人的一家之言.当用户在浏览器中能做的事情越来越多的时候,当用户慢慢习惯只用浏览器来...

    随着web技术的发展和硬件的革新,web应用已逐渐在侵占着C/S软件的领域。不得不说,B/S模式的应用将是未来的主流,当然这只是本人的一家之言.当用户在浏览器中能做的事情越来越多的时候,当用户慢慢习惯只用浏览器来获得一切需求的时候,到那时他们会发现原来他们的电脑只需要一个浏览器,仅此而已。这就是ChromeBook的发展理念吧。当然这个时候什么时候能到来却是个未知数,扯远了。

    今天要说说的是关于在浏览器中即时通讯的问题.到现在你会发现web即时通讯应用到处都能见到。很多网站都有即时通讯的应用。首先介绍几个比较知名的web IM应用:webqq,网页fetion,开心网,白社会等等。

    一个web即时通讯应用主要要克服两个问题:

    • 信息的持久化
    • 信息的传递。

    第一个问题很简单,选择也挺多,比如你可以选择数据库,文件,临时的缓存等来保持聊天信息。具体依据你的项目需求来做决定。本文主要是要说说这第二个问题——信息的传递。

    web通信方式对服务器来说也主要有两种方式:推和拉。

    所谓“推”即服务器收到了数据传递请求时主动向对方客户端推送的方式。这也是一种理想的方式,但却是一直很难实现的技术难题。

    “拉”即是客户端采用轮询的方式来不断对服务器进行http请求,这是现在广泛使用的方式。

    web即时通讯的信息传递一直以来有个问题那就是:如何保证当有信息需要传递的时候即时的传递给对方?也许你会觉得这不是个问题,当时当你知道了http是个无状态无连接的协议时,你会发现这是个很大的问题。让我们先看看针对这个问题才采用的解决方案的发展历程。

    阶段一:指定页面全部或局部的刷新时间间隔

    最初为了更新客户端的数据信息采用的方式是通过<meta>内指定自动刷新的时间间隔,这样浏览器会在该时间到时自动刷新该页面。这是最初的解决更新客户端信息的方式,也是最原始也是最蹩脚的方式。现在一些手机网页上还有采用这种方式,我记得以前用手机看nba文字直播的时候就是这种方式。这种用户体验让人发指,缺点显而易见。当然还有一种实现原理一样的局部刷新方式,就是内嵌隐藏的iframe来不断刷新。早期很多就是采用的这种方式。

    阶段二:Ajax的轮询

    Ajax技术的诞生,给我们带来了很大的惊喜。就是由于ajax技术使得我们可以采用异步的方式对服务器发起请求,这对用户体验绝对是一个相当大的改善。ajax轮询就是结合js的setInterval函数指定时间间隔发起http请求。但是这种方式的缺点也是很明显的,这个时间间隔你觉得取多少合适呢?

    阶段三:Ajax长轮询 —— Comet

    Comet技术的出现还是受到了很大的关注。比较这一问题至始至终都没有得到一个好的解决方案。首先先介绍介绍这个Comet。Comet 是一种新的 Web 应用架构。基于这种架构开发的应用中,服务器端会主动以异步的方式向客户端程序推送数据,而不需要客户端显式的发出请求。Comet 架构非常适合事件驱动的 Web 应用,以及对交互性和实时性要求很强的应用,如股票交易行情分析、聊天室和 Web 版在线游戏等。它的主要不同之处就在于它会客户端保持一种长连接状态,直到消息被传递后才释放。其实到这里这才是真正的算得上实时通讯了。我去网上查了下这个技术一般都是和Java使用。Tomcat6已支持了Comet技术。然后我本想找找PHP和Comet结合的例子,得到的尽是无情的鄙视。Comet实现长连接有两种方式:

    • HTTP 流(HTTP Streaming)这种情况下,客户端打开一个单一的与服务器端的 HTTP 持久连接。服务器通过此连接把数据发送过来,客户端增量的处理它们。
    • HTTP 长轮询(HTTP Long Polling这种情况下,由客户端向服务器端发出请求并打开一个连接。这个连接只有在收到服务器端的数据之后才会关闭。服务器端发送完数据之后,就立即关闭连接。客户端则马上再打开一个新的连接,等待下一次的据。

    这种方式实现通讯方式相比已经有很大提高,至少能对得起实时通信这个称号。现在很多实时通讯应用就是基于此技术。如webqq。当然它的缺点就是要维持这个长连接明显加大了服务器的负担。

    接下来或许是HTML5 WebSocket…

    WebSocket 是HTML5一种新的协议。它是实现了浏览器与服务器的双向通讯。在 WebSocket API 中,浏览器和服务器只需要要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。这种方式不仅简单,而且降低了服务器的要求。只是至少要等到你的用户使用的浏览器支持它了再说。

    其他插件式的通信方式

    其实在上述发展的过程中,还有一种通讯方式存在,那就是使用activeX控件或者JAVA Applet等实现Socket通信。还有使用的较为广泛的flash。其实这种通信方式是最划算的。但是不足的是原生浏览器并不支持,需要用户安装相关的浏览器插件才行。于是我便可以不多说了。谁爱装插件谁装去(flash除外,没办法)。

    好了,这里只是简单的说下web通讯方面的一些技术,如果你要想研究透其中的某一项都得花些时间专研才行。

    展开全文
  • sockjs-web实时通信协议

    万次阅读 2015-06-22 15:12:12
    sockjs-web实时通讯应用解决方案 socksjs目标 客户端和服务器端api尽可能简洁,尽量靠近websocket api 支持服务端扩展和负载均衡技术 传输层应该全面支持跨域通信 如果收到代理服务器的限制,传输层能优雅地从...

    sockjs-web实时通信应用解决方案

    socksjs

    • 客户端和服务器端api尽可能简洁,尽量靠近websocket api
    • 支持服务端扩展和负载均衡技术
    • 传输层应该全面支持跨域通信
    • 如果受到代理服务器的限制,传输层能优雅地从一种方式回退到另一种方式
    • 尽可能快地建立连接
    • 客户端只是纯粹的JavaScript,不需要flash
    • 客户端JavaScript必须经过严格的测试
    • 服务器端代码尽可能简单,降低用另一种语言重写server的代价

    实际上sockjs的目标也就是sockjs具有的特点。

    SockJS: WebSocket emulation done right一文中对sockjs的特点进行了具体阐述。

    sockjs几个特点,非常值得一提

    跨域通信

    sockjs服务器端支持跨域通信,意味着我们可以将sockjs server独立出来,把它放在与web主站点不同的域名之上,实际上这是比较合理的部署策略。关于跨域,也是一个比较大的话题,其中有一个机制叫cors(跨域资源共享)主要解决JavaScript不能跨域请求的问题。sockjs服务器应该支持这种机制。

    负载均衡

    无论server端优化得再好,一个sockjs server的处理能力都是有限的,我们更需要的是一种可扩展的解决方案。一种非常简单的方法是把每一个sockjs server放到一个不同的域名之下,如sockjs1.example.com和sockjs2.example.com,允许客户端随机选择一个server。

    Prefix-based sticky sessions

    在sockjs中,一个典型的url如下:

    http://localhost:8000/chat/<serverid>/<sessionid>/

    url中的第二个参数sessionid,必须是一个随机字符串,唯一标识一个session。第一个参数serverid,主要应用于负载均衡目的。负载均衡器可以利用这个serverid参数作为一个线索,进行负载均衡分流。具体使用方面,参考HAProxy的一个配置参考文件,其中关键的配置在于

    balance uri depth 2

    另外一种负载均衡配置方案,主要利用含有jsessionid的cookie。这个cookie由socketjs server进行设置,当response到达负载均衡器的时候,jessionid会被加上一个额外的前缀或者后缀,具体原理方面可以参考阅读
    LOAD BALANCING, AFFINITY, PERSISTENCE, STICKY SESSIONS: WHAT YOU NEED TO KNOW一文。

    健壮的传输协议

    我们知道html5 的websocket协议定义了websocket api使得网页可以利用websocket协议和远端主机进行全双工通信。websocket协议应该是最快,最好的web通信协议,已被大多数的浏览器所支持。那么为什么还需要sockjs进行封装?

    在真实的网络世界中,实际上有着非常复杂的网络拓扑结构,在浏览器和server之间,含有很多的中间节点,包括路由器,代理服务器,反向代理服务器,负载均衡器等等。即使html5 websocket协议已经成为了标准,但是这些中间节点并不一定会遵守这些标准,还有很大可能会阻止websocket handshake的过程,结果无法建立websocket连接。

    How HTML5 Web Sockets Interact With Proxy Servers一文中提到了websocket协议和代理服务器的“不友善关系”,源于代理服务器对websocket handshake的阻挠和对长连接,空闲连接的关闭处理,让我们看到了如果只是直接利用websocket协议,实在是困难重重。

    sockjs的出现,实际是为了解决这个问题,使得人们可以建立健壮的web实时通信程序。

    sockjs服务器传输协议不仅提供了websocket协议的支持,还提供了流传输Streaming和轮询Polling ,其中又包括多种底层传输方案,如:
    xhrxhr_streamingjsonpeventsourcehtmlfile。每一种传输方案,其实都值得开辟一个章节来大写特写。

    如果浏览器客户端js,采用websocket连接不上服务器,它可以回退选择其他传输方案,那么确保总可以利用一种传输协议,连接到服务器。那么开发者就不需要理睬那些可恶的中间节点了。

    推荐阅读

    展开全文
  • web实时通信讲H5 WebSocket

    千次阅读 2017-04-25 13:03:03
    传统的B/S通信通常我们打开一个浏览器访问网页时,都会向页面所在的服务器发送一个HTTP请求,然后web服务器确认请求并向浏览器做出响应。简单的说,就是一个请求对应的一个响应。然而这种方法对许多的应用场景都会使...

    传统的B/S通信

    通常我们打开一个浏览器访问网页时,都会向页面所在的服务器发送一个HTTP请求,然后web服务器确认请求并向浏览器做出响应。简单的说,就是一个请求对应的一个响应。然而这种方法对许多的应用场景都会使服务器的HTTP请求变得臃肿,甚至崩溃。比如:对于股价、新闻每日推送、好友聊天信息收发等情况,如果每次都是客户端发送HTTP请求给服务器来获取相应数据,那么用户就需要每次都对页面进行刷新从而来获取最新的消息。相信这样的网页用户也不会喜欢

    前期实时通信解决方式

    1>

    HTTP轮询

       1.定义:轮询是一种定时性的同步调用,客户端想服务器发送请求查看是否有可用的新数据。请求以固定的时间间隔发出,不管是否有信息,客户端都会得到响应数据:如果有可用信息,服务器就会将它们返回给客户端;如果没有可用信息,服务器就会返回一个拒绝响应,客户端接受到这种响应时就可以关闭连接。轮询的本质上就是推迟完成HTTP响应,向客户端提交信息
       2.适用场景:在知道信息交互的时间间隔的情况下,使用它是一个好的办法,然而大多数的情况下,我们都不知道信息交付的时间间隔,我们不知道用户什么时候发数据,新闻什么时候更新等等..
       3.缺陷:使用HTTP轮询方式需要服务器有很快处理速度和资源,而且发送的http请求也很多

    2>

    长轮询

       1.定义:客户端向服务器端请求信息,并在设定的时间内打开一个连接。服务器如果没有信息推送,那么请求就会一直打开,知道服务器响应数据或者设定的时间用完为止。当请求关闭时,客户端又可以重新向服务器发送请求信息。长轮询是一种阻塞模型,类似于打电话,没有人接就不挂电话,知道拨打电话时长超过限制或者对方接了。长轮询也称为Comet或者反向AJAX,长轮询延长HTTP响应的完成时间,直到服务器响应数据或者设定时间用完,这种技术通常称为挂起GET或者搁置POST
       2.缺陷:当信息量很大时,长轮询的性能相较于传统的通信而言并没有明显的优势,因为客户端必须繁重得重连服务器来获取新信息。并且长轮询缺乏标准实现。而且长轮询需要有很高的并发能力即同时接待多个客户的能力

    3>

    流化技术

       1.定义:在流化技术中,客户端发送一个请求,服务器发送并维护一个持续更新和保持打开(可以指定时间段,也可以设置为无限)的开放响应,每当服务器有需要交付给客户端的信息时,它就更新响应
       2.缺陷:流化技术中的服务器从不发出完成HTTP响应的请求,从而使连接一直保持打开状态。这种情况下,代理和防火墙可能会缓存HTTP响应,导致信息交付的延迟时间增加,因此,大多数的流化测试对于存在防火墙和代理的网络都是不友好的

    WebSocket

       1.定义:WebSocket是一种自然的全双工、双向、单套接字连接。通过使用WebSocket,客户端发送的即时HTTP请求变成了打开WebSocket的单一请求,并且这一请求式连接会一直重用,知道用户关闭。
       2.优势:WebSocket明显减少了延迟时间,因为只要建立起WebSocket连接,服务器就可以在消息可用时发送他们,客户端和服务器连接全过程都只发出一个请求,建立一个连接,服务器不需要等待来自客户端的HTTP请求,同时,客户端也可以在任何时候向服务器发送消息

    WebSocket与轮询方式发送请求的方式

    WebSocket测试小实例

    // 新建js文件 hellows.js
    <html>
        <head>
            <title>hello websocket</title>
            <meta charset='UTF-8' />
        </head>
        <body>
            <input type="button" id='test' value='点我测试' />
            <!--引入JQuery文件简化DOM操作(其实就是懒~)-->
            <script src="JS/jquery.min.js"></script>
            <script>
                $(function(){
                    //websocket测试服务器
                    var url = "ws://echo.websocket.org/echo";
                    var ws = null;
                    function createws(){
                        if('WebSocket' in window)
                            ws = new WebSocket(url);
                        else if('MOzWebSocket' in window)
                            ws = new MozWebSocket(url);
                        else
                            console.log("浏览器太旧,不支持");
                    }
                    function btnfun(){
                        createws();
                        //成功建立WebSocket连接时触发onopen事件,通常客户端发送数据都是放在open事件里面
                        ws.onopen = function(){
                            console.log("connected");
                            ws.send("hello world");
                        };
                        //接受服务器响应数据时触发onmessage事件
                        ws.onmessage = function(event){
                            console.log("receive message:"+event.data);
                            //关闭websocket连接
                            ws.close(999,"close normal");
                        };
                        //服务器处理异常,通常在服务器里try-catch发生异常时或者连接异常时触发onerror事件
                        ws.onerror = function(err){
                            console.log("error: "+err);
                            ws.close(1000,"close after error");
                        };
                        //websocket连接关闭时触发onclose事件
                        ws.onclose = function(event){
                            console.log("close reason: "+event.reason);
                        };
                    };
                    //为button绑定事件
                    $("#test").click($.fn.btnfun);
                });
            </script>
        </body>
    </html>

    浏览器打开该页面,打开浏览器的控制台,然后点击里面的按钮将会出现一系列我们在里面设置的测试输出数据则代表websocket测试成功了。如果console控制台输出的是“浏览器太旧,不支持”,就表示当前所使用的浏览器版本太旧,虽然目前所有的主流浏览器的最新版本都包含了对WebSocket API以及其协议的支持,但是还是有一些在用的旧版本的浏览器没有这方面的支持,因此想要获得WebSocket的支持可以去下载新版本或者主流的浏览器,也可以研究变通或者模拟策略来自己模拟实现WebSocket~~

    展开全文
  • 随着互联网技术的高速发展,人们对Web应用的实时性要求越来越高,传统的Web实时通信方案已经无法满足一些现实应用的需求。在长期的Web应用过程中该传统方案逐渐露出资源浪费、实时性不高等问题,这些问题的出现对...
  • 实时通信技术的架构设计

    千次阅读 2015-03-20 13:55:15
    一、WEB实时通信技术对比 在WEB端的实时通信技术中,主要有以下几种方式:   1)轮询技术 轮询是最简单的一种实时通信技术,易于实现,非常适用于一些小型的应用。其基本原理是这样的,先在客户端设定...
  • Web实时通讯技术简介

    千次阅读 2016-08-08 09:54:04
    一、概述 1.Web端即时通讯技术 即时通讯技术简单的说...这种限制出现的主要原因是,一般的Web通信都是浏览器先发送请求到服务器,服务器再进行响应完成数据的现实更新。 2.实现Web端即时通讯的方法 实现即时通讯
  • [转]web实时通信方式

    千次阅读 2010-01-19 00:28:00
    (4) Flash XMLSocket:在页面中内嵌入一个使用了XMLSocket类的 Flash 程序JavaScript通过调用此Flash程序提供的Socket接口与服务器端的Socket接口进行通信,JavaScript在收到服务器端以XML格式传送的信息后控制页面...
  • 基于WEB实时通信方案

    千次阅读 2015-03-20 18:20:30
    本文所讲述的『实时通信』主要围绕浏览器端和服务器端之间的实时通信实时通信主要分3大类: 1. Pull技术,轮询(Polling) 客户端定时轮询请求,服务器端立刻返回。 优点:短链接,服务器处理方便,...
  • Web端即时通信技术

    千次阅读 2018-06-15 10:48:24
    以前限制web开发接近原生应用的一大障碍就是web开发很难实现即时通信。因为在web应用中,由于其使用的http协议的特殊性,只有用户在界面中进行操作后,服务器的到客户端的信息,才能进行响应。也就是说,使用web开发...
  • SignalR 实现 Web 客户端与服务器实时通信简介ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信。什么是实时通信Web呢?就是让客户端(Web页面)和服务器端可以互相实时通知...
  • 基于 HTTP 的实时 Web 通信

    千次阅读 2018-03-27 15:27:24
    基于 HTTP 的实时 Web 通信 Web 应用的信息交互过程通常是客户端通过浏览器发出一个请求,服务器端接收和审核完请求后进行处理并返回结果给客户端,然后客户端浏览器将信息呈现出来,这种机制对于信息变化不是特别...
  • Web 实时推送技术的总结

    千次阅读 2019-04-24 15:56:31
    前言 随着 Web 的发展,用户对于 Web实时推送要求也越来越高 ,...本文对过去和现在流行的 Web 实时推送技术进行了比较与总结。 本文完整的源代码请猛戳Github博客(https://github.com/ljianshu/Blog),纸上得...
  • 在介绍web实时交互方式前,先了解一下HTTP的通信机制,共分为以下四步: 第一步: HTTP是基于传输层的TCP协议,在HTTP开始工作之前,web浏览器首先通过网络与尾部服务器在TCP层建立连接。在TCP层进行“三次握手”之后...
  • Web页面实时刷新技术探讨

    万次阅读 2017-09-05 11:01:49
    随着网络技术的飞速发展,使用B/S结构来实现项目应用已经越来越多,而实时监控一直都是多数行业软件所必备的功能,由此使用Web页面来实现实时监控成了一种必然的需求。   二、实时刷新技术 1、传统的页面...
  • 原文地址: Comet 也称反向 Ajax 或服务器端...本人做了简单的web实时聊天系统:服务器推送(聊天).zip 系统简单说明如下: { 系统所用数据库:sqlite数据库  UserInfo:用户信息表  UserRelation:用户关系表
  • Web世界通信协议 - 学习/实践

    千次阅读 2019-12-18 11:04:23
    了解web世界中, 各种网络通信协议, 实现的手段, 区别和原理. 另外发现, 网上很多博客, 问答等都没有回答清楚web中的一些协议, 通信的准确定义以及原理和实质. 这里希望自己能逐步准确整理出来网络相关的...
  • 网络通信技术基础

    千次阅读 2018-07-21 12:39:38
    在我们日常使用的各种各样的软件,都涉及到一项很关键的技术——网络通信技术。今天我们就从软件开发者的角度来探究一下J网络通信技术。 一、网络通信技术 当我们用在点击下QQ对话框的“发送”按键时,相应的好友...
  • FLEX实现Web实时监控

    千次阅读 2010-08-25 22:14:00
    监控系统逐步向B/S框架结构[1]转变,但由于HTTP协议固有的缺陷,使WEB模式在工业监控实时领域应用一直不尽人意,AJAX... 技术的出现,结合消息服务技术实现的推技术(Push),解决了实时难题,彻底实现了Web实时监控工作模式.
  • web实时推送技术--websocket

    千次阅读 2018-01-16 15:55:32
    Python的tornado框架中,websocket允许浏览器和服务器之间进行双向,实时,持久的,全双工通信。协议本身使用 ws://URL 的格式,如果是加密的websocket则使用的是 wss://URL websocket的起源 websocket和其他...
  • 用COMET技术实现WEB实时推送应用(转)

    千次阅读 2011-10-30 21:13:36
     demo:http://www.blogjava.net/Files/JAVA-HE/TestComet.rar  查阅词典Comet中文是“彗星”的意思,起初我见到这个单词的时候,我就猜想优美名字背后到底是什么呢?他是一种WEB服务器推的应用技术(Server Pu
  • 详解Zoosk千万用户实时通信背后的开源技术 发表于22小时前| 174次阅读| 来源High Scalability| 0 条评论| 作者Peter Offringa RTCTigase实时通讯ZooskPeterOffringa 摘要:Zoosk是一个具有5000...
  • 最近关于HTML 5 Web Socket的流言已经满天飞,它通过Web上的一个单一Socket定义了一个全双工通信信道,HTML 5 Web Socket并不是普通HTTP通信的增强版,它代表着一个巨大的进步,特别是针对实时的、事件驱动的Web应用...
  • 讲解如何搭建Janus,并运行Janus WebDemo。... 实现iOS端使用Janus流媒体服务器与Web端进行多人的实时音视频互动 课程升级支持janus0.9.2,配置文档已经上传在  《janus-demo演示》附件中
  • 最近应项目组要求研究了下WebRTC(目前支持Firefox和Chrome),WebRTC,名称源自网页实时通信Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的技术,WebRTC使得开发者在...
  • Google开源实时通信项目WebRTC

    千次阅读 2012-08-21 18:46:21
    最近,Google正式开源了WebRTC实时通信项目,希望浏览器厂商能够将该技术内建在浏览器中,从而使Web应用开发人员能够通过HTML标签和JavaScript API就实现Web音频、视频通信功能。 WebRTC(Web Real Time ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 253,555
精华内容 101,422
关键字:

web实时通信技术