基于增强QUIC协议优化弱网下的直播观看体验

如今,直播已成为电商、教育、娱乐等各领域信息传递与线上消费的重要载体,而网络质量则是决定直播体验的核心命脉。然而,当用户一旦置身于地铁、户外等弱网环境中,画面卡顿、画质模糊、音画错位等问题便接踵而至,原本精彩的直播瞬间变得支离破碎,用户观看体验随之直线下降。

基于此,HarmonyOS SDK远场通信服务(Remote Communication Kit)提供了QUIC长连接能力,能够在即时通讯、实时推送、在线直播等场景中,显著提升通信效率,即使在弱网环境下,也能保障直播画面无卡顿、无时延,有效提高用户使用体验。

实现原理

当应用冷启动时,传统网络请求需要经历域名解析、TCP连接建立、TLS握手等连接过程,在一次完整的请求中,连接阶段的操作会消耗大量时间,从而影响用户首屏加载体验。而QUIC长连接基于QUIC(Quick UDP Internet Connections)协议实现,相比传统的TCP协议,QUIC在速度、灵活性和稳定性方面更具备核心优势。

我们以应用接收长连接服务端消息推送场景为例来进行说明。在服务端主动推送消息的场景下,QUIC长连接通过无队头阻塞的多路复用及更少的握手次数,有效优化传统HTTP/1.1及HTTP/2协议中的队头阻塞与多次握手问题,降低网络延迟和资源消耗。此外,QUIC长连接能够保持连接的持久性,减少连接建立和断开频率,进一步提升通信效率。

能力优势

● 抗弱网算法

采用智能丢包重传与动态抖动缓冲技术,显著提升抗网络丢包和抖动能力,在30%丢包率下仍保障音视频清晰流畅。

● 物理链路无感切换

支持Wi-Fi与蜂窝网络间无缝迁移,连接自动保持无需重建,用户无感知,通话或直播不中断,体验稳定可靠。

● 多路复用

单连接内并行传输多路数据流,彻底消除队头阻塞,降低传输延迟,提升带宽利用率与并发性能,尤其适配实时通信场景。

