Implement messaging

Update time: 2023/01/18 09:20:05

Instant Messaging (IM) is a stable messaging service based on the communication technology provided by CommsEase. You can use IM to build robust chatting features for your apps. NetEase Instant Messaging (NIM) SDK for Flutter offers a full-fledged instant messaging framework using Flutter, encapsulates internal complexities, and provides easy-to-use APIs to facilitate quick integration with third-party applications. The SDK for Flutter supports Android and iOS.

This topic describes how to integrate the NIM SDK for Flutter and call APIs to implement messaging in your app.

Prerequisites

  • You have performed the following operations in the CommsEase console.

    Create a project and get the AppKey and App Secret of the project. 1. In the left-side navigation pane, find "Project" and click "New".

    2. Input the required information and click `Create`.

    3. After creating an app, you can view the project in the left navigation bar. You can click `AppKey Management`, and get the AppKey and App Secret.
    Register IM accounts and get accid and token for each account

    Register IM accounts and get accid and token for each account. The accid and token are used for log in to CommsEase server

    1. Click the specified application name in the left navigation pane to enter the details page of the application.

    2. Click `Account Management` in `Features`.

    3. On the test page, single Click "New Account", fill in the account (accid), nickname (name), password (Token), and click OK.
  • You have set up the following environment or tool:

  • Flutter-dart 2.12.0 or later.

  • Development environment for each platform:

    Android
    • Android Studio 3.5 or later
    • Android 4.4 API 19 or later
    • 1.5.21 or later for kotlin-gradle-plugin.
    iOS
    • Xcode 11.0 and later.
    • iOS 9.0 or later
    • Your project must have a valid signature.
    Windows (Beta)
    • Windows 7 SP1 or later (x86-64 based 64-bit OS).
    • Visual Studio 2019
    • CMake 3.10 or later
    macOS (Beta)
    • Xcode 11.0 and later.
    • macOS 10.14 or later.
    • Your project must have a valid signature.
    Web (Beta)
    • You have installed Visual Studio Code with the flutter plugininstalled.
    • Proficient in using Flutter commands.

Windows, macOS, and Web are currently still in beta and closed testing. Stay tuned.

Workflow

Process overview

You can implement messaging for P2P chats by performing the following 4 steps. The following diagram may display improperly due to network issues. To fix display issues, refresh the page.

uml diagram

Step 1 Integrate the SDK

Integrate the SDK for Android, iOS, Windows, or macOS

NIM SDK for Flutter has been published to the pub library. You can download, and update the newest SDK by configuring pubspec.yaml .

  1. Add the following dependencies to your project's pubspec.yaml file.
jsondependencies: 
nim_core: ^1.1.0 
  1. Download the dependency packages by running the following command in the Shell or IDE.

    flutter pub get
    
Integrate the SDK for Web
  1. Add the following dependencies to your project's pubspec.yaml file.

    dependencies: 
    nim_core: ^1.1.0 
    
  2. Run the following command to download dependencies using Shell or IDE:

    flutter pub get
    
  3. Create a web folder and create an index.html file in the web folder. The template of the index file is as follows:

    The link in the following template is the link of the front-end js resource package of the Flutter SDK for Web. You must replace the link for new upgrades. Contact technical support for the link of the latest version.


    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8" />
        <meta content="IE=Edge" http-equiv="X-UA-Compatible" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta
        name="description"
        content="Flutter web"
        />
        <title>You page title</title>
        <script>
        // The value below is injected by flutter build, do not touch.
        var serviceWorkerVersion = null;
        </script>
        <script src="flutter.js"></script>
    </head>
    <body>
        <script>
        <!-- The link below is the link of the front-end js resource package of the Flutter SDK for Web. You must replace the link for new upgrades. Contact technical support for the link of the latest version.
        var jsConfig = [
            "https://yx-web-nosdn.netease.im/package/1664415864168/index.0.0.6.umd.js",
        ];
    
        window.onload = function () {
            // Download main.dart.js
            try {
            _flutter.loader
                .loadEntrypoint({
                serviceWorker: {
                    serviceWorkerVersion: serviceWorkerVersion,
                },
                })
                .then(function (engineInitializer) {
                return engineInitializer.initializeEngine()
                }).then(appRunner => {
                require(jsConfig, (RootService) => {
                    window.$flutterWebGlobal = {
                    rootService: new RootService.default(),
                    }
                    appRunner.runApp();
                });
                })
            } catch (error) {
            console.log(error);
            }
        };
    
        async function dartCallNativeJs(callInfo = {}) {
            const { serviceName, method, params, successCallback, errorCallback } =
                callInfo;
            try {
            console.log('dartCallNativeJs: ', callInfo)
            const service = window.$flutterWebGlobal.rootService[serviceName];
            if (!service) {
                throw new Error(`You do not implement this service: ${serviceName}`);
            }
            if (!service[method]) {
                throw new Error(`This method: ${method} is not implemented on this service: ${serviceName}`);
            }
            // Delete serviceName from the parameter
            if (params.hasOwnProperty('serviceName')) {
                delete params.serviceName;
            }
            const res = await service[method](params);
            successCallback(res)
            } catch (error) {
            console.error('dartCallNativeJs failed: ', error)
            errorCallback(error)
            throw error
            }
        }
        </script>
    </body>
    </html>
    
  4. Test whether the SDK for Web is integrated by running the flutter run -d chrome command. If you can see the following page and Chrome console call log after running the command, the integration is successful.

    FlutterWeb集成成功.png

