跳到主要内容

流式消息

本文介绍如何在 Flutter IMLib SDK 中接收并拉取流式消息,涵盖消息监听、拉取流程、事件回调与摘要获取等内容。

提示

此功能从 5.32.0 版本开始支持。

流式消息简介

流式消息由业务服务器触发,融云 IM 服务器会以多次推送的形式将数据片段下发到客户端。客户端首先通过 onMessageReceived 收到一条 RCIMIWStreamMessage,再调用 requestStreamMessageContent 拉取完整内容,并通过流式事件监听器按 init > data > complete 顺序获取生成过程。

警告

Flutter SDK 仅负责接收和拉取流式消息,不提供发送流式消息的接口。

下图展示了完整的交互流程:

RCIMIWStreamMessage 继承自 RCIMIWMessage,关键字段如下:

字段类型说明
contentString?首包携带的流式内容片段
typeString?服务器自定义的文本格式描述,例如 text/plain
completebool?是否已生成完毕
syncbool?客户端是否已完成完整拉取,false 时需主动调用 requestStreamMessageContent
completeReasonint?业务侧定义的结束原因码
stopReasonint?服务器定义的结束原因,0 代表正常结束
referMsgRCIMIWReferenceInfo?流式消息引用的原消息信息

接收流式消息

SDK 不支持发送流式消息,需要由服务器触发。当收到流式消息时,可在 onMessageReceived 回调中判断消息类型,并根据 sync 字段决定是否发起拉取:

Dart
engine?.onMessageReceived = (RCIMIWMessage? message, int? left, bool? offline, bool? hasPackage) {
if (message?.content is RCIMIWStreamMessage) {
final streamMsg = message!.content as RCIMIWStreamMessage;
if (streamMsg.sync == false) {
debugPrint('收到流式消息 ${message.messageUId},需要继续拉取');
} else {
debugPrint('流式消息已同步完成,无需重复拉取');
}
}
};

历史流式消息

SDK 接收到流式消息后,会存储到本地数据库。开发者在调用获取历史消息相关接口时,可以查询到流式消息。

拉取流式消息

监听拉取事件

在调用 requestStreamMessageContent 之前,先设置流式拉取事件监听,分别处理初始化、增量数据与完成事件:

Dart
engine?.onStreamMessageRequestInit = (String? messageUId) {
debugPrint('init => $messageUId');
};

engine?.onStreamMessageRequestData = (
RCIMIWMessage? message,
RCIMIWStreamMessageChunkInfo? chunkInfo,
) {
debugPrint('chunk => ${message?.messageUId}, data=${chunkInfo?.content}');
};

engine?.onStreamMessageRequestComplete = (String? messageUId, int? code) {
debugPrint('complete => $messageUId, code=$code');
};

事件说明

回调参数说明
onStreamMessageRequestInitmessageUId请求准备完成,若之前异常中止会清理旧数据
onStreamMessageRequestDatamessage, chunkInfo每次收到一个增量片段,chunkInfo.content 为片段内容
onStreamMessageRequestCompletemessageUId, code拉取结束,code 为完成原因,非 0 时可结合消息 completeReasonstopReason 排查异常

发起拉取

开发者在获取到流式消息后,可以通过 sync 参数判断流式消息是否已经同步完成。如果为 false,开发者可以按需拉取流式消息。

接口

Dart
requestStreamMessageContent(
RCIMIWStreamMessageRequestParams params,
{IRCIMIWOperationCallback? callback}
)

参数说明

参数类型说明
paramsRCIMIWStreamMessageRequestParams请求参数,仅需传入 messageUId
callbackIRCIMIWOperationCallback?表示请求是否成功发起,真正的数据通过事件监听返回

RCIMIWStreamMessageRequestParams 字段说明

字段类型说明
messageUIdString?目标流式消息的唯一 ID(必填)

示例代码

Dart
final params = RCIMIWStreamMessageRequestParams.create(messageUId: messageUId);

final IRCIMIWOperationCallback callback = IRCIMIWOperationCallback(
onSuccess: () => debugPrint('流式消息拉取请求已受理'),
onError: (int? code) => debugPrint('流式消息拉取失败: $code'),
);

await IMEngineManager().engine?.requestStreamMessageContent(params, callback: callback);
提示

IRCIMIWOperationCallback 仅表示请求是否成功进入服务端流程,真正的流式内容请使用事件监听(onStreamMessageRequest…)获取。

获取流式消息摘要

当服务器完成流式内容生成后,会通过消息扩展的方式写入摘要(默认 key:RC_Ext_StreamMsgSummary)。您可以使用消息扩展监听或直接读取消息体上的 expansion 获取摘要。

监听消息扩展更新

Dart
engine?.onRemoteMessageExpansionUpdated = (Map? expansion, RCIMIWMessage? message) {
if (message?.content is RCIMIWStreamMessage) {
final summary = expansion?['RC_Ext_StreamMsgSummary'];
if (summary != null) {
debugPrint('实时收到流式摘要: $summary');
}
}
};

读取历史摘要

消息扩展会存储在本地数据库,可结合 RCIMIWStreamMessage.complete 判断,直接从消息实体的 expansion map 中读取:

Dart
if (message.content is RCIMIWStreamMessage) {
final streamMsg = message.content as RCIMIWStreamMessage;
if (streamMsg.complete == true) {
final summary = message.expansion?['RC_Ext_StreamMsgSummary'];
debugPrint('历史流式摘要: $summary');
}
}