Camunda消息事件(Message events)是引用已命名消息的事件。一条消息有一个名称和一个有效负载。与信号不同,消息事件总是指向单个收件人。消息事件定义是通过使用messageEventDefinition元素声明的。messageRef属性引用声明为定义根元素的子元素的消息元素。


Camunda消息事件包括:Message Start Event(消息启动事件)、Message Intermediate Catching Event(消息中间捕获事件)、Message Boundary Event(消息边界事件)、Message Intermediate Throwing Event(消息中断抛出事件)、Message End Event(消息结束事件)。


本文重点介绍Message Start Event(消息启动事件),其它事件请参考camunda官方文档:https://docs.camunda.org/manual/7.15/reference/bpmn20/events/


一、设计流程图


以下通过模拟订票业务,来说明如何通过消息触发启动流程。


发送消息主流程:



发送消息节点配置:



通过一个Java类模拟触发消息事件:


package com.example.demo1;import org.camunda.bpm.engine.RuntimeService;import org.camunda.bpm.engine.delegate.DelegateExecution;import org.camunda.bpm.engine.delegate.JavaDelegate;/** * 触发消息启动模拟类 */public class InstantiateProcessByMessageDelegate implements JavaDelegate { public void execute(DelegateExecution execution) { String type = (String)execution.getVariable("type"); RuntimeService runtimeService = execution.getProcessEngineServices().getRuntimeService(); if(type!=null && type.equals("tel")){ runtimeService.startProcessInstanceByMessage("telMessage"); }else{ runtimeService.startProcessInstanceByMessage("pcMessage"); } }}


主流程BPMN流程模型文件:


<?xml version="1.0" encoding="UTF-8"?><bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="_TZZ5cHYXEeSiaf32_fRHjA" targetNamespace="http://camunda.org/examples" exporter="Camunda Modeler" exporterVersion="4.8.1" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"> <bpmn2:process id="Instantiating_Process" name="消息发起主流程" isExecutable="true"> <bpmn2:startEvent id="StartEvent_1" name="开始"> <bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing> </bpmn2:startEvent> <bpmn2:serviceTask id="ServiceTask_1" name="发送消息" camunda:class="com.example.demo1.InstantiateProcessByMessageDelegate"> <bpmn2:incoming>SequenceFlow_1</bpmn2:incoming> <bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing> </bpmn2:serviceTask> <bpmn2:sequenceFlow id="SequenceFlow_1" name="" sourceRef="StartEvent_1" targetRef="ServiceTask_1" /> <bpmn2:userTask id="UserTask_1" name="业务办理" camunda:assignee="demo"> <bpmn2:incoming>SequenceFlow_2</bpmn2:incoming> <bpmn2:outgoing>SequenceFlow_3</bpmn2:outgoing> </bpmn2:userTask> <bpmn2:sequenceFlow id="SequenceFlow_2" name="" sourceRef="ServiceTask_1" targetRef="UserTask_1" /> <bpmn2:endEvent id="EndEvent_1" name="结束"> <bpmn2:incoming>SequenceFlow_3</bpmn2:incoming> </bpmn2:endEvent> <bpmn2:sequenceFlow id="SequenceFlow_3" name="" sourceRef="UserTask_1" targetRef="EndEvent_1" /> </bpmn2:process> <bpmndi:BPMNDiagram id="BPMNDiagram_1"> <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Instantiating_Process"> <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_3" bpmnElement="SequenceFlow_3" sourceElement="_BPMNShape_UserTask_2" targetElement="_BPMNShape_EndEvent_49"> <di:waypoint x="554" y="118" /> <di:waypoint x="604" y="118" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_2" bpmnElement="SequenceFlow_2" sourceElement="_BPMNShape_ServiceTask_2" targetElement="_BPMNShape_UserTask_2"> <di:waypoint x="360" y="118" /> <di:waypoint x="454" y="118" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="SequenceFlow_1" sourceElement="_BPMNShape_StartEvent_13" targetElement="_BPMNShape_ServiceTask_2"> <di:waypoint x="188" y="118" /> <di:waypoint x="260" y="118" /> </bpmndi:BPMNEdge> <bpmndi:BPMNShape id="_BPMNShape_UserTask_2" bpmnElement="UserTask_1"> <dc:Bounds x="454" y="78" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="_BPMNShape_EndEvent_49" bpmnElement="EndEvent_1"> <dc:Bounds x="604" y="100" width="36" height="36" /> <bpmndi:BPMNLabel> <dc:Bounds x="612" y="143" width="22" height="14" /> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="_BPMNShape_ServiceTask_2" bpmnElement="ServiceTask_1"> <dc:Bounds x="260" y="78" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="_BPMNShape_StartEvent_13" bpmnElement="StartEvent_1"> <dc:Bounds x="152" y="100" width="36" height="36" /> <bpmndi:BPMNLabel> <dc:Bounds x="159" y="143" width="22" height="14" /> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram></bpmn2:definitions>


