转载

基于Wilddog的实时web架构

实时需求一直都在,瓶颈在技术

HTTP协议头最重要的一个字段是Method,其中可选的值可以是Get,Post,Put,Delete 等。why?因为HTTP协议最根本的作用是对数据的读写。更广义的说就是对资源的访问。URL的作用是统一定位资源。可以说整个互联网是面向资源的。

HTTP协议的特点是短连接,基于请求响应,无状态。这些特点可以很好的满足非实时的资源访问,并不能满足实时需求。因为实时就意味着要么客户端与服务端一直有网络连接,要么就意味着服务端可以随时访问客户端。后一种可能性在现在的网络下是不可能实现的,因为很多客户端都在NAT后面。所以,实时数据传输的可能性就只有长连接。

技术进步的驱动力是需求,实时的需求其实一直都在。在真正能够让网页和服务端实现双向实时通信的技术之前伟大的程序员们就进行了各种实时化的尝试,比如:

  • Ajax polling:客户端使用Ajax每隔一定时间向服务端发起一次数据请求。实时性取决于请求的频次,而性能也决定于请求的频次,代价非常昂贵

基于Wilddog的实时web架构

  • Ajax long polling:跟Ajax polling的方式类似,不同之处是需要服务端keep-alive的支持。客户端不再定时发送数据请求,而是发送一个请求后一直等待,直到这个请求返回数据再发起下一次请求。比起polling进步的一点是可以做到真正的实时,而且性能明显提高,但依然不够高。 基于Wilddog的实时web架构

HTML5的WebSocket协议让真正的实时长连接变成了可能。WebSocket直接在客户端和服务端之间搭建了一条数据通道,实时高效,经济实惠。为什么说WebSocket经济实惠呢?因为websocket只是使用HTTP协议握手建联,真正的数据传输基于一个很小的二进制协议头,而不是巨大的基于文本的HTTP协议头。看一个对比就知道:

WebSocket相比于long polling能够节省更多的资源,这也就意味着相同的资源可以容纳更多的用户,性能不再是个问题。而且Websocket API 十分简单,一个前端工程师几分钟就可以学会。那么这是否意味着web实时化是件很简单的事情呢?

事情没有那么简单,标准是一回事,普通工程师能用的技术是另外一回事。这就好比为什么你可以直接操作DOM,却还是需要JQuery。标准提供的是完整,可用的API,而开发者希望拿到的是好用的API。单纯的Webocket协议并不解决以下问题:

  • 浏览器兼容性
  • 断线重连,会话维持
  • 服务端逻辑

每一个问题都会吓走大量的开发者,所以及时实时化很诱人,真正去做的人也很少。这个时候我们期待一个JQuery一样的工具帮我们解决这些问题。这样的工具也是存在,比如 Socket.io。Socket.io可以很好的解决上面的问题,实时需求是否能够真的满足?

实时数据同步解决问题

用户拿Socket.io 去开发一个一般的聊天应用已经足够了,就好像使用Jquery去开发一个不那么动态的web app已经足够了。然而HTML5让前端变得越来越复杂,直接操作DOM变成了一件很恶心的事情,因为往往一个操作会有多个DOM改变,而一个页面上能操作的东西非常多,这就意味着你要写很多事件处理函数,里面要写很多DOM操作。应对这样复杂场景需求,数据绑定的思想越来越被接受。像 Angular的双向数据绑定,React的单向数据绑定。

数据绑定的模型非常简单,就是一个数据对应一个DOM状态。数据到DOM状态的同步由框架来完成。操作DOM很头大,而操作数据就没那么麻烦了。一种编程模式是否足够好取决于是否简化了操作,和在简化操作的同时是否增加了限制。数据绑定的模式让DOM操作变成了数据操作,用户在写逻辑的时候不必关心DOM,简化了操作,而这种简化几乎没有对开发者带来任何限制。所以 数据绑定优于直接DOM操作。

同样的道理,数据同步优于直接数据传输

起始作为开发者,你并不想关心连接状态,数据流向。 但Html5让页面操作变得复杂的同时也让网络交互越来越频繁,尤其实时化后,你要注意接收和发送各种数据。你需要考虑这个数据是发给A还是发给B,你还要注意自己的连接状态和对方的连接状态,时间一久这种直接对数据传输的操作就面临向Jquery直接操作DOM一样的窘境,让人抓狂。这个时候就需要像数据绑定一样的思想来拯救你了。这就是服务端与客户端的数据同步。

