In-app Chat
  • iOS
  • Android
  • Web
  • Flutter : Dart
  • React Native
  • Unity3D
  • Windows
  • macOS
  • Introduction
    • Overview
    • Basic concepts
  • Sample app
  • Getting started
  • Client SDKs
    • SDK downloads
    • Release notes
    • Upgrade guide
  • Guides
    • Authentication
    • Manage users
    • Room
    • Group
    • Messaging
    • Call invitation (signaling)
    • Manage sessions
  • Offline push notifications
  • Error codes
  • Client APIs
  • Server APIs
  • Documentation
  • In-app Chat
  • Getting started

Send and receive messages

Last updated:2023-01-17 17:39

This document describes how to use the ZIM SDK (In-app Chat) to send and receive messages.


Solution

The following shows the access solution that the ZIM SDK provides.

/Pics/InappChat/im_solution_en.png

In this solution, you will need to implement the following business logic based on your actual business requirements:

  • The logic for managing the users on the client, and the logic for distributing user ID for users to log in.

Prerequisites

Before you begin, make sure:

  • Go to ZEGOCLOUD Admin Console, and do the following:
    • Create a project, get the AppID and AppSign.
    • Activate the In-app Chat service (as shown in the following figure).
      /Pics/InappChat/ActivateZIMinConsole2.png
  • Flutter 2.5.0 or later. For details, see Flutter - Get started.
  • iOS 9.0 or later
  • Android 4.1 or later and supports JDK 1.6 or later.
  • An iOS device or Android device that is connected to the internet.

Integrate the SDK

Optional: Create a project

Skip this step if a project already exists.

Create a new project

To create a new project, refer to the Flutter Doc - Get started.

Import the SDK

  1. Open the pubspec.yaml file, add the zego_zim dependencies as follows:
```yaml
dependencies:
    zego_zim: ^2.6.0
```
  1. After adding and saving the file, run the command flutter pub get in the terminal.

  2. If you are configuring a Web platform, then you will need to in your index.html file, add the following to import the Web SDK.

    <script src="assets/packages/zego_zim/assets/index.js" type="application/javascript"></script>

Set permissions

  • For iOS, Web: no special permissions need to be set.

  • For Android: Go to the app/src/main directory, in the AndroidManifest.xml file, add the permissions.

    <!-- The permissions required by SDK-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Prevent code obfuscation

When building your Android app with Flutter, to prevent obfuscation of the SDK public class names, in your project's proguard-rules.pro file, add the following:

-keep class **.zego.**{*;}

Implementation steps

Import the header file

Import the header file zego_zim.dart.

import 'package:zego_zim/zego_zim.dart';

Create a ZIM SDK instance

Creating a ZIM instance is the very first step, an instance corresponds to a user logging in to the system as a client.

So, let's suppose we have two clients now, client A and client B. To send and receive messages to each other, both of them will need to call the create method with the AppID and AppSign (for Web, AppSign is not required) you get in the previous Prerequisites steps to create a ZIM SDK instance of their own:

// Create a ZIM SDK instance.
//Create a ZIM SDK instance and pass in the AppID and AppSign.
ZIMAppConfig appConfig = ZIMAppConfig();
appConfig.appID = appID;
appConfig.appSign = appSign;

ZIM.create(appConfig);

Before a client user's login, you will need to call the ZIMEventHandler method to implement a static Function object that contains various event callbacks of the ZIMEventHandler. And you can receive callback notifications when SDK errors occur or receive message with the Function passed in.

implement the methods involved in the protocol to receive callbacks (you can customize the event callbacks, such as you can receive callback notifications when SDK errors occur or receive message-related callback notifications).

The following is the sample code for changing the connection status changes in the zim_event_handler_manager.dart file:

/Pics/ZIM/flutter/1.png

// The callback for receiving error codes. This callback will be triggered when SDK returns error codes. 
static void Function(ZIMError errorInfo)? onError;

// The callback for Token expires. This callback will be triggered when the Token is about to expire, and you can customize a UI for this event.  
static void Function(int second)? onTokenWillExpire;

// The callback for connection status changes. This callback will be triggered when the connection status changes, and you can customize a UI for this event.
static void Function(ZIMConnectionState state, ZIMConnectionEvent event, Map extendedData)? onConnectionStateChanged;

// The callback for receiving one-on-one messages. You can receive message notifications through this callback after login. 
static void Function(List<ZIMMessage> messageList, String fromUserID)? onReceivePeerMessage;

// The callback for receiving the in-room massages. You can receive in-room message notifications through this callback after login and joining a room.  
static void Function(List<ZIMMessage> messageList, String fromRoomID)? onReceiveRoomMessage;

