实现聊天室消息收发

更新时间: 2024/03/15 16:12:34

聊天室是网易云信 IM 即时通讯服务中一种比群组更加开放、更加自由的组织形态,可帮助您实现真正意义上的大型聊天室,参与人数无上限,又可满足消息到达的实时性要求,主要应用于娱乐直播、教育直播等场景。

本文介绍如何通过较少的代码集成 NetEase IM SDK (以下简称 NIM SDK)并调用相关 API,在您的应用中实现聊天室消息收发。

使用前准备

实现流程

流程概览

实现聊天室消息收发的流程,可分为下图所示的 5 步:

uml diagram

步骤1: 集成 NIM SDK

本节仅介绍更为快速的 Gradle 自动集成方式。如需查看手动集成的具体说明,请参见手动集成

Gradle 自动集成

  1. 创建 Android 项目。若已有 Android 项目,则跳过该步骤。

    打开 Android Studio,在顶部菜单依次选择 File > New > New Project 新建工程,再依次选择 Phone and Tablet > Empty Activity,单击 Next
    创建 Android 项目成功后,Android Studio 会自动开始同步 gradle, 您需要等同步成功后再进行下一步操作。

  2. 在项目根目录下的build.gradle文件中,在 repositories 后配置 mavenCentral,示例代码如下:

    javaallprojects {
        repositories {
            mavenCentral()
        }
    }
    
  3. 在主工程的 build.gradle 文件中,设置支持的 SO 库架构。

    javaandroid {
        defaultConfig {
            ndk {
                //设置支持的 SO 库架构
                abiFilters "armeabi-v7a", "x86","arm64-v8a","x86_64"
            }
        }
    }
    
  4. 在主工程的 build.gradle 文件中,根据需要添加对应的依赖库:

    javadependencies {
        implementation fileTree(dir: 'libs', include: '*.jar')        
        // 添加 IM 基础功能依赖 (必需),LATEST_VERSION 为 SDK 最新版本号
        implementation "com.netease.nimlib:basesdk:${LATEST_VERSION}"
        // 添加第三方离线推送相关依赖(可选),LATEST_VERSION 为 SDK 最新版本号
        implementation "com.netease.nimlib:push:${LATEST_VERSION}"
        // 添加聊天室相关依赖(聊天室功能必需),LATEST_VERSION 为 SDK 最新版本号
        implementation "com.netease.nimlib:chatroom:${LATEST_VERSION}"
    }
    

    添加的各依赖库版本号必须一致。可在SDK 下载页面查看当前最新版本号。

添加权限

根据实际应用需求,在 AndroidManifest.xml 中添加所需权限。请将 com.netease.nim.demo 替换为自己的包名。