消息事件子流程:



消息事件节点配置:



子流程BPMN流程模型文件:


<?xml version="1.0" encoding="UTF-8"?><bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="_ersGAHYXEeSiaf32_fRHjA" targetNamespace="http://camunda.org/examples" exporter="Camunda Modeler" exporterVersion="4.8.1" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"> <bpmn2:process id="Message_Start_Process" name="订票业务流程" isExecutable="true"> <bpmn2:startEvent id="StartEvent_1" name="电话订票事件"> <bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing> <bpmn2:messageEventDefinition id="MessageEventDefinition_1" messageRef="Message_1" /> </bpmn2:startEvent> <bpmn2:userTask id="UserTask_1" name="电话接听处理" camunda:assignee="demo"> <bpmn2:incoming>SequenceFlow_1</bpmn2:incoming> <bpmn2:outgoing>Flow_0waoc5v</bpmn2:outgoing> </bpmn2:userTask> <bpmn2:sequenceFlow id="SequenceFlow_1" name="" sourceRef="StartEvent_1" targetRef="UserTask_1" /> <bpmn2:endEvent id="EndEvent_1" name="结束"> <bpmn2:incoming>Flow_1rob1g6</bpmn2:incoming> </bpmn2:endEvent> <bpmn2:startEvent id="Event_1v29b3m" name="网站订票事件"> <bpmn2:outgoing>Flow_0xy81oh</bpmn2:outgoing> <bpmn2:messageEventDefinition id="MessageEventDefinition_1719j4p" messageRef="Message_06gkrpi" /> </bpmn2:startEvent> <bpmn2:sequenceFlow id="Flow_0xy81oh" sourceRef="Event_1v29b3m" targetRef="Activity_065n4o2" /> <bpmn2:userTask id="Activity_065n4o2" name="网站自助处理" camunda:assignee="demo"> <bpmn2:incoming>Flow_0xy81oh</bpmn2:incoming> <bpmn2:outgoing>Flow_0mwncvx</bpmn2:outgoing> </bpmn2:userTask> <bpmn2:sequenceFlow id="Flow_0waoc5v" sourceRef="UserTask_1" targetRef="Activity_07rexvn" /> <bpmn2:sequenceFlow id="Flow_0mwncvx" sourceRef="Activity_065n4o2" targetRef="Activity_07rexvn" /> <bpmn2:sequenceFlow id="Flow_1rob1g6" sourceRef="Activity_07rexvn" targetRef="EndEvent_1" /> <bpmn2:scriptTask id="Activity_07rexvn" name="出票" scriptFormat="JavaScript"> <bpmn2:incoming>Flow_0waoc5v</bpmn2:incoming> <bpmn2:incoming>Flow_0mwncvx</bpmn2:incoming> <bpmn2:outgoing>Flow_1rob1g6</bpmn2:outgoing> <bpmn2:script>execution.setVariable("buyTicket","ok");</bpmn2:script> </bpmn2:scriptTask> </bpmn2:process> <bpmn2:message id="Message_1" name="telMessage" /> <bpmn2:message id="Message_06gkrpi" name="pcMessage" /> <bpmndi:BPMNDiagram id="BPMNDiagram_1"> <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Message_Start_Process"> <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="SequenceFlow_1" sourceElement="_BPMNShape_StartEvent_14" targetElement="_BPMNShape_UserTask_3"> <di:waypoint x="236" y="126" /> <di:waypoint x="340" y="126" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="Flow_0xy81oh_di" bpmnElement="Flow_0xy81oh"> <di:waypoint x="236" y="260" /> <di:waypoint x="340" y="260" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="Flow_0waoc5v_di" bpmnElement="Flow_0waoc5v"> <di:waypoint x="440" y="126" /> <di:waypoint x="485" y="126" /> <di:waypoint x="485" y="190" /> <di:waypoint x="530" y="190" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="Flow_0mwncvx_di" bpmnElement="Flow_0mwncvx"> <di:waypoint x="440" y="260" /> <di:waypoint x="485" y="260" /> <di:waypoint x="485" y="210" /> <di:waypoint x="530" y="210" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="Flow_1rob1g6_di" bpmnElement="Flow_1rob1g6"> <di:waypoint x="630" y="190" /> <di:waypoint x="712" y="190" /> </bpmndi:BPMNEdge> <bpmndi:BPMNShape id="_BPMNShape_StartEvent_14" bpmnElement="StartEvent_1"> <dc:Bounds x="200" y="108" width="36" height="36" /> <bpmndi:BPMNLabel> <dc:Bounds x="187" y="151" width="67" height="14" /> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="_BPMNShape_UserTask_3" bpmnElement="UserTask_1"> <dc:Bounds x="340" y="86" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Event_1f38wnq_di" bpmnElement="Event_1v29b3m"> <dc:Bounds x="200" y="242" width="36" height="36" /> <bpmndi:BPMNLabel> <dc:Bounds x="185" y="285" width="67" height="14" /> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Activity_1n0yeg5_di" bpmnElement="Activity_065n4o2"> <dc:Bounds x="340" y="220" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="_BPMNShape_EndEvent_50" bpmnElement="EndEvent_1"> <dc:Bounds x="712" y="172" width="36" height="36" /> <bpmndi:BPMNLabel> <dc:Bounds x="720" y="215" width="22" height="14" /> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Activity_0xkaeuy_di" bpmnElement="Activity_07rexvn"> <dc:Bounds x="530" y="150" width="100" height="80" /> </bpmndi:BPMNShape> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram></bpmn2:definitions>


