基于增强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与蜂窝网络间无缝迁移,连接自动保持无需重建,用户无感知,通话或直播不中断,体验稳定可靠。
● 多路复用
单连接内并行传输多路数据流,彻底消除队头阻塞,降低传输延迟,提升带宽利用率与并发性能,尤其适配实时通信场景。
接收长连接服务端消息推送的开发实现步骤
- 在.cpp文件导入模块。
#include "RemoteCommunicationKit/rcp_quic.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
- 在CMakeLists.txt文件中添加以下lib依赖包。
librcp_quic.so
- 自定义全局变量,可用于QUIC连接与流配置。
uint64_t g_StreamId = 0;
uint64_t userData = 0;
char *alpn = "h3";
const char *serverName = "www.example.com"; // 示例代码,仅用于展示调用,实际运行请替换为真实的QUIC协议服务端地址
uint64_t serverPort = 443; // 示例代码,仅用于展示调用,实际运行请替换为真实端口
- 自定义回调方法,用于后续步骤注册监听事件,可在回调中补充需要的业务逻辑。
// 连接成功时触发
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;
}
- 初始化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);
- 与服务端进行连接。
HMS_Rcp_QuicConnConnect(session, conn, serverName, serverPort);
- 服务端主动创建流,客户端接收到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);
- 业务完成后,关闭连接并释放资源。
// 关闭流
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);
}
了解更多详情>>
浙公网安备 33010602011771号