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. java实现两个不同list对象合并后并排序

    工作上遇到一个要求两个不同list对象合并后并排序1.问题描述从数据库中查询两张表的当天数据,并对这两张表的数据,进行合并,然后根据时间排序.2.思路从数据库中查询到的数据放到各自list中,先遍历两 ...

  2. db2开启监控monitor 查看快照snapshot

    ths   https://blog.csdn.net/huaishu/article/details/9671771 #查看监控器 db2 get monitor switches #打开监控器db ...

  3. extJs相关名字解释

      1.initComponent 初始化部件启动 2.defaults : Object defaults属性可以包含任意个name/value属性对,这些属性将会被添加到每一个元素中...例如, ...

  4. SQL Server 定价及授权方式

    https://www.microsoft.com/zh-cn/sql-server/sql-server-2017-pricing http://www.360doc.com/content/15/ ...

  5. Head First Servlets & JSP 学习笔记 第六章 —— 会话状态

    MVC中的M(模型),通常就是一个普通的类,这个类里面的信息就是业务逻辑. 会话(Session) 我们可以使用一个HttpSession对象,来保存横跨多个请求的会话状态. HTTP协议使用的是无状 ...

  6. vue组件之时间组件

    效果图 主要有两个注意点,前面时分,通过定时器,1秒钟取一次,只要数据变了立刻让他展示,当然也可以1分钟取一次,我看了下定时器和真正的时间 其实有一定的偏差的,大约要1分多才会改变,所以我用了1秒取一 ...

  7. VS中程序包错误,引用错误该如何解决

    1.找到包的文件.packages.config 对应于: 2.删除掉 packages.config 报错的项.然后再重新添加一次.就没有解决的不了的问题. 是不是很爽.....

  8. python 数据可视化 -- 读取数据

    从 CSV 文件中读取数据(CSV) import sys import csv # python 内置该模块 支持各种CSV文件 file_name = r"..\ch02_data\ch ...

  9. linux批量修改文件中包含字符串的查找替换

    find -name "*.env" | xargs perl -pi -e 's|\babcdefg\b|hahaha|g' .env 文件中abcdef 改为hahaha

  10. cpp 区块链模拟示例(三)新基本原形工程的建立

    /* 作 者: itdef 欢迎转帖 请保持文本完整并注明出处 技术博客 http://www.cnblogs.com/itdef/ 技术交流群 群号码:432336863欢迎c c++ window ...