Flowable工作流结果实时返回方案


当后端 Flowable 工作流处理完毕并得到结果时,如何将这个结果返回给前端 Bpmn.js,以及前端是根据 historyInstance 查询到执行完成再去发送请求,还是后端直接返回结果,这主要取决于你的业务需求和对实时性的要求。

这两种方式各有优缺点,下面我们来详细分析:

1. 前端通过 historyInstance 查询(轮询)

工作原理:

  1. 启动流程后,后端返回流程实例ID给前端。
  2. 前端定期向后端发送请求,查询 Flowable 的 historyInstance API。 这个查询通常会带上之前获取到的流程实例ID。
  3. 后端调用 Flowable 的 historyService 查询流程或特定节点的历史状态。
  4. 当前端查询到流程或特定任务/节点的状态变为“完成”时, 它就知道可以发送一个新的请求给后端,去获取最终的业务处理结果。

优点:

  • 实现简单直接: 对于不追求极致实时性的场景,这种方式开发起来相对简单。
  • 解耦性好: 前后端相对独立,前端根据自己的节奏去拉取数据。

缺点:

  • 实时性差: 结果的返回会有延迟,取决于你设置的轮询间隔
  • 增加服务器压力: 频繁的轮询会增加后端和 Flowable 的查询压力,尤其是在并发量高的情况下。
  • 不必要的网络请求: 在流程未完成时,会产生很多无效的查询请求。
  • 用户体验一般: 用户需要等待一段时间才能看到结果,可能感到卡顿或不流畅。

2. 后端直接通知前端

工作原理:

  1. Flowable 流程执行到关键节点(如:流程结束节点、特定服务任务完成节点),触发后端业务逻辑。 这通常通过在 Flowable 的服务任务 (Service Task) 中编写代码,或者使用 Flowable 事件监听器来实现。
  2. 后端获取到流程处理的最终结果。
  3. 后端直接将结果“推送”给前端。 这可以通过以下技术实现:
    • WebSocket: 建立持久化的双向连接。后端可以直接向前端发送消息,实现实时通信。这是最推荐的方式。
    • Server-Sent Events (SSE): 基于 HTTP 的单向通信,后端可以持续向前端推送事件流。适合后端只向前端发送更新的场景。
    • 长轮询 (Long Polling): 前端发送请求后,后端不立即响应,而是等待有数据更新或超时后再响应。相比普通轮询,减少了不必要的请求,但不如 WebSocket 实时

优点:

  • 实时性强: 结果一旦产生,前端几乎可以立即接收到,用户体验极佳。
  • 减少不必要的网络请求: 只有在有数据更新时才进行通信。
  • 提升用户体验: 用户能即时看到流程进展和最终结果。

缺点:

  • 实现复杂性增加: 需要引入 WebSocket 或 SSE 等技术,对后端和前端都有一定的开发成本。
  • 服务器资源消耗: 维护大量的 WebSocket 连接可能会消耗一定的服务器资源。

推荐方案

综合来看,后端直接通知前端是更现代化、用户体验更好的方案,尤其推荐使用 WebSocket

具体步骤建议:

  1. 在 Flowable 中设计流程: 当流程或某个关键任务完成时,添加一个服务任务 (Service Task)
  2. 后端实现服务任务逻辑: 在这个服务任务中,编写 Java 代码(或你使用的后端语言代码),执行以下操作:
    • 获取 Flowable 流程的最终结果或相关业务数据。
    • 通过 WebSocket 连接,向前端发送一条消息。这条消息可以包含流程实例ID、当前状态、以及处理结果等信息。
  3. 前端 (Bpmn.js 应用) 建立 WebSocket 连接:
    • 前端页面加载时,与后端建立 WebSocket 连接。
    • 监听后端发送过来的 WebSocket 消息。
    • 一旦收到后端发送的包含流程结果的消息,前端可以根据流程实例ID来更新 Bpmn.js 界面的状态,例如高亮已完成的节点,显示最终结果,或者触发其他业务逻辑。

WebSocket:使用WebSocket实现前端和后端之间的实时双向通信,当后端状态发生变化时,立即通知前端更新状态。
轮询:前端定期向后端发送请求,获取最新的运行状态。虽然这种方式不如WebSocket实时,但在某些场景下可能更简单。

轮询、SSE、WebSocket 选型对比与前端面试高频考点解析


一、核心对比与适用场景

以下是三种技术的核心差异与典型应用场景总结,建议结合业务需求选择:

