Liferay Message Bus提供了松耦合的消息发送接收机制(生产和消费的设计模式),用于本地服务,不支持远程服务,支持集群。

主要用途:

  • 两个或多个插件之间的通讯。
  • 在事件中发送搜索索引,比如传递工作流的实例索引。
  • 发送订阅邮件或系统消息,比如在工作流中的待办到达时,给用户发送提醒消息。
  • 定时任务消息发送,比如在工作流中的定时任务启动时,给用户发送提醒消息。
  • 运行异步过程

主要分几个组件

  • Message Bus: 管理消息发送;
  • Destinations: 目标终端地址,用于注册监听者接收消息的地址;可以把它想象为邮件地址,或XMPP服务里的To JID;
  • Listeners: 消息接收者,即Receivers;
  • Senders: 发送者;

一个服务,即可以是接收者,也可以同时为发送者。

消息分为两种:

  • 1、同步消息,线程阻塞的消息,要求在一定时间内必须处理消息相应,否则抛出异常;
  • 2、异步消息,非阻塞,发送者可以指定两种消息,要求call-back和单向消息(Send-and-Forget,字面意思也很直观,就是发送然后忘了它)

配置文件:

  • WEB-INF/src/META-INF/messaging-spring.xml: 指定destinations、listeners、mappings关系;
  • WEB-INF/web.xml: 添加 messaging-spring.xml 到这个文件进行注册;

同步消息

同步消息很简单,就是发送-->接收一条流程。
首先要确定Destination (在messaging-spring.xml中配置)

现在以一个直观例子解释,比如要开一个演唱会,需要做一个Tasks portlet project,处理开唱前的各项准备工作,比如灯光、音响、升降机等设备的安装。
这个project有2类角色,一类是负责接收(发自Task的任务)的跑腿安装者(Setup),一类是负责管理任务的人(Task),用来给Setup下安装指令;

这两类人都具有Receivers、Senders功能;

比如Task通知Setup:去装座椅(这时Task是Sender,Setup是Receivers)
Setup马上收到消息开始干活,过了一段时间,座椅安装好了,Setup回消息给Task:座椅安装完毕!(这时Setup是Sender,Task是Receivers)
相对应的,需要先确定2个Destination Key:

不同角色对应的Destination

Destination Key Sender Receivers
tour/roadie/setup Tasks  Setup
tour/manager/task Setup  Tasks

消息发送处理

在我们的应用portlet中有TasksPortlet.java,在_updateTask 方法处理任务新建,(由Task新建任务)同时, 在添加新任务的时候发送消息(给Setup)

首先添加引用:
import com.liferay.portal.kernel.messaging.Message;
import com.liferay.portal.kernel.messaging.MessageBusException;
import com.liferay.portal.kernel.messaging.MessageBusUtil;

过程:

//1、New 一个 Message
Message message = new Message(); //2、通过key/value pairs写入消息
message.put("name", name);
message.put("description", description);
message.put("status", status); //3、设置response ID、response destination
//这是发送者给接收者指定的回发ID和回发响应地址
//可以想象一下,在发送电子邮件的时候,你的@地址是from发送者,对方接收后回复邮件给你,你的@地址就是收件人地址(to地址),
message.setResponseId("");
message.setResponseDestinationName("tour/manager/task"); //4、发送消息,10秒超时
//一旦超时,即抛出MessageBusException
try {
String roadieResponse = (String) MessageBusUtil.sendSynchronousMessage("tour/roadie/setup", message, );
} catch (MessageBusException e) {
e.printStackTrace();
}

消息接收

需要实现MessageListener接口,在SetupMessagingImpl.java中处理接收
首先添加引用
import com.liferay.portal.kernel.messaging.Message;
import com.liferay.portal.kernel.messaging.MessageBusUtil;
import com.liferay.portal.kernel.messaging.MessageListener;

过程:

//1、在receive(Message message)方法中获取message
String name = (String) message.get("name"); //2、创建response Message对象(基于MessageBusUtil.createResponseMessage(message)方法)
// 添加负载,是一个object,用于告诉管理者,我已经收到消息了
//(至于啥时候干完了,然后再通知管理者目前状态:我已经干完了,就又要另外想办法了,这种情况就不适合使用同步而是要用异步消息了)。
Message responseMessage = MessageBusUtil.createResponseMessage(message);
responseMessage.setPayload("RECEIVED"); //3、发送响应消息
MessageBusUtil.sendMessage(responseMessage.getDestinationName(), responseMessage);

WEB-INF/src/META-INF/messaging-spring.xml设置

<?xml version="1.0"?>
<beans
default-destroy-method="destroy"
default-init-method="afterPropertiesSet"
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
>
<!-- Listeners -->
<bean id="messageListener.setup_listener" class="com.tour.portlet.tasks.messaging.impl.SetupMessagingImpl" />
<!-- Destinations -->
<bean id="tour.roadie.setup" class="com.liferay.portal.kernel.messaging.SynchronousDestination">
<property name="name" value="tour/roadie/setup" />
</bean>
<bean id="tour.manager.task" class="com.liferay.portal.kernel.messaging.SynchronousDestination">
<property name="name" value="tour/manager/task" />
</bean>
<!-- Configurator -->
<bean id="messagingConfigurator" class="com.liferay.portal.kernel.messaging.config.PluginMessagingConfigurator">
<property name="messageListeners">
<map key-type="java.lang.String" value-type="java.util.List">
<entry key="tour/roadie/setup">
<list value-type="com.liferay.portal.kernel.messaging.MessageListener">
<ref bean="messageListener.setup_listener" />
</list>
</entry>
</map>
</property>
<property name="destinations">
<list>
<ref bean="tour.roadie.setup"/>
<ref bean="tour.manager.task"/>
</list>
</property>
</bean>
</beans>

