如何通过Quarkus API向指定平板发送带JSON数据的事件?
Quarkus API向多台平板推送事件的Webhook实现方案
1. 前置准备:平板信息表核心字段确认
假设你的数据库表已存储平板信息,需确保包含以下关键字段(若缺失可补充):
device_id:平板唯一标识(如设备序列号、UUID)webhook_url:平板暴露的事件接收端点(每台平板独立)api_key:可选,用于推送请求的身份校验status:可选,标记设备在线/离线状态,用于过滤推送目标
2. Quarkus端核心实现
2.1 定义事件数据模型
创建与平板端交互的JSON格式事件DTO:
public class DeviceEvent { private String eventId; private String deviceId; private String eventType; // 如"DATA_SYNC"、"ALERT_NOTICE" private Map<String, Object> payload; // 携带的业务数据 // 生成getter、setter及构造方法 }
2.2 平板信息查询服务
基于现有数据库实现设备信息查询逻辑(以Quarkus Panache为例):
@ApplicationScoped public class DeviceService { // Device实体对应数据库表 public Device getDeviceById(String deviceId) { return Device.findById(deviceId); } // 批量获取在线设备(若有status字段) public List<Device> getOnlineDevices() { return Device.list("status", "ONLINE"); } }
2.3 事件推送服务
使用Vertx异步HTTP客户端实现事件推送,避免阻塞事件循环:
@ApplicationScoped public class EventPushService { @Inject DeviceService deviceService; @Inject Vertx vertx; // 向单个平板推送事件 public CompletionStage<Void> pushToSingleDevice(String deviceId, DeviceEvent event) { Device device = deviceService.getDeviceById(deviceId); if (device == null || device.getWebhookUrl() == null) { return CompletableFuture.failedFuture(new IllegalArgumentException("无效设备或未配置Webhook地址")); } return vertx.createHttpClient() .postAbs(device.getWebhookUrl()) .putHeader("Content-Type", "application/json") .putHeader("X-Device-Api-Key", device.getApiKey()) // 身份校验 .sendBuffer(Buffer.buffer(JsonbBuilder.create().toJson(event))) .map(response -> { if (response.statusCode() != 200) { throw new RuntimeException("推送失败,设备返回状态码: " + response.statusCode()); } return null; }) .toCompletionStage(); } // 批量推送事件到多台平板 public CompletionStage<Void> pushToBatchDevices(List<String> deviceIds, DeviceEvent event) { List<CompletionStage<Void>> futures = deviceIds.stream() .map(id -> pushToSingleDevice(id, event)) .collect(Collectors.toList()); return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); } }
2.4 触发推送的API接口
暴露REST接口供内部系统或前端触发事件推送:
@Path("/events") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class EventResource { @Inject EventPushService eventPushService; @POST @Path("/single/{deviceId}") public CompletionStage<Response> pushToSingle(@PathParam("deviceId") String deviceId, DeviceEvent event) { return eventPushService.pushToSingleDevice(deviceId, event) .thenApply(v -> Response.ok().build()) .exceptionally(e -> Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("推送失败: " + e.getMessage()) .build()); } @POST @Path("/batch") public CompletionStage<Response> pushToBatch(@QueryParam("deviceIds") List<String> deviceIds, DeviceEvent event) { return eventPushService.pushToBatchDevices(deviceIds, event) .thenApply(v -> Response.ok().build()) .exceptionally(e -> Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("批量推送失败: " + e.getMessage()) .build()); } }
3. 平板端事件接收实现
平板需暴露HTTP接口接收事件,以Android端Ktor实现为例:
fun startWebhookServer() { embeddedServer(Netty, port = 8080) { routing { post("/device/webhook") { val event = call.receive<DeviceEvent>() // 业务处理:更新UI、本地存储数据等 println("收到事件[${event.eventType}]: ${event.payload}") call.respond(HttpStatusCode.OK) } } }.start(wait = false) } // 对应数据类 data class DeviceEvent( val eventId: String, val deviceId: String, val eventType: String, val payload: Map<String, Any> )
4. 关键优化点
- 身份校验:平板端需校验请求头中的
X-Device-Api-Key,拒绝非法请求 - 可靠性保障:添加重试机制(可使用Quarkus
@Retry注解),对未送达事件持久化后重试 - 离线处理:配合设备心跳机制检测在线状态,离线设备的事件暂存数据库,待上线后补发
- 异步非阻塞:全程使用Vertx异步客户端,避免阻塞Quarkus事件循环,提升并发能力
内容的提问来源于stack exchange,提问作者Alexis
相关产品推荐
相关产品推荐