After integrating the SDK, you can configure **Compilation and obfuscation for Android apps (not required for other platforms). For more information, see Configure compilation and obfuscation.

Step 2 Initialize the SDK

Initialize the SDK by calling the initialize method.

Initialization must be implemented during the life cycle of your app and can only be performed once.

  • Parameters

    Parameter Type Description
    context Context App context
    options NIMSDKOptions</ a> Configuration information for initialization. Optional. Use the default configuration if unspecified.
  • Example

    dart
    final NIMSDKOptions options;
    if (Platform.isAndroid) {
    options = NIMAndroidSDKOptions(
        appKey: 'appkey',
        /// Other generic options
    );
    } else if (Platform.isIOS) {
    options = NIMIOSSDKOptions(
        appKey: 'appkey',
        /// Other generic or iOS configuration
    );
    } else if (KisWeb) {
        options = NIMSDKOptions(
        appKey: 'appKey',
        /// Other generic parameters    
        )
    }
    NimCore.instance.initialize(options)
        .then((result){
            if (result.isSuccess) {
                /// success
            } else {
                /// Initialization failure
            }
        });
    
    

Step 3: Log in to IM Server

Before implementing messaging, you need to establish a connection between the SDK and the IM server, and log in to the IM server. After you log in to the server, the SDK will automatically synchronize data, such as messages and system notifications. When the synchronization is complete, the login process ends.

  1. The sender and recipient register the listener for the login logic, including login status, data synchronization and multi-device login.

    Sample code:

    Register the listener for the login status
    dart
        /// Start listening to events
        final subscription = NimCore.instance.authService.authStatus.listen((event) {
        if (event is NIMKickOutByOtherClientEvent) {
            /// Listen to the kick event
        } else if (event is NIMAuthStatusEvent) {
            /// Listen to other events
        }
        });
    
        /// If you do not want to listen to the events, unregister the listener. Otherwise, it will cause a memory leak
        /// subscription.cancel();
    
    
    Register the listener for data synchronization
    dart
    /// Start listening to events
    final subscription = NimCore.instance.authService.authStatus.listen((event) {
    if (event is NIMDataSyncStatusEvent) {
        /// Listen to data synchronization events
        if (event.status == NIMAuthStatus.dataSyncStart) {
        /// Data sync starts
        } else if (event.status == NIMAuthStatus.dataSyncFinish) {
        /// Data sync is complete
        }
    }
    });
    
    /// If you do not want to listen to the events, unregister the listener. Otherwise, it will cause a memory leak
    /// subscription.cancel();
    
    Register the listener for multi-device login
    dartfinal subscription = NimCore.instance.authService.onlineClients.listen((clients) {
    clients.forEach((client) {
        switch (client.clientType) {
        case NIMClientType.windows:
            // Windows
            break;
        case NIMClientType.macos:
            // macOS
            break;
        case NIMClientType.web:
            // Web
            break;
        case NIMClientType.ios:
            // iOS
            break;
        case NIMClientType.android:
            // Android
            break;
        default:
            // Unknown
            break;
        }
    });
    });
    
    /// If you do not want to listen to the events, unregister the listener. Otherwise, it will cause a memory leak
    /// subscription.cancel();
    
  2. The recipient registers the event stream for receiving messages onMessage to track message receiving.

    Sample code:

    NimCore.instance.messageService.onMessage.listen((List<NIMMessage> list) {
        // Handle new messages. For the convenience of uploading and processing, the SDK ensures that the messages parameter come from the same chat object.
    });
    
    
  3. The sender and recipient manually log in by calling the login method.

    • NIMLoginInfo contains following fields:

      Parameter Required Description
      account Yes IM account, or accid
      token Yes The token required for login
    • Example

      dartNimCore.instance.authService
          .login(NIMLoginInfo(account: 'account', token: 'token',))
          .then(
          (result) {
              if (result.isSuccess) {
              /// login success
              } else {
              /// Login failure
              }
          },
          );
      

    For more information, see Login and logout.

Step 4 Send and receive messages

In the following process, text messaging between User A and User B is taken as an example to introduce how to send and receive text messages in a P2P chat using the SDK. https://doc.commsease.com/docs/interface/NIM_SDK/Latest/Flutter/nim_core/MessageService-class.html MessageService.

  1. The sender create a message by calling the createTextMessage method and send the message calling the sendMessage method.

    Sample code:

    // Test account
    String account = 'testAccount';
    // P2P chat
    NIMSessionType sessionType = NIMSessionType.p2p;
    String text = 'this is an example';
    // Create and send a text message.
    Future<NIMResult<NIMMessage>> result = MessageBuilder.createTextMessage(
        sessionId: account, sessionType: sessionType, text: text)
        .then((value) => value.isSuccess
        ? NimCore.instance.messageService
            .sendMessage(message: value.data!, resend: false)
        : Future.value(value));
    
  2. The event stream of receiving a message triggers the callback, and the recipient receives the message.

What’s next

To ensure communication security, replace the IM accounts you create in the CommsEase console for use in the testing environment IM accounts created calling the server API for production.

Was this page helpful?
Yes
No
  • Prerequisites
  • Workflow
  • Process overview
  • Step 1 Integrate the SDK
  • Step 2 Initialize the SDK
  • Step 3: Log in to IM Server
  • Step 4 Send and receive messages
  • What’s next