web.xml设置

<listener>
<listener-class>com.liferay.portal.kernel.spring.context.PortletContextLoaderListener</listener-class>
</listener> <context-param>
<param-name>portalContextConfigLocation</param-name>
<param-value>/WEB-INF/classes/META-INF/messaging-spring.xml</param-value>
</context-param>

异步消息

通过JSONObject作为消息体。


分为两种:
要求call-back的消息:
https://dev.liferay.com/develop/tutorials/-/knowledge_base/6-2/asynchronous-messaging-with-callbacks

单向消息(Send-and-Forget,字面意思也很直观,就是发送然后忘了它):
https://dev.liferay.com/develop/tutorials/-/knowledge_base/6-2/asynchronous-send-and-forget-messaging

Liferay7 BPM门户开发之21: 理解消息总线(Message Bus)体系的更多相关文章

  1. Liferay7 BPM门户开发之12:acitiviti和liferay用户权限体系集成

    写到第12章才出现Liferay的内容,希望可以厚积薄发. 我们的目标是不使用不维护Activiti的用户组织架构,只维护Liferay的体系,这样的好处是非常明显的,即不用做组织架构的同步工作. 原 ...

  2. Liferay7 BPM门户开发之20: 理解Asset Framework

    Asset框架用于将您开发的门户内容添加Liferay的核心系统功能.打个比方,你开发了一个事件TodoList管理的插件,在列表显示的时候,你可以集成Asset框架,让你的自定义内容支持Tag标签. ...

  3. Liferay7 BPM门户开发之19: 理解Service Builder体系

    Service Builder是Liferay为业务开发而设计的模型驱动(model-driven)平台工具,提供一系列的实体类.数据持久化.服务相关的代码自动生成服务.支持Hibernate and ...

  4. Liferay7 BPM门户开发之37: Liferay7下的OSGi Hook集成开发

    hook开发是Liferay客制扩展的一种方式,比插件灵活,即可以扩展liferay门户,也能对原有特性进行更改,Liferay有许多内置的服务,比如用hook甚至可以覆盖Liferay服务. 可作为 ...

  5. Liferay7 BPM门户开发之17: Portlet 生命周期

    Portlet 生命周期 init() =〉 render() =〉 processAction() =〉 processEvent() =〉 serveResource() =〉destroy() ...

  6. Liferay7 BPM门户开发之10: 通用流程实现从Servlet到Portlet(Part1)

    开发目的: 实现通用流程自动化处理(即实现不需要hardcode代码的bpm统一处理后台,仅需要写少量前端html form代码和拖拽设计BPM定义) 既可独立运行或可依托于Liferay或依托其它门 ...

  7. Liferay7 BPM门户开发之44: 集成Activiti展示流程列表

    处理依赖关系 集成Activiti之前,必须搞清楚其中的依赖关系,才能在Gradle里进行配置. 依赖关系: 例如,其中activiti-engine依赖于activiti-bpmn-converte ...

  8. Liferay7 BPM门户开发之32: 实现自定义认证登陆(定制Authentication Hook)

    第一步:修改liferay-hook.xml <?xml version="1.0"?> <!DOCTYPE hook PUBLIC "-//Lifer ...

  9. Liferay7 BPM门户开发之27: MVC Portlet插件工程开发

    官网上的教材说实话实在精简不清晰. https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/creating-an-mvc-por ...

随机推荐

  1. TZOJ 1693 Silver Cow Party(最短路+思维)

    描述 One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big ...

  2. ubuntu输入法

    一直都是使用搜狗的,但是感觉一直都不兼容.经常输入一串文字导致输入法崩溃 比如 ‘外显’waixian就崩了. 而且会出现fcitx 100%cpu占用的情况 pkill fcitx &&am ...

  3. C++ static 静态变量&静态成员函数

    .h文件中定义 static变量后,如 static QTcpSocket * socket; 那么一定要在.cpp中 构造函数的外面将其初始化为 QTcpSocket * Cfiletransfer ...

  4. Object.defineProperty之observe实现

    对数据对象的属性批量劫持设置: <script type="text/javascript"> function observe(data){ if(!data || ...

  5. Chapter3_操作符_直接常量和指数计数法

    (1)直接常量 在程序中使用直接常量,相当于指导编译器,告诉它要生成什么样的类型,这样就不会产生模棱两可的情况.比如flaot a = 1f等,后缀表示告诉编译器想生成的类型.常用的后缀有l/L(lo ...

  6. hibernate的Could not execute JDBC batch update错误原因及处理

    http://blog.csdn.net/derpvailzhangfan/article/details/2332795\ 上述问题: 一设置关联 二包含关键字 三 映射文件设置 catalog=“ ...

  7. Spring AOP配置方式

    AOP 面向切面编程,允许在 java 应用中的方法调用的前后做一些处理. 本文通过实例介绍两种主要的Spring AOP 配置方式:xml 方式配置,注解方式配置 XML 方式配置 1. 项目包类结 ...

  8. 11. English vocabulary 英语词汇量

    11. English vocabulary 英语词汇量 (1) The exact number of English words is not known.The large dictionari ...

  9. MySQL 三 二进制安装

    二进制格式安装   何谓二进制格式安装?   二进制格式安装,编译好的打包在tar文件里,安装时需要下载后解包至编译时指定的位置,然后进行相关配置,完成安装   版本信息:CentOS 7.4 安装m ...

  10. XamlWriter-将对象树写入Xaml

    WPF通常用Xaml格式创建对象树.您还可以使用XamlWriter类进行反方向操作——将对象树写入Xaml. 对于XamlWriter来说,将对象转换成良好的Xaml表示形式通常很容易.但是,您不能 ...