为了好理解,做个比喻,工程师在写代码的时候都使用Git或SVN,我们写代码的时候并不直接把代码发送给其他协作者。我们只关注修改本地代码然后同步一下,就提交到中央仓库,对方再同步一下这个数据传输的过程就完成了。这里使用git做比喻仅仅是为了说明同步的原理,实际上Wilddog的使用场景跟git并没有关系。git同步的是代码,而Wilddog同步的是结构化数据。

我们看到同步的好处是:

  • 只关注本地逻辑,不关注其他端
  • 离线可用

理解了同步再理解实时同步就简单了:就是不断提交与不断同步的git。

Wilddog的实时数据同步同样具有上面提到的优点。

简单的例子:

//新建一个Wilddog引用,引用所指向的位置由url决定 var ref = new Wilddog("https://test-app.wilddogio.com/user/info");   //将原始数据和发生的变化都反应到DOM上 ref.on('value',function(snap){       var name = snap.val().name     setDOM(name)//把数据同步到dom }) //点击按钮设置数据 somebutton.onclick = function(){       var name = getNameFromDom();     ref.child("name").set(name); } 

这个例子中代码作用有两个

  • 点击 somebutton 在Wilddog数据库中保存 name
  • name 同步到DOM上,并且将后续的变化也实时同步到DOM

如果点击按钮,逻辑是这样进行的, 用户点击button->数据被修改->触发回调函数->DOM被修改

这个逻辑不论用户在线还是离线都是可以正常运行的。如果用户在线,这个对 name 的最新更改会马上同步到云端,并且同步给所有 on 了这部分数据的客户端。而如果用户不在线,那么这个更新会被缓存在本地,直到用户重新在线后数据再同步给服务端。

基于JSON的Nosql数据库

Wilddog在同步这件事情上与Git类似,不过在数据形态上却大不相同。事实上Wilddog客户端(服务端也一样)就是一个基于JSON的Nosql数据库。这个数据库能够提供基于JSON的数据读写操作和简单的数据查询。比如,可以这样保存用户的信息

{     "id":"123",     "name":"不知道怎么认真起个名",     "age":22,     friends:{         "123345":true,         "132":true     } } 

比如这段数据保存的位置是 https://YOUR-APP-ID.wilddogio.com/users/123 对这段数据读写非常简单

var ref = new Wilddog('https://YOUR-APP-ID.wilddogio.com/users/123');   ref.child('name').set("新名字");   ref.update({'age':23});   ref.on('value',function());   ref.child('friends').on('child_added',function(snap){       console.log(snap.key()) }) 

在Wilddog SDK中涉及数据写操作的API只有

  • set
  • update
  • remove
  • push

读操作的API有:

  • on
  • once

其中可能的事件有

  • value 任何修改都会触发回调
  • child_added 当有一个子节点被添加
  • child_removed 当有一个子节点被删除
  • child_changed 当一个子节点发生了改变
  • child_moved 当一个子节点位置发生了改变

Wilddog的API十分自由,你几乎可以访问Wilddog数据库里的所有数据。然而数据安全和隐私是所有人关注的。

Wilddog对于数据隐私和安全的考虑主要分两部分

  • 认证
  • 授权

先说认证,Wilddog提供多种认证方式,满足各种场景需求。

  • Email,密码登录
  • 微博微信等第三方OAuth登录
  • 匿名登录
  • 第三方帐号登录

所有的认证方式的目的都是一样的:给当前这个客户端的长连接绑定一个uid。这个uid在授权阶段使用。

再说授权。Wilddog的授权采用一种类似JSON的规则表达式,系统按照层级匹配规则,判断允许或组织其对数据的访问。

默认情况下的访问规则是

{   .read:true,   .write:true } 

意思是对于所有的数据,任何用户都可以自由读写。 上面的例子,如果我们要求只有uid与当前key匹配才可以读,而所有人都不可以写,就可以这样配

{   "user"{     "$userId":{       ".read":"$userId === auth.uid",       ".write":false     }   } } 

与已有系统集成的实时web架构

Wilddog数据是可以通过服务端访问的。Wilddog数据库中的数据结构不支持数组,原因是要做到RESTful,数据库中的任何一条数据都能够通过url直接访问到。所以服务端访问Wilddog的方式也非常简单,比如上面的例子中,通过http协议

GET https://YOUR-APP-ID.wilddogio.com/users/123/id.json   

你将得到

同样支持 POST,PUT,DELETE,PATCH操作,而且还支持SSE,与你的服务端实时数据同步。

原文  http://blog.jackxy.com/wilddogshi-shi-yao-gui/
正文到此结束
Loading...