Skip to main content

Streaming messages

This guide covers how to receive and fetch streaming messages in the Flutter Chat SDK, including message listeners, fetch flow, event callbacks, and summary retrieval.

Overview

Streaming messages are triggered by your app server. The Nexconn server delivers data fragments to the client through multiple pushes. The client first receives a StreamMessage via onMessageReceived, then calls requestStreamMessageContent to fetch the full content. The streaming event listener delivers events in the order init > data > complete.

caution

The Flutter SDK only receives and fetches streaming messages. It does not provide an API to send streaming messages.

The following diagram shows the complete interaction flow:

StreamMessage extends Message. Key fields:

FieldTypeDescription
contentString?Streaming content fragment from the first packet
typeString?Server-defined text format description, e.g., text/plain
completebool?Whether generation is finished
syncbool?Whether the client has completed a full fetch. If false, call requestStreamMessageContent.
completeReasonint?Business-defined completion reason code
stopReasonint?Server-defined stop reason. 0 means normal completion.

Receive streaming messages

The SDK does not support sending streaming messages — they must be triggered by the server. When a streaming message arrives, the onMessageReceived callback fires. Register a MessageHandler and check the message type and sync field:

Dart
NCEngine.addMessageHandler('stream-handler', MessageHandler(
onMessageReceived: (event) {
final message = event.message;
if (message is StreamMessage) {
if (message.sync == false) {
print('Received streaming message ${message.messageId}, needs fetch');
} else {
print('Streaming message already synced');
}
}
},
onMessageMetadataUpdated: (event) {
final message = event.message;
if (message is StreamMessage) {
final summary = event.metadata?['RC_Ext_StreamMsgSummary'];
if (summary != null) {
print('Streaming summary: $summary');
}
}
},
));

Fetch streaming message content

When sync == false, the streaming content has not been fully fetched. Call requestStreamMessageContent on the StreamMessage instance to start fetching. Stream data is delivered through MessageHandler callbacks in the order initdatacomplete.

Register the streaming event handlers before calling requestStreamMessageContent:

Dart
NCEngine.addMessageHandler('stream-events', MessageHandler(
onStreamMessageRequestInit: (event) {
print('Stream initialized: ${event.messageId}');
},
onStreamMessageRequestDelta: (event) {
print('Received chunk: ${event.chunkInfo?.content}');
},
onStreamMessageRequestComplete: (event) {
print('Stream complete: ${event.messageId}, error: ${event.error}');
},
));

Then call requestStreamMessageContent on the received StreamMessage:

Dart
if (message is StreamMessage && message.sync == false) {
await message.requestStreamMessageContent((error) {
if (error == null) {
print('Fetch started — streaming events incoming');
}
});
}

Get the streaming message summary

After the server completes content generation, it writes a summary through metadata. The default key is RC_Ext_StreamMsgSummary. Listen for metadata updates in the MessageHandler or read the metadata property on the message:

Dart
// Already handled in the MessageHandler above (onMessageMetadataUpdated)

// For historical messages:
if (message is StreamMessage && message.complete == true) {
final summary = message.metadata?['RC_Ext_StreamMsgSummary'];
print('Historical streaming summary: $summary');
}