维度轮询(Polling)SSE(Server-Sent Events)WebSocket
通信方向客户端→服务端(单向请求)服务端→客户端(单向推送)双向全双工通信
协议HTTP 短连接(每次请求独立)HTTP 长连接(基于事件流)TCP 自定义协议(需协议升级)
实时性依赖轮询间隔(秒级延迟)亚秒级(服务端主动推送)毫秒级(即时双向通信)
开发复杂度低(仅需 setInterval中(需处理连接状态)高(需管理握手、心跳、重连)
浏览器兼容性全兼容(包括 IE)现代浏览器(IE 不支持)现代浏览器(需降级方案)
资源消耗高(频繁建立 HTTP 连接)中(单长连接)高(维护 TCP 连接)
适用场景低频更新(如配置同步)服务端单向实时推送(如通知、监控)高频双向交互(如聊天、游戏)

二、面试高频问题与解析
1. 如何选择技术方案?

考察点:对业务场景的理解与技术权衡能力。
参考回答

  • 优先选 SSE:若需服务端单向推送(如实时日志、消息通知),且无需复杂双向交互。
  • 必选 WebSocket:若需双向高频通信(如在线协作、即时聊天)。
  • 慎用轮询:仅作为兼容旧浏览器或极低频场景的降级方案。
    示例

“电商后台的订单状态更新适合用 SSE,因为服务端可主动推送变更;而实时对战游戏必须用 WebSocket 实现低延迟交互。”

2. SSE 如何实现自动重连?

考察点:对 SSE 特性的掌握。
参考回答
SSE 内置自动重连机制(默认 3 秒),可通过 EventSourcereconnectionTime 属性调整间隔。若需自定义逻辑(如指数退避),可监听 error 事件:

const sse = new EventSource('/stream');
sse.onerror = (err) => {
  console.log('连接失败,5秒后重试');
  setTimeout(() => sse.close(), 5000);
};
3. WebSocket 如何兼容低版本浏览器?

考察点:兼容性解决方案。
参考回答

  • 降级方案
    1. 长轮询(Long Polling):模拟实时性,但需手动管理请求队列。
    2. SSE + Polyfill:使用 eventsource-polyfill 兼容 IE。
  • 替代协议
    使用 Socket.IO 等库,自动处理协议降级(如长轮询→WebSocket)。
4. 轮询的优化技巧有哪些?

考察点:性能优化能力。
参考回答

  • 长轮询(Long Polling):服务端挂起请求直至数据更新,减少无效请求。
  • 条件轮询:根据业务状态动态调整轮询频率(如无数据时延长间隔)。
  • ETag 缓存:通过 If-None-Match 头避免重复传输相同数据。
5. 如何保证 WebSocket 消息的可靠性?

考察点:高并发与容错设计。
参考回答

  • 消息确认机制:客户端收到消息后返回 ACK,服务端重发未确认消息。
  • 心跳检测:定时发送心跳包(如每 30 秒),超时则重连。
  • 消息队列:服务端缓存离线消息,客户端重连后拉取。

三、实战场景与代码示例
场景 1:实时股票行情(SSE)
// 前端
const sse = new EventSource('/stock-prices');
sse.addEventListener('message', (e) => {
  const data = JSON.parse(e.data);
  updateChart(data); // 更新图表
});

// 后端(Node.js)
app.get('/stock-prices', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  const sendUpdate = () => {
    res.write(`data: ${JSON.stringify(getStockData())}\n\n`);
  };
  setInterval(sendUpdate, 1000);
});
场景 2:聊天室(WebSocket)
// 前端
const ws = new WebSocket('wss://chat.com');
ws.onmessage = (e) => {
  appendMessage(e.data);
};
ws.send(JSON.stringify({ text: 'Hello!' }));

// 后端(Node.js + ws 库)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {
  ws.on('message', (msg) => {
    wss.clients.forEach(client => client.send(msg));
  });
});

四、总结与进阶建议
  1. 选型原则

    • 单向推送 → SSE
    • 双向交互 → WebSocket
    • 兼容旧浏览器 → 长轮询 + SSE Polyfill
  2. 性能优化

    • 减少轮询频率,优先用 SSE/WebSocket
    • WebSocket 消息压缩(如 permessage-deflate
  3. 面试加分项

    • 了解协议细节(如 SSE 的 idevent 字段)
    • 掌握调试工具(如 Chrome 的 Network → WS 面板)
    • 熟悉主流库(Socket.IORxJS 流处理)

通过理解技术原理与业务场景的匹配关系,能在面试中清晰阐述选型逻辑,并展示解决复杂问题的能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GISer_Jinger

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值