JSON

前端通信进阶(2)

字号+ 作者:H5之家 来源:H5之家 2016-03-25 17:01 我要评论( )

他的技术并不是很难,和websocket不同,他依赖原生的HTTP,所以对于开发者来说更好理解。 比如,在nodeJS, 只要我不执行res.end(),并且一定时间持续发送信息的话,那么该连接就会持续打开(keep-alive). 其实通俗来说

他的技术并不是很难,和websocket不同,他依赖原生的HTTP,所以对于开发者来说更好理解。 比如,在nodeJS, 只要我不执行res.end(),并且一定时间持续发送信息的话,那么该连接就会持续打开(keep-alive). 其实通俗来说,就是一个长连接. 所以,以前我们通常使用ajax,iframe长轮询来代替他.但是这样有个缺点就是, 可操控性弱, 错误率高。 所以,正对于这点W3C, 觉得需要在客户端另外指定一个机制--能够保证服务器推送, 实现连接的keep-alive,操作简单... 在这样背景下SSE诞生了.

但SSE和AJAX具体的区别在什么地方呢?

  • 数据类型不同: SSE 只能接受 type/event-stream 类型. AJAX 可以接受任意类型

  • 结束机制不同: 虽然使用AJAX长轮询也可以实现这样的效果, 但是, 服务器端(nodeJS)必须在一定时间内执行res.end()才行. 而SSE, 只需要执行res.write() 即可.

  • 简单demo

    先看一个client端, 一个比较简单的demo

    var source = new EventSource('/dates'); //指定路由发送 source.onmessage = function(e) { //监听信息的传输 var data = JSON.parse(e.data), origin = e.origin; }; source.onerror = function(e) { //当连接发生error时触发 console.log(e); }; source.onopen = function(e) { //当连接正式建立时触发 console.log(e); };

    SSE主要就是创建一个EventSource对象. 里面的参数就是发送的路由, 不过目前还不支持CORS,所以也被限制在同源策略下.在返回的source里面包含了,需要处理的一切信息.SSE也是通过事件驱动的,如上面demo所述. 这里,SSE通常有一下几类重要的事件.

    eventName effect

    open 当连接打开时触发

    message 当有数据发送时触发, 在event对象内包含了相关数据

    error 当发生错误时触发

    上面几个方法比较重要的还是message方法. message主要用来进行信息的接受, 回调中的event 包含了返回的相关数据.event包含的内容

    property effect

    data 服务器端传回的数据

    origin 服务器端URL的域名部分,有protocol,hostname,port

    lastEventId 用来指定当前数据的序号.主要用来断线重连时数据的有效性

    服务器返回数据格式

    上文说过,SSE 是以event-stream格式进行传输的. 但具体内容是怎样的呢?

    data: hi data: second event id: 100 event: myevent data: third event id: 101 : this is a comment data: fourth event data: fourth event continue

    上面就是一个简单的demo. 每一段数据我们称之为事件, 每一个事件经过空行分隔. : 前面是数据类型,后面是数据. 通常的类型有:

  • 空类型: 表示注释,在处理是会默认被删除.比如 : this is a comment .

  • event: 声明该事件类型,比如message.

  • data: 最重要的一个类型, 表示传输的数据。可以为string格式或者JSON格式. 比如: data: {"username": "bobby"}

  • id: 其实就是lastEventId. 用来表明该次事件在整个流中的序号

  • retry: 用来表明浏览器断开再次连接之前等待的事件(不常用)

  • 其实上面最重要的两个字段就是data,id. 所以,我们一般获取的话就可以使用 event.data 和 event.lastEventId .

    上文说道, 每一段内容是通过换行实现的, 那服务器端应该怎么实现, 写入的操作呢?

    同样, 这里以nodeJS 为例:

    res.write("id: " + i + "\n"); res.write("data: " + i + "\n\n");

    通过使用'\n\n'进行两次换行操作--即,产生空行即可.

    使用自定义事件

    服务器端不仅可以返回指定数据,还可以返回指定事件.不过默认情况下都是 message 事件, 但我们也可以指定事件. 比如

    event: myevent data: third event id: 101

    这里出发的就是 myevent事件。 即, 这就是触发自定义事件的方式.在front-end 我们可以使用addEventListener 来进行监听.

    var source = new EventSource('/someEvents'); source.addEventListener('myevent', function(event){ //doSth }, false); 服务端使用SSE

    由于使用的是HTTP协议,所以对于服务端基本上没什么太大的改变. 唯一注意的就是, 发送数据使用res.write()即可,断开的时候使用res.end();

    res.writeHead(200, { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", "Access-Control-Allow-Origin": "*" //允许跨域 }); var num =0; var f = function(){ if(num===10){ res.end(); }else{ res.write("id: " + num + "\n"); res.write("data: " + num + "\n\n"); num++; } setTimeout(f,1000); } f();

    Ok~ 这里有一个 demo , 大家可以打开控制台看一下. 会发现,有一个连接一直处于Content-Download状态. 该连接就是一个SSE。

    兼容性

    目前SSE,在市面上大受欢迎, 不过总有一个SB, 离经叛道... 居然连edge都不支持. 偶尔去翻了一下,还在 underConsideration . 结果底下的评论基本都是xxxx. 有空可以去看看, 逼逼MS程序员.

    websocket

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • 聊聊前端和后台的数据交互与协议

      聊聊前端和后台的数据交互与协议

      2016-01-03 12:25

    • json处理总结(前端js和后端java)

      json处理总结(前端js和后端java)

      2015-11-25 09:22

    • Web前端 程序员之家论坛

      Web前端 程序员之家论坛

      2015-11-21 11:56

    • json与jsonp的区别

      json与jsonp的区别

      2015-11-19 11:29

    网友点评
    >