• Liferay7 BPM门户开发之21: 理解消息总线(Message Bus)体系


    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("1111");
    message.setResponseDestinationName("tour/manager/task");
    
    //4、发送消息,10秒超时
    //一旦超时,即抛出MessageBusException
    try {
    String roadieResponse = (String) MessageBusUtil.sendSynchronousMessage("tour/roadie/setup", message, 10000);
    } 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

  • 相关阅读:
    ssh框架下 写简单的hql语句
    onclick事件 在使用模板填充情况下 向后台传递多值
    调用 sendResponseMsg 遇到的问题
    ERP项目有关时间的修改和查看的显示,去掉时分秒
    ERP中select的填充方法
    最简单的jQuery ajax请求
    ERP中默认申请人和申请部门
    list 按元素的某字段排序方法。作者:黄欣
    C# 对象、文件与二进制串(byte数组)之间的转换【转载】
    .net framework(4.6.2) 迁移 .net core(2.2) 总结
  • 原文地址:https://www.cnblogs.com/starcrm/p/6047118.html
Copyright © 2020-2023  润新知