xml<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
	      package="com.netease.nim.demo">
	<!-- 权限声明 -->
	<!-- 访问网络状态-->
	<uses-permission android:name="android.permission.INTERNET" />
	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
	<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
	
    <!-- 外置存储存取权限 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <!-- 多媒体相关 -->
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <!-- Android11:V8.6.1及之后的版本不需要;其他:V4.4.0及之后的版本不需要 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

    <!-- 控制呼吸灯,振动器等,用于新消息提醒 -->
    <uses-permission android:name="android.permission.FLASHLIGHT" />
    <uses-permission android:name="android.permission.VIBRATE" />
    
    <!-- 8.0+系统需要-->
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />


    <!-- 下面的 uses-permission 一起加入到你的 AndroidManifest 文件中。 -->
    <permission
        android:name="com.netease.nim.demo.permission.RECEIVE_MSG"
        android:protectionLevel="signature"/>

     <uses-permission android:name="com.netease.nim.demo.permission.RECEIVE_MSG"/>

    <application
        ...>
        <!-- APP key, 可以在这里设置,也可以在 SDKOptions 中提供。
            如果 SDKOptions 中提供了,则取 SDKOptions 中的值。 -->
        <meta-data
            android:name="com.netease.nim.appKey"
            android:value="key_of_your_app" />

        <!-- 云信后台服务,请使用独立进程。 -->
        <service
            android:name="com.netease.nimlib.service.NimService"
            android:process=":core"/>
        <!-- 云信后台服务,使用 V10 接口需要添加以下代码。 -->
        <service 
            android:name="com.netease.nimlib.service.NimServiceV2" />

       <!-- 云信后台辅助服务 -->
        <service
            android:name="com.netease.nimlib.service.NimService$Aux"
            android:process=":core"/>

        <!-- 云信后台辅助服务 -->
        <service
            android:name="com.netease.nimlib.job.NIMJobService"
            android:exported="false"
            android:permission="android.permission.BIND_JOB_SERVICE"
            android:process=":core"/>

        <!-- 云信监视系统启动和网络变化的广播接收器,保持和 NimService 同一进程 -->
        <receiver android:name="com.netease.nimlib.service.NimReceiver"
            android:process=":core"
            android:exported="false">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
            </intent-filter>
        </receiver>

        <!-- 云信进程间通信 Receiver -->
        <receiver android:name="com.netease.nimlib.service.ResponseReceiver"/>

        <!-- 云信进程间通信service -->
        <service android:name="com.netease.nimlib.service.ResponseService"/>

        <!-- 云信进程间通信provider -->
        <provider
            android:name="com.netease.nimlib.ipc.NIMContentProvider"
            android:authorities="com.netease.nim.demo.ipc.provider"
            android:exported="false"
            android:process=":core" />
            
        <!-- 云信进程间通信 provider,使用 V10 接口需要添加以下代码。-->
        <provider 
            android:name="com.netease.nimlib.ipc.NIMContentProviderV2" 
            android:authorities="${applicationId}.ipc.provider.v2" 
            android:exported="false" />
      	
      	<!-- 云信内部使用的进程间通信provider -->
      	<!-- SDK启动时会强制检测该组件的声明是否配置正确,如果检测到该声明不正确,SDK会主动抛出异常引发崩溃 -->
        <provider
            android:name="com.netease.nimlib.ipc.cp.provider.PreferenceContentProvider"
            android:authorities="com.netease.nim.demo.ipc.provider.preference"
            android:exported="false" />
    </application>
</manifest>

防止代码混淆

为了避免代码混淆而导致调用接口异常,请在 proguard-rules.pro 文件中添加以下代码,将 NIM SDK 相关类加入不混淆名单。

groovy-dontwarn com.netease.nim.**
-keep class com.netease.nim.** {*;}

-dontwarn com.netease.nimlib.**
-keep class com.netease.nimlib.** {*;}

-dontwarn com.netease.share.**
-keep class com.netease.share.** {*;}

-dontwarn com.netease.mobsec.**
-keep class com.netease.mobsec.** {*;}

#如果你使用全文检索插件,需要加入
-dontwarn org.apache.lucene.**
-keep class org.apache.lucene.** {*;}

#如果你开启数据库功能,需要加入
-keep class net.sqlcipher.** {*;}

步骤2: 初始化 SDK

集成 SDK 后,需要先完成 SDK 的初始化后才能使用其他功能。

ApplicationonCreate 中,调用 NIMClient#initV2 方法进行初始化。

示例代码如下:

javapublic class NimApplication extends Application {
    public void onCreate() {
        // 激活V10 API后,可以根据该字段选项选择是否禁用V10 API登录,默认false,即使用V10 API登录
        // sdkOptions.disableV2Login = true;
        ...
        // 按需设置其它 SDKOptions 设置项

        NIMClient.initV2(context, sdkOptions);
    }
}

以上提供了一个简化的初始化示例,更多初始化信息请参见初始化 Android SDK