// The callback for a new user joins the room. You can receive notifications when a new user joins the room through this callback after logging in and joining a room.
static void Function(List<ZIMUserInfo> memberList, String roomID)? onRoomMemberJoined;

// The callback for an existing user leaves the room. You can receive notifications when an existing user leaves the room through this callback after login and joining a room.
static void Function(List<ZIMUserInfo> memberList, String roomID)? onRoomMemberLeft;

For more detailed description for methods, refer to the onTokenWillExpire, onConnectionStateChanged, onReceivePeerMessage, onReceiveRoomMessage, onRoomMemberJoined, onRoomMemberLeft.

Log in to the ZIM SDK

For client A and client B to send and receive messages after creating the ZIM SDK instance, they will need to log in to the ZIM SDK.

To log in, Clients A and B both need to do the following:

  1. Call the ZIMUserInfo method to create a user object.
  2. Then, call the login method with their own user information .
  • You can custom the userID and userName, and we recommend you set these two to a meaningful value and associate them with the account system of your application.

First, create a ZIMUserInfo object with your user information. Then, client A and client B can call the login to log in to the ZIM SDK.

// userID must be within 32 bytes, and can only contain letters, numbers, and the following special characters: '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=', '-', '`', ';', '’', ',', '.', '<', '>', '/', '\'.
// userName must be within 64 bytes, no special characters limited.
ZIMUserInfo userInfo = ZIMUserInfo();
userInfo.userID = "userID"; //Fill in a String type value. 
userInfo.userName = "userName";//Fill in a String type value. 

ZIM
  .getInstance()
  .login(userInfo)
  .then((value) {
      //This will be triggered when login successful.
  })
  .catchError((onError) {
      switch (onError.runtimeType) {
          //This will be triggered when login failed.
          case PlatformException:
            log(onError.code); //Return the error code when login failed. 
            log(onError.message!);// Return the error indo when login failed.
            break;
          default:
      }
  });

Send messages

Client A can send messages to client B after logging in successfully.

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.

To send one-to-one messages, for example, if client A wants to send a message to client B, then client A needs to call the sendMessage method with client B's userID, message content, and the message type ZIMConversationType. And client A can be notified whether the message is delivered successfully through the callback ZIMMessageSentResult.

  • onMessageAttached callback: 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. For example, you can get the ID of the message before sending it. Or when sending a message with large content, such as a video, you can get the localMessageID of the message before the message is uploaded to implement a Loading UI effect.
// The following shows how to send one-to-one message, the [conversationType] needs to be set to ZIMConversationType.peer.
ZIMTextMessage textMessage = ZIMTextMessage(message: "message");
ZIMMessageSendConfig sendConfig = ZIMMessageSendConfig();
// Set priority for the message
sendConfig.priority = ZIMMessagePriority.low;

ZIMPushConfig pushConfig = ZIMPushConfig();
pushConfig.title = "Title of the offline push";
pushConfig.content = "Content of the offline push";
pushConfig.extendedData = "Extended info of the offline push";
sendConfig.pushConfig = pushConfig;
ZIMMessageSendNotification notification = ZIMMessageSendNotification(onMessageAttached: (message){
    //  The callback on the message not sent yet. You can get a temporary object here and this object must be the same as that created zimMessage object. You can make your own business logic using this as needed, for example, display a UI ahead of time.
});

// Set message type.
ZIMConversationType type = ZIMConversationType.peer;

ZIM.getInstance()!.sendMessage(textMessage, toConversationID, type, sendConfig).then((value) => {
    // The callback on the results of message sending.
}).catchError((onError){
    // This callback can be used to catch the reason for message sending failure.
});

Receive messages

After client B logs in, he will receive client A's message through the callback onReceivePeerMessage which is already set in the ZIMEventHandler method.

When a message is received, you need to determine whether the message is a Text message or a Command message because these two message types are based on the basic message. You need to convert the basic message class to a concrete message type and then retrieve the message content from the Message field.

ZIMEventHandler.onReceivePeerMessage = (messageList, fromUserID) {
    //Receives the messageList from fromUserID.
    //This callback will be triggered when receiving one-to-one messgaes.
    for (ZIMMessage message in messageList) {
        switch (message.type) {
            case ZIMMessageType.text:
                message as ZIMTextMessage;
                break;
            case ZIMMessageType.command:
                message as ZIMCommandMessage;
                break;
            case ZIMMessageType.image:
                message as ZIMImageMessage;
                break;
            case ZIMMessageType.file:
                message as ZIMFileMessage;
                break;
            default:
        }
    }
};

Log out

For a client to log out, call the logout method.

ZIM.getInstance().logout();

Destroy the ZIM SDK instance

To destroy the ZIM SDK instance, call the destroy method.

ZIM.getInstance().destroy();
Page Directory