题干与适用场景
同一 WebTransport 会话需要同时发送实时预览、控制消息和大文件。预览希望低延迟,控制消息必须及时到达,大文件可以让出带宽。请使用 WebTransportSendGroup、sendOrder 和 getStats() 设计发送策略,并说明优先级边界、拥塞、重连、浏览器不支持和错误处理。
MDN 将 send group 描述为把多个流和数据报放在同一组内,并用 sendOrder 决定组内相对发送优先级;不同组之间的带宽分配由实现决定。该接口仍是实验性能力,本文基于公开资料整理,不声称是公司真题。
面试官考察点
面试官关注你是否区分“组内相对顺序”和“跨组公平性”,能否把业务优先级映射到可观测的发送队列,并说明数据报不可靠、流可靠有序的差异。强回答会提到 createSendGroup()、创建流时传入 sendGroup、sendOrder、组级 getStats()、拥塞控制和能力检测;普通回答只说“给重要消息加权”。
回答前需要澄清的问题
- 哪些数据可丢弃,哪些必须可靠、有序和持久化?
- 低延迟目标、文件吞吐目标和最大排队时长分别是多少?
- 优先级是会话级固定策略,还是由用户操作动态变化?
- 目标浏览器是否支持 send group,回退通道能否表达同样的业务语义?
30 秒回答框架
“我先把可靠控制消息、实时可丢弃预览和后台文件传输分成明确的业务流。需要比较顺序的流放入同一 send group,通过 sendOrder 让控制和预览先于文件;不要把它当成跨组带宽保证。发送端限制队列和单条大小,按 getStats() 监测排队与完成情况,拥塞时丢弃过期预览、暂停文件。能力不支持时回退到独立连接或应用层调度,并保持控制消息的可靠性。”
分步骤深入解答
先定义可靠性边界。控制、权限和最终确认使用可靠流;实时预览可使用数据报并允许丢弃;大文件使用可靠流但可以低优先级。一个 send group 只解决成员之间的相对发送顺序,不会把不同 group 变成可预测的权重队列,也不替业务完成重试。
创建 group 后,把发送流或可写数据报流关联到它,并给成员设置 sendOrder。数值关系必须在团队协议中写清楚,避免不同实现对“更大还是更小优先”产生误解。只有同组中参与严格排序的成员才比较 sendOrder;未设置顺序的成员顺序由实现决定。
const group = transport.createSendGroup();
const control = await transport.createUnidirectionalStream({
sendGroup: group,
sendOrder: 30,
});
const preview = transport.datagrams.createWritable({
sendGroup: group,
sendOrder: 20,
});
const archive = await transport.createUnidirectionalStream({
sendGroup: group,
sendOrder: 1,
});业务层仍要做预算:限制预览数据报大小和过期时间,合并同一对象的最新状态;文件分片要有取消、重试和断点记录。队列接近上限时,先丢弃过期预览,再暂停文件,不能丢弃控制消息。对关键消息使用确认和幂等键,不能因为发送顺序高就假设已经到达。
拥塞控制是传输层偏好,不是严格的业务 SLA。congestionControl 可表达偏好为低延迟或高吞吐,但实际效果取决于实现和网络。连接创建时选择偏好,运行中用应用指标判断是否应该减少预览频率或暂停后台任务,不能仅凭一个配置值宣称延迟有保证。
通过 group 的 getStats() 和成员级指标观察排队、发送、丢弃、重试和完成时延。把统计按组、消息类型、网络和会话版本记录,区分“尚未发送”“数据报丢失”和“接收端处理慢”。重连后重新建立 group、恢复可靠流状态,并从权威快照重建可丢弃预览,不复用失效的流对象。
能力检测要在建立会话前完成。send group 不可用时,核心控制流仍应能工作;可以退回单独的可靠连接或应用层队列。不要为了保留视觉预览而阻塞登录、权限或提交操作。实验性接口上线前应有浏览器分组、灰度开关和关闭路径。
高质量示范回答
我会把控制消息、实时预览和文件传输拆成不同发送成员,并根据可靠性选择流或数据报。需要比较顺序的成员进入同一 send group,控制设置最高 sendOrder,预览其次,文件最低;未设置顺序的成员不纳入严格比较。组内顺序只表达相对优先级,跨组公平性由实现决定,所以我不会把它当成带宽配额。
应用层维护消息预算、取消、幂等和过期策略:拥塞时合并或丢弃旧预览,暂停文件,控制消息保留可靠确认。congestionControl 只表达低延迟或高吞吐偏好,getStats() 用来观测排队和完成时延。重连后重新建组并从快照恢复,能力不支持时保留可靠控制路径,预览退化或关闭。最后按组和消息类型监控丢弃率、延迟和用户任务成功率。
常见错误
- 错误表现 → 把 sendOrder 当成跨组带宽权重;失败原因 → 规范只定义组内相对发送顺序;修正方法 → 在应用层做跨组调度并观测实际结果。
- 错误表现 → 用高优先级代替可靠确认;失败原因 → 发送顺序不保证到达;修正方法 → 关键消息使用可靠流、确认和幂等。
- 错误表现 → 拥塞时继续排队所有预览和文件;失败原因 → 延迟和内存都会失控;修正方法 → 设置预算、合并最新状态并暂停后台传输。
- 错误表现 → 重连后复用旧流对象;失败原因 → 流属于旧会话,状态可能已过期;修正方法 → 重建 group、恢复权威状态并重新订阅。
- 错误表现 → 把实验性 API 当作唯一通道;失败原因 → 浏览器差异会阻断核心操作;修正方法 → 能力检测、灰度和可靠回退。
追问及应对
组内和组间优先级有什么区别?
同一 send group 内,参与排序的流或数据报用 sendOrder 比较相对发送顺序;不同 group 之间预期被公平分配,但具体比例由实现决定。需要跨组权重时,应在应用层拆分连接或调度队列,并用指标验证。
为什么预览不能只用高 sendOrder 保护?
优先级只影响排队顺序,不改变数据报的不可靠语义,也不保证接收端及时处理。预览还需要过期时间、合并和丢弃策略;控制事实则要靠可靠传输、确认和持久化。
如何判断暂停文件是否有效?
记录文件队列长度、预览延迟、控制消息完成时延和用户任务成功率。若暂停后控制时延改善且预览仍达标,可继续;若网络恢复或业务优先级改变,再按预算恢复文件,避免无限饥饿。
不支持 send group 时怎样回退?
先保证可靠控制流和核心导航,再把预览退回单独数据通道、可靠流或关闭。应用层保留同一消息协议和取消规则,不能让回退路径丢失权限、提交和错误处理语义。