接收长连接服务端消息推送的开发实现步骤

  1. 在.cpp文件导入模块。

    #include "RemoteCommunicationKit/rcp_quic.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

  2. 在CMakeLists.txt文件中添加以下lib依赖包。

    librcp_quic.so

  3. 自定义全局变量,可用于QUIC连接与流配置。

    uint64_t g_StreamId = 0;
    uint64_t userData = 0;
    char *alpn = "h3";
    const char *serverName = "www.example.com"; // 示例代码,仅用于展示调用,实际运行请替换为真实的QUIC协议服务端地址
    uint64_t serverPort = 443; // 示例代码,仅用于展示调用,实际运行请替换为真实端口

  4. 自定义回调方法,用于后续步骤注册监听事件,可在回调中补充需要的业务逻辑。

    // 连接成功时触发
    void OnConnectedImpl(Rcp_QuicConn *conn, void *userObject) {
    (void)conn;
    if (userObject == NULL) {
    return;
    }
    }

    // 异常发生时触发
    void OnErrorImpl(Rcp_QuicConn *conn, void *userObject, Rcp_QuicErrorCode errCode, const char *errDetail) {
    (void)conn;
    if (errCode == 0 || userObject == NULL || errDetail == NULL) {
    return;
    }
    }

    // 连接关闭时触发
    void OnClosedImpl(Rcp_QuicConn *conn, void *userObject) {
    (void)conn;
    if (userObject == NULL) {
    return;
    }
    }

    // 接收到对端传输数据时触发,需要返回接收到的数据大小
    void OnReceiveDataImpl(Rcp_QuicConn *conn, void *userObject, uint64_t streamId,
    const Rcp_QuicStreamData *streamData) {
    (void)conn;
    (void)streamId;
    (void)userObject;
    uint64_t totalBytes = 0;
    for (uint32_t i = 0; i < streamData->iovLen; i++) {
    totalBytes += streamData->iov[i].length;
    }
    return totalBytes;
    }

    // 接收到流事件时触发
    void onQuicStreamEventImpl(Rcp_QuicConn *conn, void *userObject, uint64_t streamId, Rcp_QuicErrorCode errCode,
    const char *errDetail) {
    (void)conn;
    (void)userObject;
    (void)streamId;
    (void)errCode;
    (void)errDetail;
    }

    // 接收到对端创建流时触发
    void OnStreamInboundImpl(Rcp_QuicConn *conn, void *userObject, uint64_t streamId) {
    (void)conn;
    (void)userObject;
    g_StreamId = streamId;
    }

  5. 初始化QUIC配置项。

    // 创建QUIC会话对象,用于管理全局资源
    Rcp_QuicSession *session = HMS_Rcp_QuicCreateSession();
    // 创建QUIC连接对象,需要指定ALPN协议和用户对象
    Rcp_QuicConn *conn = HMS_Rcp_QuicConnCreate(alpn, &userData);
    // 设置连接建立成功时的回调
    HMS_Rcp_QuicConnSetOpt(conn, RCP_QUIC_CONN_ON_CONNECTED_FUNCTION, &OnConnectedImpl, 0);
    // 设置发生错误时的回调
    HMS_Rcp_QuicConnSetOpt(conn, RCP_QUIC_CONN_ON_ERROR_FUNCTION, &OnErrorImpl, 0);
    // 设置连接关闭时的回调
    HMS_Rcp_QuicConnSetOpt(conn, RCP_QUIC_CONN_ON_CLOSED_FUNCTION, &OnClosedImpl, 0);
    // 设置服务端创建流时的回调
    HMS_Rcp_QuicConnSetOpt(conn, RCP_QUIC_CONN_STREAM_INBOUND_FUNCTION, &OnStreamInboundImpl, 0);

  6. 与服务端进行连接。

    HMS_Rcp_QuicConnConnect(session, conn, serverName, serverPort);

  7. 服务端主动创建流,客户端接收到OnStreamInboundImpl回调后,为返回的对端流streamId设置监听事件。

    HMS_Rcp_QuicStreamSetOpt(conn, g_StreamId, RCP_QUIC_STREAM_EVENT_FUNCTION, &onQuicStreamEventImpl, 0);
    HMS_Rcp_QuicStreamSetOpt(conn, g_StreamId, RCP_QUIC_STREAM_DATA_FUNCTION, &OnReceiveDataImpl, 0);

  8. 业务完成后,关闭连接并释放资源。

    // 关闭流
    uint64_t appErr = 0; // 自定义业务状态码,服务端在流关闭时可以接收到此状态码用于对关闭原因进行判断
    HMS_Rcp_QuicConnStreamShutdown(conn, g_StreamId, RCP_QUIC_STREAM_SHUTDOWN_WRITE, appErr);
    HMS_Rcp_QuicConnStreamShutdown(conn, g_StreamId, RCP_QUIC_STREAM_SHUTDOWN_READ, appErr);

    // 销毁连接对象,关闭所有流并释放连接资源
    if (conn != NULL) {
    HMS_Rcp_QuicConnDestroy(conn);
    }

    // 销毁会话对象,释放QUIC全局资源
    if (session != NULL) {
    HMS_Rcp_QuicDestroySession(session);
    }

了解更多详情>>

访问远场通信服务联盟官网

获取使用QUIC协议进行网络通信开发指导文档

相关推荐
安好说AI2 小时前
Flutter 三方库 adaptive_image_picker 的鸿蒙化适配指南:零权限选图、纯 Dart 裁剪与目标大小压缩
flutter·harmonyos
2501_919749034 小时前
华为鸿蒙免费PDF工具—小羊免费PDF
华为·pdf·harmonyos·鸿蒙
贾伟康5 小时前
【口算王|10】HarmonyOS ArkTS 语音报题实战:协调朗读、作答和页面生命周期
生命周期·harmonyos·arkts·语音交互·texttospeech
贾伟康7 小时前
【口算王|08】HarmonyOS ArkTS 分类训练实战:让年级与运算分类参数保持一致
harmonyos·arkts·数据建模·路由参数·分类训练
光锥智能7 小时前
华为新麒麟芯片、鸿蒙7问世,手机底层竞赛升级
华为·智能手机·harmonyos
贾伟康8 小时前
【口算王|09】HarmonyOS ArkTS 学习统计实战:计算连续训练和正确率趋势
harmonyos·arkts·数据可视化·preferences·学习统计
lqj_本人8 小时前
Flutter 鸿蒙实战:用 wakelock_plus 三方库给阅读页加上屏幕常亮
flutter·华为·harmonyos
aqi0019 小时前
鸿蒙版本的JSBridge兼容与安卓配套的H5啦
android·华为·harmonyos·鸿蒙·移动应用
熊猫钓鱼>_>19 小时前
Flutter app_settings 鸿蒙适配实战:Intent 体系到 Want 的跨越
flutter·华为·harmonyos·openharmony·intent·want