步骤3: 登录聊天室

  1. 发送方和接收方调用 newInstance 方法创建聊天室实例。调用成功后,返回聊天室实例(instanceId),聊天室实例与聊天室(roomId)形成一一绑定关系。

    示例代码如下:

    javaV2NIMChatroomClient chatroomClient = V2NIMChatroomClient.newInstance();
    
  2. 发送方和接收方调用 addChatroomClientListener 方法注册聊天室登录相关监听器,包括聊天室连接状态变更、进出聊天室、被踢出聊天室。

    示例代码如下:

    javachatroomClient.addChatroomClientListener(new V2NIMChatroomClientListener() {
        @Override
        public void onChatroomStatus(V2NIMChatroomStatus status, V2NIMError error) {
    
        }
    
        @Override
        public void onChatroomEntered() {
    
        }
    
        @Override
        public void onChatroomExited(V2NIMError error) {
    
        }
    
        @Override
        public void onChatroomKicked(V2NIMChatroomKickedInfo kickedInfo) {
    
        }
    });
    
  3. 在登录聊天室之前,需要先提前获取聊天室地址。可以通过以下两种方式获取:

  • 若当前客户端已登录 IM,那么可以通过 getChatroomLinkAddress 方法获取指定聊天室的地址。

    示例代码如下:

    javaV2NIMConnectStatus status=  NIMClient.getV2NIMLoginService().getConnectStatus();
    
  • 若当前客户端未登录 IM,那么 SDK 无法获取聊天室服务器的地址,需要客户端向开发者应用服务器请求该地址,而应用服务器需要向网易云信服务器请求,然后将请求结果原路返回给客户端。具体请 参考获取聊天室地址 服务端 API。

  1. 发送方和接收方调用 enter 方法登录聊天室。

    示例代码如下:

    javaV2NIMChatroomLinkProvider chatroomLinkProvider = new V2NIMChatroomLinkProvider() {
        @Override
        public List<String> getLinkAddress(String roomId, String accountId) {
            return "聊天室 link 地址";
        }
    };
    
    V2NIMChatroomLoginOption loginOption = V2NIMChatroomLoginOption.V2NIMChatroomLoginOptionBuilder.builder()
    // 按需设置
    //                .withAuthType()
    //                .withLoginExtensionProvider()
    //                .withTokenProvider()
    .build();
    
    V2NIMChatroomEnterParams enterParams = V2NIMChatroomEnterParams.V2NIMChatroomEnterParamsBuilder.builder(chatroomLinkProvider)
    // 按需设置
    //                .withAccountId()
    //                .withAnonymousMode()
    //                .withAntispamConfig()
    //                .withLocationConfig()
    //                .withLoginOption(loginOption)
    //                .withNotificationExtension()
    //                .withRoomAvatar()
    //                .withRoomNick()
    //                .withServerExtension()
    //                .withTagConfig()
    //                .withTimeout()
    //                .withToken()
    .build();
    
    V2NIMChatroomClient.newInstance().enter(roomId, enterParams,
    new V2NIMSuccessCallback<V2NIMChatroomEnterResult>() {
        @Override
        public void onSuccess(V2NIMChatroomEnterResult result) {
    
        }
    },
    new V2NIMFailureCallback() {
        @Override
        public void onFailure(V2NIMError error) {
                
        }
    });
    
  2. 登录聊天室成功后,调用getChatroomService方法获取聊天室服务。后续聊天室相关操作(聊天室成员、消息等)均在返回的 V2NIMChatroomService 类中实现。

    示例代码如下:

    javaV2NIMChatroomService chatroomService = chatroomClient.getChatroomService()
    

步骤5: 聊天室消息收发

NIM SDK 支持多种消息类型,包括文本消息、图片消息、语音消息、视频消息、文件消息、地理位置消息、提示消息、通知消息以及自定义消息。

本节以发送方与接收方的消息交互为例,介绍通过 NIM SDK 快速实现聊天室文本消息收发的流程。

