在Event bus的消息实践上实现实时WEB特性 译<十三>

TIP:这部分相应的代码在step-10文件夹中(https://github.com/vert-x3/vertx-guide-for-java-devs)html

在以前的guide中,咱们能够看到用event bus来链接verticles通信,经过传递消息的形式,开发者仅仅须要java

注册消费者来接受和发送订阅消息。git

SockJS event bus bridge拓展了客户端,浏览器的能力,建立一个分布式的event bus,不只能够是集群中不一样的verticle实例,也能够是客户端浏览器上运行的JavaScript程序。所以咱们能够建立包含浏览器和服务端的大的分布式event bus,在基于消息分布式应用中须要肯定结果一致性。github

在这个章节,咱们将会修改step-9中的代码:web

  Markdown的内容渲染发送到服务端,不发送HTTP请求数据库

  若是用户编辑的页面已经被其余用户编辑将提示一个warningnpm

创建 SockJS event bus bridge编程

NOTE:SockJS是个客户端的JavaScript库,遵照提供一个相似WebSocket接口的协议,不论实际的浏览器或网络WebSockets,它支持各类不一样的浏览器和服务器之间传输,选择一个运行的。浏览器

第一步,咱们须要装上vertx-web提供的SockJSHandler:服务器

    1.为Vert.x实例建立一个新的SockJSHandler

    2.容许浏览器传递的消息来着app.markdown地址,咱们也用这个地址来获取服务器执行咱们在页面上执行的编辑的Markdown内容。

    3.容许发送消息到page.saved地址的浏览器,咱们将使用这个地址来通知浏览器,当页面被编辑的时候。

    4.配置bridge SockJS traffic到Event bus

    5.处理/ eventbus路径下全部的请求。

CAUTION:对于大多数应用程序,您可能不但愿客户端JavaScript可以发送任何消息给服务器上的任何处理程序,或其余浏览器。例如:

    1.你可能有一个service在event bus上,能够访问或删除数据的服务,显然咱们不但愿表现差的或恶意的客户可以删除数据库中的全部数据。

    2.咱们没有必要让客户端能够监放任何事件总线地址。

为了解决这个问题,一个SockJS bridge将默认拒绝任何信息。这就是为何它是由你来告诉个人消息是否经过该桥(做为例外,回复消息老是容许经过)

在客户端

如今服务端已经准备好接受消息,咱们将配置客户端

第一,咱们SockJS和Vert.x event bus JavaScript端须要load,最简单的方式是从网络服务中获取:

NOTE:事件总线客户端能够先下载预捆绑应用,可使用maven,npm,bower,甚至wevjars仓库

而后建立一个EventBus Javascript实例:

var eb = new EventBus(window.location.protocol + "//" + window.location.host + "/eventbus");

发送Markdown内容到event bus 

SockJS bridge 运行起来后,为了将Markdown内容发送到服务端,咱们须要注册一个消费者,这个消费者将消息发送到app.markdown地址:

vertx.eventBus().<String>consumer("app.markdown", msg -> {
  String html = Processor.process(msg.body());
  msg.reply(html);
});

这里没有什么新东西,咱们以前已经建立了一个event bus消费者,而后咱们看看在付端端修改了什么代码:

    1.reply程序方法有两个参数:一个error(若是须要)和一个reply对象,reply对象的内容包含在body中

    2.由于 event bus client没有被AngularJS管理,$scope.$apply用于生命周期的回调

    3.当咱们使用$http,借助updateRendering来处理HTML结果。

诚然,这代码和HTTP endpoint代码相似,然而好处是不依赖于代码的行数编号。事实上,若是你在 event bus进行服务端的通讯,bridge透明的处理分布的注册消费者的消息。所以,当Vert.x运行在集群模式中,这浏览不是联系一个当以的服务器程序(除了sockjs链接),更重要的是对服务器的链接是永远不会关闭,因此HTTP / 1.1这节省了为每一个请求创建一个TCP链接,这多是有用的,若是你有服务器和客户端之间的交流不少。

当页面被他人修改提示Warning

在不少的应用中,咱们老是以最后的提交为准则来处理这个冲突:当两个用户在同一个时间编辑相同的资源,最后一个提交保存的会覆盖前个的修改。

针对这个问题咱们有多重方式,像实体版本,或者分布式的拓展字段。然而,让咱们坚持一个简单的解决方案,看看咱们如何可以通知用户当变化,至少他获得一个机会来处理状况。一旦数据库中的内容修改,用户能够决定最好的行动是什么:改写或从新加载。

咱们须要添加一个 alert alert-warning 信息到 div中,可是咱们仅仅在pageModified设置为true的状况下展现。

<div class="col-md-12">
  <div class="alert alert-warning ng-class:{'invisible': !pageModified};" role="alert">
    The page has been modified by another user.
    <a href="#" ng-click="load(pageId)">Reload</a>
  </div>
</div>

当页面被保存的时候pageModified设置为true,咱们从page.saved地址注册event bus程序:

    1.咱们不想打印警告若是咱们修改本身的内容,咱们须要一个客户端标识符

    2.回调地址将会出发在消息被page.saved地址接收

    3.检查body是否为空

    4.肯定event是关联到当前wiki 页面

    5.肯定没有修改

    6.设置pageModified true

当页面的额内容被保存到数据库的时候须要发送消息:

    1.rxSavePage返回Single<Void>对象,成功后发送一个event

    2.消息包含一个页面标识

    3.消息包含一个客户端标识

    4.event被发送到page.saved 地址

若是咱们打开应用在两个不一样的tabs,能够是同一个浏览器或者是不一样的,选择相同的页面,在其中一个更新信息,另外一个个提示警告信息:

咱们能够简单的拓展SockJS bridge为了其余目的,像有多少用户在同一个页面,支持一个实时聊天的窗口等等。关键的一点是,在服务器和客户端共享相同的编程模型,经过消息传递的事件总线。

原文连接:http://vertx.io/docs/guide-for-java-devs/

个人微信公众号:

相关文章
相关标签/搜索