zoukankan      html  css  js  c++  java
  • 跨域(二)

    Comet
    Ajax是一种从页面向服务器请求数据的技术,而Comet则是一种服务器向页面推送数据的技术。Comet能够让信息近乎实时地被推送到页面上
    有两种实现Comet的方式:长轮询和流

    1、轮询

    1)短轮询:浏览器定时向服务器发送请求,看有没有更新数据
    2)长轮询:页面发送一个到服务器的请求,然后服务器一直保持打开状态,直到有数据可发送。发送完数据之后,浏览器关闭连接,随即又发起一个到服务器的请求

    无论是短轮询还是长轮询,浏览器都要在接收数据之前,先发起浏览器向服务器的连接,轮询的优势是所有浏览器都支持,因为使用xhr对象和settimeout()就能实现。
    而你要做的是决定什么时候发送请求
    2、流
    流不同于上述两种轮询,因为它在页面的整个生命周期内只使用一个http连接。具体来说,就是浏览器向服务器发送一个请求,而服务器保持连接打开,
    然后周期性地向浏览器发送数据。
    通过侦听readystatechange事件及检测readyState的值是否为3,就可以利用xhr对象实现http流

    function createStreamingClient(url,progress,finished){
        var xhr = new XMLHttpRequest(),
        received = 0;
        xhr.open('get',url,true);
        xhr.onreadystatechange = function(){
            var result;
            if(xhr.readyState == 3){
                // 只取得最新数据并调整计数器
                result = xhr.responseText.substring(received);
                received +=result.length;
    
                //调用progress回调
                progress(result)
    
            }else if(xhr.readyState == 4){
                finished(xhr.responseText)
            }
        };
        xhr.send(null);
            return xhr
        }
        var client = createStreamingClient('localhost/index.php',
        function(data){
            console.log('Received' + data)
        },
        function(data){
            console.log('Done!');
        }
    )

    这个createStreamingClient()函数接收三个参数:要链接的url、在接收到数据时调用到函数以及关闭这个连接时调用的函数


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

    var source = new EventSource('myevets.php');

    *:传入的URL必须与创建对象的页面同源。EventSource实例有一个readyState属性,值为0表示正连接到服务器,值为1表示打开了连接,值为2表示关闭了连接。
    另外,还有以下三个事件

    open: 在建立连接时触发。
    message: 在从服务器接收到新事件时触发。
    error: 在无法建立连接时触发。
    source.onmessage = function(event){
    var data = event.data;
    //处理数据
    }

    服务器发回的数据以字符串形式保存在event.data中。
    默认情况下,EventSource对象会保持与服务器的活动连接。如果连接断开,还会重新连接。这意味着SSE适合长轮询和HTTP流。如果想强制立即断开连接并且不再
    重新连接,可以调用close()方法

    source.close();


    Web Sockets
    Web Sockets的目标是在一个单独的持久连接上提供全双工、双向通信。标准的http服务器无法实现web sockes。只有支持这种协议的专门服务器才能正常工作。
    由于Web Sockets使用了自定义的协议,所以url模式也略有不同。未加密的连接不再是http://,而是ws://;加密的连接也不是https://,而是wss://。SSE
    使用自定义协议的好处是,能够在客户端和服务器之间发送非常少量的数据,而不必担心http那样字节级的开销。
    1)Web Sockets API

    //创建一个Web Sockets实例
    var socket = new WebSocket('ws://www.example.com/server.php');

    *:必须给WebSocket构造函数传入绝对url。同源策略对Web Sockets不适用,因此可以通过它打开到人和站点到连接。

    与xhr类似,WebSocket也有一个表示当前状态到readyState属性。不过,与xhr并不相同。

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

    WebSocket没有readystatechange事件;不过,它有其他事件,对应不同到状态。readyState到值永远从0开始。

    要关闭Web Socket,可以在任何时候调用close()方法

    socket.close();

    调用colse()之后,readyState的值立即变为2(正在关闭),而在关闭连接后就会变成3.

    2)发送和接收数据

    var socket = new WebSocket('ws://www.example.com/server.php');
    socket.send('Hello world');

    因为Web Sockets只能通过连接发送纯文本数据,对于复杂的数据结构,在通过连接发送之前,必须进行序列化

    var message = {
        time: new Date(),
        text: 'Hello world!',
        clientId:'9527'
    };
    socket.send(JSON.stringify(message));

    当服务器向客户端发来消息时,WebSocket对象就会触发message事件。返回数据保存在event.data属性中

    socket.onmessage = function(event){
    var data = event.data;
        //处理数据
    }

    3)其他事件

    open:在成功建立连接时触发
    error:在发生错误时触发。连接不能持续。
    close:在连接关闭时触发
    var socket = new WebSocket('ws://www.example.com/server.php');
    socket.onopen = function(){
        alert('connection established.');
    }
    socket.onerror = function(){
        alert('connection error.');
    }
    socket.onclose = function(){
        alert('connection closed.');
    }

    在这三个事件中,只有close事件的event对象you额外的信息。这个事件的事件对象you是三个额外的属性:

    wasClean:是一个布尔值,表示连接是否已经明确地关闭;
    code:服务器返回的数值状态码;
    reason:一个字符串,包含服务器发回的消息
    socket.onclose = function(event){
        console.log('Was clean?' + event.wasClean + ' code=' + event.code + ' reason=' + event.reason);
    }

    使用sse还是web Sockets
    1、是否有自由度建立和维护web sockets服务器?
    WebSocket协议不同于http,所有现有浏览器不能用于web socket,sse倒是通过常规的http通信,因此现有浏览器都满足需求
    2、到底需不需要双向通信
    如果只需读取服务器数据,如比赛成绩,那么sse比较容易实现。如果必须双向通信,比如聊天室,那么web sockets显然更好
    在不能使用web sockets的情况下,组合xhr和sse也能实现双向通信的

  • 相关阅读:
    从屏幕刷新频率到Unity VSync
    TextMesh Pro不能显示中文的解决办法是创建字贴图,常用汉字3500+特殊字符
    50 个 Chrome Developer Tools 必备技巧
    Unity发布到Google Play应用上架流程
    Unity Shader入门
    Unity2019游戏框架搭建第一季C# 核心知识与简易框架搭建 + Unity2019 游戏框架搭建第二季:UI 模块与资源模块持续精进
    TextMesh Pro不能显示中文的解决办法是创建字贴图,常用汉字3500
    permanently
    UE4地编大型开放世界~制作烘焙全流程
    Unity高级游戏地编案例
  • 原文地址:https://www.cnblogs.com/wzndkj/p/8628233.html
Copyright © 2011-2022 走看看