其他类型消息收发相关详情,请参见聊天室消息管理

  1. 接收方注册聊天室监听器,监听聊天室消息接收回调事件 onReceiveMessages

    示例代码如下:

    javaV2NIMChatroomClient v2ChatroomClient = V2NIMChatroomClient.getInstance(instanceId);
    V2NIMChatroomService v2ChatroomService = v2ChatroomClient.getChatroomService();
    
    V2NIMChatroomListener listener = new V2NIMChatroomListener() {
        @Override
        public void onReceiveMessages(List<V2NIMChatroomMessage> messages) {
    
        }
    };
    
    v2ChatroomService.addChatroomListener(listener);
    
  2. 发送方调用 createTextMessage 方法,构建一条文本消息。并调用 sendMessage 方法,发送已构建的文本消息。

    示例代码如下:

    objective-c// 新建一个聊天室实例,注意:每次 newInstance 都会返回一个新的实例,实际使用中请一个聊天室对应一个V2NIMChatroomClient实例,使用中需要临时缓存
    V2NIMChatroomClient v2ChatroomClient = V2NIMChatroomClient.newInstance();
    // 获取聊天室服务
    V2NIMChatroomService v2ChatroomService = v2ChatroomClient.getChatroomService();
    // 创建一条文本消息
    V2NIMChatroomMessage v2Message = V2NIMChatroomMessageCreator.createTextMessage("xxx");
    
    V2NIMChatroomMessageConfig messageConfig = new V2NIMChatroomMessageConfig();
    // 根据实际情况配置
    // 设置是否需要在服务端保存历史消息,默认true
    // messageConfig.setHistoryEnabled(true);
    // 设置是否是高优先级消息,默认false
    // messageConfig.setHighPriority(false);
    
    V2NIMMessageRouteConfig routeConfig = V2NIMMessageRouteConfig.V2NIMMessageRouteConfigBuilder.builder()
    // 根据实际情况配置
    // .withRouteEnabled()
    // .withRouteEnvironment()
    .build();
    
    V2NIMMessageAntispamConfig antispamConfig = V2NIMMessageAntispamConfig.V2NIMMessageAntispamConfigBuilder.builder()
    // 根据实际情况配置
    // .withAntispamBusinessId()
    // .withAntispamCheating()
    // .withAntispamCustomMessage()
    // .withAntispamEnabled()
    // .withAntispamExtension()
    .build();
    
    V2NIMSendChatroomMessageParams params = new V2NIMSendChatroomMessageParams();
    // 设置消息相关配置
    // params.setMessageConfig(messageConfig);
    // 设置路由抄送相关配置
    // params.setRouteConfig(routeConfig);
    // 设置反垃圾相关配置
    // params.setAntispamConfig(antispamConfig);
    // 是否开启本地反垃圾,默认false
    // params.setClientAntispamEnabled(false);
    // 本地反垃圾的替换文本
    // params.setClientAntispamReplace("xxx");
    //设置聊天室定向消息接收者账号ID列表
    // params.setReceiverIds(receiverIds);
    // 设置消息的目标标签表达式
    // params.setNotifyTargetTags("xxx");
    // 设置位置信息
    // params.setLocationInfo(locationInfo);
    v2ChatroomService.sendMessage(v2Message,params,
    new V2NIMSuccessCallback<V2NIMSendChatroomMessageResult>() {
        @Override
        public void onSuccess(V2NIMSendChatroomMessageResult result) {
            // 发送成功
        }
    },
    new V2NIMFailureCallback() {
        @Override
        public void onFailure(V2NIMError error) {
            // 发送失败
        }
    },
    new V2NIMProgressCallback() {
        @Override
        public void onProgress(int progress) {
            // 发送进度
        }
    });
    
  3. 接收方通过 onReceiveMessages 回调收到聊天室消息。

后续步骤

为保障通信安全,如果您在调试环境中的使用的是云信控制台生成的测试用 IM 账号 和 Token,请确保在后续的正式生产环境中,将其替换为通过 IM 服务端 API 生成的正式 IM 账号和 token

相关参考

此文档是否对你有帮助?
有帮助
去反馈
  • 使用前准备
  • 实现流程
  • 流程概览
  • 步骤1: 集成 NIM SDK
  • Gradle 自动集成
  • 添加权限
  • 防止代码混淆
  • 步骤2: 初始化 SDK
  • 步骤3: 登录聊天室
  • 步骤5: 聊天室消息收发
  • 后续步骤
  • 相关参考