Send & Receive messages
ZEGOCLOUD's In-app Chat (the ZIM SDK) provides the capability of message management, allowing you to send and receive one-to-one, group, in-room messages, query message history, delete messages, and more. With the message management feature, you can meet different requirements of various scenarios such as social entertainment, online shopping, online education, interactive live streaming, and more.
This document describes how to send and receive messages with the ZIM SDK.
Message types
Currently, the ZIM SDK supports the following message types:
Message type | Description | Details |
---|---|---|
ZIMTextMessage(1) | Text message. Size limit: 32 KB. Rate limit: 10 requests/second. | Enable messages to be more deliverable, and can be stored as message history. Suitable for one-on-one chat and group chat. |
ZIMCommandMessage(2) | Customizable signaling message. Size limit: 5 KB. Rate limit: 10 requests/second. | Supports massive concurrency. Suitable for live audio room, online classroom, the messages won't be stored after the room is destroyed. |
ZIMBarrageMessage(20) | In-room barrage message (bullet) screen message). Size limit: 5 KB. No specific rate limit. | The high-frequency messages that don't require 100% deliverability, this message type is often used to send bullet screen messages. Supports massive concurrency, but the message deliverability can't be guaranteed. |
ZIMImageMessage(11) | Image message. Supports major image formats, including JPG, PNG, BMP, TIFF, and GIF. Size limit: 10 MB. Rate limit: 10 requests/second. | Enable messages to be more deliverable, and can be stored as history messages. Suitable for one-on-one chat, room chat, and group chat. |
ZIMFileMessage(12) | File message. Supports files in any format. Size limit: 100 MB. Rate limit: 10 requests/second. | |
ZIMAudioMessage(13) | Voice message. Supports voice messages in MP3 format within 300 seconds. Size limit: 6 MB. Rate limit: 10 requests/second. | |
ZIMVideoMessage(14) | Video message. Supports video messages in MP4 or MOV format. Size limit: 100 MB. Rate limit: 10 requests/second. |
Send/Receive regular messages
Regular messages refer to the messages of the following message types: ZIMTextMessage, and ZIMBarrageMessage.
- To receive event callbacks (receive in-room messages, get the connection status, token expiration, etc.), you can set up the ZIMEventHandler method and implement a
Function
object that contains related event callbacks. - When receiving messages, you need to determine whether the message is a Text message (ZIMTextMessage) or a Command message (ZIMCommandMessage) because these two message types are based on the basic message class (ZIMMessage). You need to convert the basic message class to a concrete message type and then retrieve the message content from the
message
field. - When a message is received, it can be sorted using the message's
orderKey
. The larger theorderKey
, the newer the message. And the number of unread messages will be updated automatically upon receiving.
Send messages
The following process shows how Client A sends one-to-one messages to Client B:
- Client A and Client B create their own ZIM SDK instances, and set up an event handler ZIMEventHandler to listen for related events (receive one-to-one messages, get connection status, and receive the notification when Token is about to expire).
- Client A and Client B log in to the ZIM SDK.
- Client A calls the sendMessage method to send a one-to-one message to Client B.
- Client B receives a notification through the onReceivePeerMessage when receiving Client A's one-to-one messages.
You can't send messages to yourself by calling the sendMessage
method (when toConversationID = your ID). If you did so, the error code 6000001 will return.
Sample code
// 1. Create a ZIM SDK object with the AppID and AppSign you get.
ZIMAppConfig appConfig = ZIMAppConfig();
appConfig.appID = appID;
appConfig.appSign = appSign;
ZIM.create(appConfig);
// 2. Log in
await ZIM
.getInstance()
!.login(userInfo, "token")
.then((value) {
// This will be triggered when operation successful.
})
.catchError((onError) {
switch (onError.runtimeType) {
// This will be triggered when operation failed.
case PlatformException:
log(onError.code); // Retuned error code for failed login.
log(onError.message!);// Returned error info for failed login.
break;
default:
}
});
// 3. Send messages.
ZIMTextMessage textMessage = ZIMTextMessage(message: "message");
ZIMMessageSendConfig sendConfig = ZIMMessageSendConfig();
// Set the message priority.
sendConfig.priority = ZIMMessagePriority.low;
ZIMPushConfig pushConfig = ZIMPushConfig();
pushConfig.title = "Offline notification title";
pushConfig.content = "Offline notification content";
pushConfig.extendedData = "Extension info of the offline notification";
sendConfig.pushConfig = pushConfig;
ZIMMessageSendNotification notification = ZIMMessageSendNotification(onMessageAttached: (message){
// The callback on the message not sent yet. Before the message is sent, you can get a temporary ZIMMessage message for you to implement your business logic as needed.
});
// 4. Set conversation type. Set it based on your conversation type.
// Send one-on-one messages.
ZIMConversationType type = ZIMConversationType.peer;
// Send group messages.
ZIMConversationType type = ZIMConversationType.room;
// Send in-room messages.
ZIMConversationType type = ZIMConversationType.group;
ZIM.getInstance()!.sendMessage(textMessage, toConversationID, type, sendConfig).then((value) {
// You can listen for this callback for the message sending results.
}).catchError((onError){
// You can use this to error info of the message sending failure.
});
Receive messages
- To send messages, call the sendMessage method and set the
ZIMConversationType
accordingly. - To receive messages:
- One-on-one messages (Peer type), through the callback onReceivePeerMessage.
- In-room messages (Room type), through the callback onReceiveRoomMessage.
- Group messages (Group type), through the callback onReceiveGroupMessage.
Sample code
ZIMEventHandler.onReceivePeerMessage = (zim, messageList, fromUserID) {
// This will be triggered when one-to-one messages received.
};
ZIMEventHandler.onReceiveGroupMessage = (zim, messageList, fromGroupID) {
// This will be triggered when group messages received.
};
ZIMEventHandler.onReceiveRoomMessage = (zim, messageList, fromGroupID) {
// This will be triggered when in-room messages received.
};
Send/Receive rich media content
The ZIM SDK now supports sending and receiving messages of different rich media types, such as images, audio, video, and files. To send and receive rich media content, refer to the following:
- To send rich media content after login, you will need to specify the message type (image, file, audio, video) first and then the conversation type (one-on-one chat, room chat, group chat).
- For a receiver to receive and download the rich media content, set up and listen for related event callbacks based on the conversation type (one-on-one chat, room chat, group chat) after logging in.
Send rich media content
To send rich media content after login, call the sendMediaMessage method, and specify the message type (image, file, audio, video), the conversation type (one-on-one chat, room chat, group chat), and message related configurations as needed.
- When sending rich media content, the file path to be sent must be in
UTF-8
encoding format. - To send rich media content to a room/group, the sender must be in the room/group.
To know the results of the rich media message sending operation, you can check the return value of the class ZIMMessageSentResult.
Sample code
// Send rich media content in one-on-one chat - Send images:
ZIMImageMessage imageMessage = ZIMImageMessage('xxx/xxx.jpeg');
ZIMMessageSendConfig sendConfig = ZIMMessageSendConfig();
ZIMMediaMessageSendNotification notification = ZIMMediaMessageSendNotification(onMessageAttached: (message){
// You can listen for this callback and
implement your event handling logic here before the message is sent.
},onMediaUploadingProgress: (message,currentFileSize,totalFileSize){
// You can listen for this callback to know the progress of the message sending.
});
ZIM.getInstance()!.sendMediaMessage(
imageMessage,
'toConversationID',
ZIMConversationType.peer,
sendConfig, notification).then((value) {
// This will be triggered when operation successful.
}).catchError((onError){
// This will be triggered when operation failed.
});
Callback for the sending progress of rich media content
You will be notified of the sending progress of rich media content through the callback ZIMMediaUploadingProgress.
Sample method call
typedef ZIMMediaUploadingProgress = void Function(
ZIMMessage message, int currentFileSize, int totalFileSize);
Among which:
- message: The content of the message being sent.
- currentFileSize: The size of the message that has been sent.
- totalFileSize: The overall size of the message sent.
Receive rich media content
To receive the rich media content messages, do the following:
- Listen for the following callbacks based on the conversation type (one-on-one chat, room chat, group chat): onReceivePeerMessage, onReceiveRoomMessage, onReceiveGroupMessage.
- Call the downloadMediaFile method to download the rich media content.
When downloading rich media content, you need to specify the file type of the corresponding media messages first.
- Image messages: You can choose to download the original file, large view, or thumbnail.
- Files/Audio messages: Only original files/audio files can be downloaded.
- Video messages: You can choose to download the original video file and the thumbnail of the first frame of the video.
Sample method call
To know the rich media downloading progress and receive its event notification, you can check the return value of the ZIMMediaDownloadedResult.
Sample code
// Receive rich media content in one-on-one chat - Receive images:
ZIMEventHandler.onReceivePeerMessage = (zim, messageList, fromUserID) {
// This will be triggered when one-to-one messages received.
for (ZIMMessage message in messageList) {
// You can tell by the Type which kind of message you are receiving.
switch (message.type) {
case ZIMMessageType.image:
message as ZIMImageMessage;
break;
case ZIMMessageType.video:
message as ZIMVideoMessage;
break;
case ZIMMessageType.audio:
message as ZIMAudioMessage;
break;
case ZIMMessageType.File:
message as ZIMFileMessage;
break;
default:
}
}
};
Callback for the downloading progress of rich media content
You will be notified of the downloading progress of rich media content through the callback ZIMMediaDownloadingProgress.
Sample method call
typedef ZIMMediaDownloadingProgress = void Function(
ZIMMessage message, int currentFileSize, int totalFileSize);
Among which:
- message: The message content you are downloading.
- currentFileSize: The size of messages that have been downloaded.
- totalFileSize: The overall size of the download message.
Send/Receive signaling messages
The ZIM SDK now supports you to send and receive signaling messages. To do that, you can call the ZIMCommandMessage to define the message type you want to send, for example, your location information.
This message type does not support offline push and local storage.
The following shows how to send custom messages to a specified user.
Send signaling messages
Sample code
// Send signaling message to a specified user
Uint8List cmdMessage = Uint8List.fromList([1, 2, 3]);
ZIMCommandMessage commandMessage = ZIMCommandMessage(message: cmdMessage);
ZIMMessageSendConfig sendConfig = ZIMMessageSendConfig();
ZIM.getInstance()!.sendMessage(cmdMsg, 'toUserID', ZIMConversationType.peer, sendConfig)
.then((value) => {
// Triggered when successful
})
.catchError((onError) {
// Triggered when failed
});
Receive signaling messages
Sample code
// User receives signaling message
ZIMEventHandler.onReceivePeerMessage = (zim, messageList, fromUserID) {
// Triggered when receiving private chat messages
for (ZIMMessage message in messageList) {
switch (message.type) {
case ZIMMessageType.command:
message as ZIMCommandMessage;
break;
default:
}
}
};
Send/Receive custom messages
The ZIM SDK supports developers to send and receive customized messages. Developers can define their own message types using the ZIMCustomMessage object, such as voting types, chain types, video card types, etc. Developers can follow the steps below to implement the sending and receiving of custom messages.
- Only ZIM SDK version 2.8.0 and above supports sending custom type messages and receiving and viewing the content of custom type messages.
- If the SDK version of the receiving end is between [2.0.0, 2.8.0), you can receive custom messages, but the message type will be displayed as unknown and the message content cannot be obtained. To obtain this message, please upgrade the SDK to version 2.8.0 or above.
- If the SDK version of the receiving end is version 1.x.x, custom messages cannot be received, and unknown messages will not be received either.
Send custom messages
Developers need to define custom type messages using the ZIMCustomMessage object, including the following parameters:
Then, pass the message to sendMessage to send the custom message.
Sample code
The following is an example code for sending custom messages in a one-on-one chat conversation:
// Send custom messages to a specific user in a one-on-one chat conversation
// 1. Create a ZIM object and pass in the appID and appSign
// Please refer to the relevant code in the previous section [Send/Receive Normal Messages - Send Messages] for the specific code.
// 2. Set the setEventHandler callback
// Please refer to the relevant code in the previous section [Send/Receive Normal Messages - Send Messages] for the specific code.
// 3. Log in
// Please refer to the relevant code in the previous section [Send/Receive Normal Messages - Send Messages] for the specific code.
// 4. Send custom messages
// The ID of the specified user
String userID = "xxxx";
// The text content of the custom message
String message = "";
// The specific custom type
int subType = 100;
// The search field of the custom message
String searchedContent = "";
ZIMCustomMessage zimCustomMessage = ZIMCustomMessage(message, subType);
// Advanced property configuration for sending messages
ZIMMessageSendConfig config = ZIMMessageSendConfig();
// Set the message priority
config.priority = ZIMMessagePriority.low;
// Send one-on-one messages
ZIMConversationType type = ZIMConversationType.Peer;
// Send group messages
// ZIMConversationType type = ZIMConversationType.Group;
// Send room messages
// ZIMConversationType type = ZIMConversationType.Room;
ZIM.getInstance().sendMessage(zimCustomMessage, toConversationID, type, config,ZIMMessageSendNotification(onMessageAttached: (ZIMMessage message){
// Developers can use this callback to listen for whether the message is ready to be sent. Only messages that pass the local basic parameter check will trigger this callback, otherwise an error will be thrown through the onMessageSent callback.
})).then((value) {
// Successful callback
}).catchError((onError){
// Handle failure
});
Receive custom messages
Sample code
The following is an example code for receiving custom messages in a one-on-one chat conversation:
// Receive custom messages in a one-on-one chat conversation
ZIMEventHandler.onReceivePeerMessage = (
ZIM zim, List<ZIMMessage> messageList, String fromUserID){
for (ZIMMessage message in messageList){
if(message is ZIMCustomMessage){
}
}
};
Listen for the message status
On a weak network condition, this may happen: the ZIM SDK doesn't receive the response from the server for some reason (e.g., packet loss), while the message is successfully sent. In this case, the ZIM SDK considers the message sending failed due to the reply timeout, but the message is actually sent successfully, which results in message status confusion. To solve this and Clarify the message status, the SDK 2.6.0 or later now allows you to listen for the onMessageSentStatusChanged callback to receive the changes of the message status. And we now have three different message statuses: Sending, Success, and Failed. You can know whether your message is sent successfully by the status, and implement your event handling logic as needed.
// Listen for the message status.
ZIMEventHandler.onMessageSentStatusChanged = (
ZIM zim, List<ZIMMessageSentStatusChangeInfo> messageSentStatusChangedInfoList){
for(ZIMMessageSentStatusChangeInfo info in messageSentStatusChangedInfoList){
log(info.status.toString());
log(info.message!.messageID.toString());
}
};