从“断流”到“长流”:A2A 协议如何用 SSE 与推送让 AI 任务永不下线

从“断流”到“长流”:A2A 协议如何用 SSE 与推送让 AI 任务永不下线

关键词:A2A 协议、Server-Sent Events、Push Notification、长任务、实时推送、Webhook、SSRF、JWT、微服务


开场 3 行说清楚

  • 还在用轮询看 AI 任务跑完没?又慢又费钱。
  • A2A 协议把「长任务」拆成两条路:
    1. SSE 流式——实时吐结果,像追番;
    2. 推送通知——离线也能收快递,像点外卖。
  • 今天一文带你配好这两条“高速公路”,附赠防 SSRF、JWT 旋转全套安全秘籍。

1. 场景速写:当你的 AI 任务需要“马拉松”

场景耗时体验痛点
生成长文档几分钟用户盯空白页,心态炸裂
视频摘要十几分钟移动端切后台,WebSocket 断
金融风控模型几小时函数计算 15 min 超时,直接被杀

A2A 协议给出的答案:

「让客户端决定是挂电话(推送)还是保持通话(SSE)。」


2. SSE:把“等结果”变成“边跑边看”

2.1 建立一条永不打烊的单向流

POST /rpc/message/stream HTTP/1.1
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": 101,
  "method": "message/stream",
  "params": {
    "prompt": "请给我 10 万字的《三体》同人小说",
    "stream": true
  }
}

服务器立刻回:

HTTP/1.1 200 OK
Content-Type: text/event-stream

event: message
data: {"jsonrpc":"2.0","id":101,"result":{"type":"TaskStatusUpdateEvent","state":"working","message":"正在思考黑暗森林法则..."}}

随后每生成一段就吐一段,直到:

{"type":"TaskStatusUpdateEvent","state":"completed","final":true}

客户端即可 close(),优雅结束。

2.2 断线自动续命

断网场景客户端动作Server 策略
地铁进隧道tasks/resubscribe可选重放丢失事件
浏览器刷新同上仅推送新事件

小贴士:在 Agent Card 里把 capabilities.streaming: true 亮出来,客户端就知道你能“追剧”。


3. Push Notification:让服务器做“外卖小哥”

3.1 配好地址与暗号

客户端在一次普通请求里夹带私货:

"pushNotification": {
  "url": "https://my-callback.example.com/a2a/webhook",
  "token": "task-xyz-42",
  "authentication": {
    "type": "Bearer",
    "tokenEndpoint": "https://auth.example.com/oauth2/token"
  }
}

服务器把任务状态变化 POST 到 url,附赠:

X-A2A-Notification-Token: task-xyz-42
Authorization: Bearer <JWT>

3.2 收到快递后,客户端再取货

  1. 服务端回调:任务已完成
  2. 客户端立即 GET /rpc/tasks/get?id=task-xyz-42 拉完整结果。
  3. 移动端可把这条消息再转成本地推送,用户甚至没打开 App。

4. 安全攻防:别让 Webhook 变成 SSRF 炮灰

4.1 服务端:别乱敲门

  • 域名白名单:只允许 .example.com.mycompany.cn
  • 挑战-应答:首次配置时 GET ?validationToken=uuid,必须回显 uuid
  • 出口防火墙:限制 A2A Server 只能访问 443 端口且目标域名经过解析校验

4.2 客户端:验明正身

校验维度实现示例
身份校验 JWT iss, aud,用 JWKS 动态拉公钥
时效拒绝 iat 超过 5 min 的旧通知
去重jti 写入 Redis SET,TTL 30 min
授权对比 X-A2A-Notification-Token 与本地任务 token

示例代码(Node.js):

const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');

const client = jwksClient({ jwksUri: 'https://a2a-server.example.com/.well-known/jwks.json' });
const cert = await client.getSigningKey(kid);
jwt.verify(token, cert.getPublicKey(), {
  issuer: 'a2a-server.example.com',
  audience:  'my-webhook.example.com',
  maxAge: '5m'
});

5. 场景选型速查表

场景推荐模式原因
Web 端实时聊天SSE双向流量小,延迟 <1 s
移动 App 视频摘要Push避免长连接费电
Serverless 批处理Push15 min 超时限制
企业内网长任务SSE + mTLS内网稳定,双向证书更可信

6. 5 分钟跑通 Demo

6.1 启动 A2A 兼容 Server(Python 示例)

pip install a2a-protocol[examples]
export A2A_WEBHOOK_ALLOWLIST="https://*.example.com"
a2a-server --streaming --push

6.2 客户端订阅 SSE

curl -N -H "Accept:text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"message/stream","params":{"prompt":"写首诗"}}' \
  http://localhost:8080/rpc/message/stream

6.3 再试推送

curl -X POST http://localhost:8080/rpc/message/send \
  -d '{"jsonrpc":"2.0","id":2,"method":"message/send","params":{"prompt":"写首诗","pushNotification":{"url":"https://webhook.site/unique-id"}}}'

7. 结语:让长任务像短视频一样顺滑

A2A 协议把「长任务」从同步阻塞的泥潭里捞出来:

  • 有网就 SSE,像追番;
  • 没网就推送,像外卖。
RTMP推流到SRS(Server-Sent Real-Time Messaging Protocol,简单流服务器)是一种常见的视频直播传输协议。当遇到断流情况时,可能会导致直播中断。以下是一些处理RTMP断流并实现重推的方法: 1. **网络连接稳定性检查**:在推流过程中,SRS会定期检查客户端的连接状态。如果检测到网络不稳定或者丢包严重,它可能会暂时断开连接,并设置一个重试机制。 2. **重试策略**:当连接被断开时,SRS通常会等待一段时间后自动尝试重新连接。这个时间可以根据设置进行调整,避免频繁的重试导致服务器压力过大。 3. **错误处理和通知**:推流端应该捕获和处理RTMP连接错误,如`400 Bad Request`或`408 Request Timeout`等。一旦发生错误,应用应该记录错误信息,并根据配置进行处理,比如发送通知给用户或系统管理员。 4. **流媒体编码缓存**:SRS支持将已编码的视频帧存储在缓存中,如果客户端断开连接,可以从缓存中读取并继续播放,直到缓存耗尽。 5. **流切片和断点续传**:为了提高用户体验,一些直播平台可能会使用分片技术,将直播流分成多个小的部分。断流时,可以从断点处恢复推流,而不是从头开始。 6. **自定义逻辑扩展**:如果你有更高级的需求,可以编写自定义的客户端或服务端插件,来实现更复杂的断流重推策略,比如使用心跳包保持连接,或者基于用户行为动态调整带宽。 相关问题-- 1. 如何设置SRS来自动重连断开的RTMP连接? 2. SRS的缓存机制如何帮助处理断流问题? 3. 在RTMP推流中,如何实现流切片和断点续传?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值