二、发起流程测试


通过demo用户登录camunda平台http://localhost:8080/camunda/app/tasklist/default/#/login,发起主流程。


填写流程变量type值为tel,表示要触发子流程的电话订票消息事件:



启动主流程后,通过Message Start Event(消息启动事件)自动发起子流程,流程状态如下:



如果填写流程变量type值为pc,表示要触发子流程的网站订票消息事件.


三、消息启动事件接口说明


1、如何触发消息事件?


作为一个可嵌入的流程引擎,Camunda引擎与消息的接收部分无关。这将依赖于环境,并需要特定于平台的活动,如连接到JMS (Java消息传递服务)队列/主题或处理Webservice或REST请求。因此,您必须将消息接收作为嵌入流程引擎的应用程序或基础设施的一部分来实现。接收到消息后,可以选择是使用引擎的内置关联,还是显式地交付消息以启动新的流程实例或触发等待执行。


消息启动事件可用于使用命名消息启动流程实例。这有效地允许我们使用消息名从一组可选启动事件中选择正确的启动事件。Camunda流程引擎提供了一个基本的关联机制,它可以向等待特定消息的执行发出信号,也可以用匹配的消息启动事件实例化进程。RuntimeService提供了流畅的消息相关性API:


ProcessInstance startProcessInstanceByMessage(String messageName);ProcessInstance startProcessInstanceByMessage(String messageName, Map<String, Object> processVariables);ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey, Map<String, Object> processVariables);


2、如何查询消息事件订阅


引擎支持消息启动事件和中间消息事件。对于消息启动事件,消息事件订阅与特定的流程定义关联。这样的消息订阅可以使用ProcessDefinitionQuery查询:


ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().messageEventSubscription("newCallCenterBooking").singleResult();


消息事件存储在数据库act_ru_event_subscr表:



参考:


https://docs.camunda.org/manual/7.15/reference/bpmn20/events/message-events/