消息收发

更新时间: 2024/07/01 15:37:47

NetEase IM SDK(以下简称 NIM SDK)支持收发多种消息类型,助您快速实现多样化的消息业务场景。

本文介绍通过 NIM SDK 实现消息收发的具体流程。

本文介绍的消息收发仅包含单聊、高级群、超大群消息,不包含聊天室、圈组的消息,具体实现流程请分别参见聊天室消息收发圈组消息收发

技术原理

消息收发流程图

应用集成 NIM SDK 并完成 SDK 初始化后,消息收发流程如下图所示(本地提示消息通知消息除外):

消息收发基本流程如下:

  1. 账号集成与登录。
    1. 开发者将用户账号 accountId 传入云信 IM 服务器。
    2. 云信 IM 服务器返回 Token 给应用服务器。
    3. 应用客户端登录应用服务器。
    4. 应用服务器将 Token 返回给应用客户端。
    5. 用户携带用户账号和 Token 登录云信 IM 服务器,云信 IM 服务器进行校验。
  2. 用户A 发送一条消息到云信 IM 服务器。
  3. 云信 IM 服务器投递消息至其他用户,分为如下两种情况:
    • 如果为单聊消息,IM 服务器将其投递至用户B。
    • 如果为群聊消息,IM 服务器将其投递至群内其他每一位用户。

上图仅以静态 Token 登录为例展示消息收发流程。网易云信 IM 还支持动态 Token 登录鉴权和第三方回调登录鉴权,相关详情请参见登录鉴权

关键接口说明

前提条件

在实现消息收发之前,请确保:

频控限制

发送消息(sendMessage)方法一分钟内默认最多可调用 300 次。

实现文本消息收发

API 调用时序

uml diagram

实现步骤

  1. 接收方注册消息监听器,监听消息接收回调事件。

    Android/iOS/macOS/Windows

    接收方调用 addMessageListener 方法注册消息监听器,监听消息接收回调事件 onReceiveMessages

    Android
    javaV2NIMMessageService v2MessageService = NIMClient.getService(V2NIMMessageService.class);
    
    V2NIMMessageListener messageListener = new V2NIMMessageListener() {
    
        @Override
        public void onReceiveMessages(List<V2NIMMessage> messages) {
    
        }
    };
    v2MessageService.addMessageListener(messageListener);
    
    iOS
    objective-c[[[NIMSDK sharedSDK] v2MessageService] addMessageListener:listener];
    
    macOS/Windows
    cppV2NIMMessageListener listener;
    listener.onReceiveMessages = [](nstd::vector<V2NIMMessage> messages) {
        // receive messages
    };
    messageService.addMessageListener(listener);
    

    如需移除消息监听器,可调用 removeMessageListener

    Android
    javaV2NIMMessageService v2MessageService = NIMClient.getService(V2NIMMessageService.class);
    
    v2MessageService.removeMessageListener(messageListener);
    
    iOS
    objective-c[[[NIMSDK sharedSDK] v2MessageService] removeMessageListener:listener];
    
    macOS/Windows
    cppmessageService.removeMessageListener(listener);
    

    Web/uni-app/小程序/Harmony

    调用 on("EventName") 方法注册消息监听器,监听消息接收回调事件 onReceiveMessages

    Web/uni-app/小程序
    typescriptnim.V2NIMMessageService.on("onReceiveMessages", function (messages: V2NIMMessage[]) {})
    

    如需移除登录相关监听器,可调用 off("EventName")

    typescriptnim.V2NIMMessageService.off("onReceiveMessages", function (messages: V2NIMMessage[]) {})
    
    Harmony
    typescriptnim.messageService.on("onReceiveMessages", function (messages: V2NIMMessage[]) {})
    

    如需移除登录相关监听器,可调用 off("EventName")

    typescriptnim.messageService.off("onReceiveMessages", function (messages: V2NIMMessage[]) {})
    
  2. 发送方调用 createTextMessage 方法,构建一条文本消息。

    Android
    javaV2NIMMessage v2TextMessage = V2NIMMessageCreator.createTextMessage("text content");
    
    iOS
    objective-cV2NIMMessage *v2Message = [V2NIMMessageCreator createTextMessage:@"hello world"];
    
    macOS/Windows
    cppauto textMessage = V2NIMMessageCreator::createTextMessage("hello world");
    if(!textMessage) {
        // create text message failed
    }
    
    Web/uni-app/小程序
    typescripttry {
        const message = nim.V2NIMMessageCreator.createTextMessage('hello world')
    } catch(err) {
        // todo error
    }
    
    Harmony
    typescripttry {
        const message = nim.messageCreator.createTextMessage('hello world')
    } catch(err) {
        // todo error
    }
    
  3. 发送方调用 sendMessage 方法,发送已构建的文本消息。 发送消息时,设置消息发送成功回调参数 success 和消息发送失败回调参数 failure,监听消息发送是否成功。若消息发送成功,则通过 V2NIMSuccessCallback 回调返回的 V2NIMSendMessageResult 接收消息对象;若消息发送失败,则通过 V2NIMFailureCallback 获取相关错误码。

    • 参数说明

      Android
      参数名称 类型 是否必填 默认值 描述
      message V2NIMMessage - 消息对象,通过调用 V2NIMMessageCreator 中的接口创建。如果为空或不存在则返回 191004 参数错误。
      conversationId String - 会话 ID,通过调用 V2NIMConversationIdUtil 的对应函数创建。
      • 组成方式:用户账号(accid)|会话类型( V2NIMConversationType)|聊天对象账号(accid)或群组 ID。
      • 如果为空或不存在则返回 191004 参数错误。
      params V2NIMSendMessageParams null 消息发送配置参数,包括发送、推送、抄送、反垃圾等配置。
      success V2NIMSuccessCallback - 消息发送成功回调,返回 V2NIMSendMessageResult
      failure V2NIMFailureCallback - 消息发送失败回调,返回 错误码
      progress V2NIMProgressCallback null 附件上传进度回调,用于图片、语音、视频、文件类型消息。
      iOS
      参数名称 类型 是否必填 默认值 描述
      message V2NIMMessage - 消息对象,通过调用 V2NIMMessageCreator 中的接口创建。如果为空或不存在则返回 191004 参数错误。
      conversationId String - 会话 ID,通过调用 V2NIMConversationIdUtil 的对应函数创建。
    • 组成方式:用户账号(accid)|会话类型( V2NIMConversationType)|聊天对象账号(accid)或群组 ID。
    • 如果为空或不存在则返回 191004 参数错误。
    • params V2NIMSendMessageParams null 消息发送配置参数,包括发送、推送、抄送、反垃圾等配置。
      success V2NIMSuccessCallback - 消息发送成功回调,返回 V2NIMSendMessageResult
      failure V2NIMFailureCallback - 消息发送失败回调,返回 错误码
      progress V2NIMProgressCallback null 附件上传进度回调,用于图片、语音、视频、文件类型消息。
      macOS/Windows
      参数名称 类型 是否必填 默认值 描述
      message V2NIMMessage - 消息对象,通过调用 V2NIMMessageCreator 中的接口创建。如果为空或不存在则返回 191004 参数错误。
      conversationId String - 会话 ID,通过调用 V2NIMConversationIdUtil 的对应函数创建。
    • 组成方式:用户账号(accid)|会话类型( V2NIMConversationType)|聊天对象账号(accid)或群组 ID。
    • 如果为空或不存在则返回 191004 参数错误。
    • params V2NIMSendMessageParams null 消息发送配置参数,包括发送、推送、抄送、反垃圾等配置。
      success V2NIMSuccessCallback - 消息发送成功回调,返回 V2NIMSendMessageResult
      failure V2NIMFailureCallback - 消息发送失败回调,返回 错误码
      progress V2NIMProgressCallback null 附件上传进度回调,用于图片、语音、视频、文件类型消息。
      Web/uni-app/小程序
      参数名称 类型 是否必填 默认值 描述
      message V2NIMMessage - 消息对象,通过调用 V2NIMMessageCreator 中的接口创建。如果为空或不存在则返回 191004 参数错误。
      conversationId String - 会话 ID,通过调用 V2NIMConversationIdUtil 的对应函数创建。
    • 组成方式:用户账号(accid)|会话类型( V2NIMConversationType)|聊天对象账号(accid)或群组 ID。
    • 如果为空或不存在则返回 191004 参数错误。
    • params V2NIMSendMessageParams null 消息发送配置参数,包括发送、推送、抄送、反垃圾等配置。
      progress V2NIMProgressCallback null 附件上传进度回调,用于图片、语音、视频、文件类型消息。
      Harmony
      参数名称 类型 是否必填 默认值 描述
      message V2NIMMessage - 消息对象,通过调用 V2NIMMessageCreator 中的接口创建。如果为空或不存在则返回 191004 参数错误。
      conversationId String - 会话 ID,通过调用 V2NIMConversationIdUtil 的对应函数创建。
    • 组成方式:用户账号(accid)|会话类型( V2NIMConversationType)|聊天对象账号(accid)或群组 ID。
    • 如果为空或不存在则返回 191004 参数错误。
    • params V2NIMSendMessageParams null 消息发送配置参数,包括发送、推送、抄送、反垃圾等配置。
      progress V2NIMProgressCallback null 附件上传进度回调,用于图片、语音、视频、文件类型消息。
    • V2NIMSendMessageParams 消息发送配置属性说明

      名称 类型 是否必填 默认值 描述
      messageConfig V2NIMMessageConfig - 消息相关配置
      routeConfig routeConfig - 消息路由(抄送)相关配置
      pushConfig V2NIMMessagePushConfig - 消息第三方推送相关配置
      antispamConfig V2NIMMessageAntispamConfig - 消息反垃圾相关配置,包括本地反垃圾或安全通配置。
      robotConfig V2NIMMessageRobotConfig - 消息机器人相关配置
    • 示例代码

      Android
      javaV2NIMMessageService v2MessageService = NIMClient.getService(V2NIMMessageService.class);
      // 创建一条文本消息
      V2NIMMessage v2Message = V2NIMMessageCreator.createTextMessage("xxx");
      // 以单聊类型为例
      String conversationId = V2NIMConversationIdUtil.conversationId("xxx", V2NIMConversationType.V2NIM_CONVERSATION_TYPE_P2P);
      // 根据实际情况配置
      V2NIMMessageAntispamConfig antispamConfig = V2NIMMessageAntispamConfig.V2NIMMessageAntispamConfigBuilder.builder()
      .withAntispamBusinessId()
      .withAntispamCheating()
      .withAntispamCustomMessage()
      .withAntispamEnabled()
      .withAntispamExtension()
      .build();
      
      // 根据实际情况配置
      V2NIMMessageConfig messageConfig = V2NIMMessageConfig.V2NIMMessageConfigBuilder.builder()
      .withConversationUpdateEnabled()
      .withHistoryEnabled()
      .withOfflineEnabled()
      .withOnlineSyncEnabled()
      .withReadReceiptEnabled()
      .withRoamingEnabled()
      .withUnreadEnabled()
      .build();
      // 根据实际情况配置
      V2NIMMessagePushConfig pushConfig = V2NIMMessagePushConfig.V2NIMMessagePushConfigBuilder.builder()
      .withContent()
      .withForcePush()
      .withForcePushAccountIds()
      .withForcePushContent()
      .withPayload()
      .withPushEnabled()
      .withPushNickEnabled()
      .build();
      // 根据实际情况配置
      V2NIMMessageRobotConfig robotConfig = V2NIMMessageRobotConfig.V2NIMMessageRobotConfigBuilder.builder()
      .withAccountId()
      .withCustomContent()
      .withFunction()
      .withTopic()
      .build();
      // 根据实际情况配置
      V2NIMMessageRouteConfig routeConfig = V2NIMMessageRouteConfig.V2NIMMessageRouteConfigBuilder.builder()
      .withRouteEnabled()
      .withRouteEnvironment()
      .build();
      // 根据实际情况配置
      V2NIMSendMessageParams sendMessageParams = V2NIMSendMessageParams.V2NIMSendMessageParamsBuilder.builder()
      .withAntispamConfig(antispamConfig)
      .withClientAntispamEnabled()
      .withClientAntispamReplace()
      .withMessageConfig(messageConfig)
      .withPushConfig(pushConfig)
      .withRobotConfig(robotConfig)
      .withRouteConfig(routeConfig)
      .build();
      // 发送消息
      v2MessageService.sendMessage(v2Message, conversationId, sendMessageParams,
      new V2NIMSuccessCallback<V2NIMSendMessageResult>() {
          @Override
          public void onSuccess(V2NIMSendMessageResult v2NIMSendMessageResult) {
              // TODO: 发送成功
          },
          new V2NIMFailureCallback() {
              @Override
              public void onFailure(V2NIMError error) {
                  // TODO: 发送失败
              }
          });
      }
      
      iOS
      objective-c// 创建一条文本消息
      V2NIMMessage *message = [V2NIMMessageCreator createTextMessage:@"v2 message"];
      V2NIMSendMessageParams *params = [[V2NIMSendMessageParams alloc] init];
      // 发送消息
      [[[NIMSDK sharedSDK] v2MessageService] sendMessage:message 
                                          conversationId:@"conversationId"
                                                  params:params
                                              success:^(V2NIMSendMessageResult * _Nonull result) {
                                                  // 发送成功回调
                                                  }
                                              failure:^(V2NIMError * _Nonnull error) {
                                                  // 发送失败回调, error 包含错误原因
                                                  }
      }];                        
      
      macOS/Windows
      cpp// 以单聊类型为例
      auto conversationId = V2NIMConversationIdUtil::p2pConversationId("target_account_id");
      // 创建一条文本消息
      auto message = V2NIMMessageCreator::createTextMessage("hello world");
      auto params = V2NIMSendMessageParams();
      // 发送消息
      messageService.sendMessage(
          message,
          conversationId,
          params,
          [](V2NIMSendMessageResult result) {
              // send message succeeded
          },
          [](V2NIMError error) {
              // send message failed, handle error
          });
      
      Web/uni-app/小程序
      typescripttry {
      // 创建一条文本消息
      const message: V2NIMMessage = nim.V2NIMMessageCreator.createTextMessage("hello")
      // 发送消息
      const res: V2NIMSendMessageResult = await nim.V2NIMMessageService.sendMessage(message, 'test1|1|test2')
      // todo success
      } catch (err) {
      // todo error
      }
      
      Harmony
      typescripttry {
      // 创建一条文本消息
      const message: V2NIMMessage = nim.messageCreator.createTextMessage("hello")
      // 发送消息
      const res: V2NIMSendMessageResult = await nim.messageService.sendMessage(message, 'test1|1|test2')
      // todo Success
      } catch (err) {
      // todo error
      }
      
  4. 接收方通过 onReceiveMessages 回调收到文本消息。

实现富媒体消息收发

富媒体消息包括图片消息、语音消息、视频消息和文件消息。

API 调用时序

uml diagram

实现步骤

  1. 接收方注册消息监听器,监听消息接收回调事件。

    示例代码请参考实现文本消息收发的实现步骤 1。

  2. 发送方构建富媒体消息,指定 NOS 存储场景。

    NIM SDK 支持设置 IM 数据在网易对象存储(Netease Object Storage,简称 NOS)服务上的存储场景。这里的存储场景指需要存储到 NOS 的 IM 数据类型,默认包括多媒体消息的附件资源和用户、群组的资料,且这两类 IM 数据在 NOS 的存储默认不过期。NIM SDK 也支持指定 IM 数据在 NOS 上的过期时间,过期后,数据将被 NOS 删除。

  • 不同消息类型创建方法

    消息类型
    创建方法
    图片消息 createImageMessage
    语音消息 createAudioMessage
    视频消息 createVideoMessage
    文件消息 createFileMessage
  • NOS 场景参数说明

    NOS 场景 枚举值 说明
    默认场景 V2NIMStorageSceneConfig.DEFAULT_PROFILE 用于用户、群组资料的上传场景。
    IM 场景 V2NIMStorageSceneConfig.DEFAULT_IM 用于文件的上传场景。
    系统场景 V2NIMStorageSceneConfig.DEFAULT_SYSTEM 用于 SDK 内部文件的上传场景。
    安全链接场景 V2NIMStorageSceneConfig.SECURITY_LINK 查看该场景的上传文件需要密钥。
    自定义场景 - 用户调用 addCustomStorageScene 添加的自定义场景。
  • 示例代码

    图片消息:

    Android
    javaV2NIMMessage v2ImageMessage = V2NIMMessageCreator.createImageMessage(imagePath, name, sceneName, width, height);
    
    iOS
    objective-cNSString *imagePath = @"文件沙盒路径";
    V2NIMMessage *message = [V2NIMMessageCreator createImageMessage:imagePath 
                                                            name:@"imageName"
                                                        sceneName:@"nim_default_im"
                                                            width:200
                                                            height:200];
    
    macOS/Windows
    cppauto imageMessage = V2NIMMessageCreator::createImageMessage("imagePath", "imageName", V2NIM_STORAGE_SCENE_NAME_DEFAULT_IM, 100,
    100); if(!imageMessage) {
        // create image message failed
    }
    
    Web/uni-app/小程序
    typescripttry {
        const message = nim.V2NIMMessageCreator.createImageMessage(document.getElementById('fileInputId').files[0])
    } catch(err) {
        // todo error
    }
    
    Harmony
    typescripttry {
        const imagePath = "沙盒路径"
        const message = nim.messageCreator.createImageMessage(imagePath)
    } catch(err) {
        // todo error
    }
    

    语音消息:

    Android
    javaV2NIMMessage v2AudioMessage = V2NIMMessageCreator.createAudioMessage(audioPath, name, sceneName, duration);
    
    iOS
    objective-cNSString *audioPath = @"文件沙盒路径";
    V2NIMMessage *message = [V2NIMMessageCreator createAudioMessage:audioPath 
                                                            name:@"audioName"
                                                        sceneName:@"nim_default_im"
                                                        duration:2];
    
    macOS/Windows
    cppauto audioMessage = V2NIMMessageCreator::createAudioMessage("audioPath", "audioName", V2NIM_STORAGE_SCENE_NAME_DEFAULT_IM, 100);
        if(!audioMessage) {
            // create audio message failed
    }
    
    Web/uni-app/小程序
    typescripttry {
        const message = nim.V2NIMMessageCreator.createAudioMessage(document.getElementById('fileInputId').files[0])
    } catch(err) {
        // todo error
    }
    
    Harmony
    typescripttry {
        const audioPath = "文件沙盒路径"const message = nim.messageCreator.createAudioMessage(audioPath)
    } catch(err) {
        // todo error
    }
    

    视频消息:

    Android
    javaV2NIMMessage v2VideoMessage = V2NIMMessageCreator.createVideoMessage(videoPath, name, sceneName, duration, width, height);
    
    iOS
    objective-cNSString *videoPath = @"文件沙盒路径";
    V2NIMMessage *message = [V2NIMMessageCreator createVideoMessage:videoPath 
                                                            name:@"name"
                                                        sceneName:@"nim_default_im"
                                                        duration:15
                                                            width:200
                                                            height:200];
    
    macOS/Windows
    cppauto videoMessage = V2NIMMessageCreator::createVideoMessage("videoPath", "videoName", V2NIM_STORAGE_SCENE_NAME_DEFAULT_IM, 100, 100, 100);
    if (!videoMessage) {
        // create video message failed
    }
    
    Web/uni-app/小程序
    typescripttry {
        const message = nim.V2NIMMessageCreator.createVideoMessage(document.getElementById('fileInputId').files[0])
    } catch(err) {
        // todo error
    }
    
    Harmony
    typescripttry {
        const videoPath = '沙盒路径'
        const message = nim.messageCreator.createVideoMessage(videoPath)
    } catch(err) {
        // todo error
    }
    

    文件消息:

    Android
    javaV2NIMMessage v2FileMessage = V2NIMMessageCreator.createFileMessage(filePath, name, sceneName);
    
    iOS
    objective-cNSString *filePath = @"文件沙盒路径";
    V2NIMMessage *message = [V2NIMMessageCreator createFileMessage:filePath 
                                                            name:@"name"
                                                        sceneName:@"nim_default_im"];
    
    macOS/Windows
    cppauto fileMessage = V2NIMMessageCreator::createFileMessage("filePath", "fileName", V2NIM_STORAGE_SCENE_NAME_DEFAULT_IM);
    if(!fileMessage) {
        // create file message failed
    }
    
    Web/uni-app/小程序
    typescripttry {
        const message = nim.V2NIMMessageCreator.createFileMessage(document.getElementById('fileInputId').files[0])
    } catch(err) {
        // todo error
    }
    
    Harmony
    typescripttry {
        const filePath = '沙盒路径'
        const message = nim.messageCreator.createFileMessage(filePath)
    } catch(err) {
        // todo error
    }
    }
    
  1. 发送方调用 sendMessage 方法,发送已构建的富媒体消息。

    发送消息时,设置消息发送成功回调参数 success、消息发送失败参数 failure 及附件上传进度回调参数 progress,监听消息发送是否成功及附件上传进度。若消息发送成功,则通过 V2NIMSuccessCallback 回调返回的 V2NIMSendMessageResult 接收消息对象;若消息发送失败,则通过 V2NIMFailureCallback 获取相关错误码。

    如果同一个图片/文件消息需要多次发送时,建议控制时序依次发送,避免出现发送失败的问题。

    • 参数说明

      Android
      参数名称 类型 是否必填 默认值 描述
      message V2NIMMessage - 消息对象,通过调用 V2NIMMessageCreator 中的接口创建。如果为空或不存在则返回 191004 参数错误。
      conversationId String - 会话 ID,通过调用 V2NIMConversationIdUtil 的对应函数创建。
    • 组成方式:用户账号(accid)|会话类型( V2NIMConversationType)|聊天对象账号(accid)或群组 ID。
    • 如果为空或不存在则返回 191004 参数错误。
    • params V2NIMSendMessageParams null 消息发送配置参数,包括发送、推送、抄送、反垃圾等配置。
      success V2NIMSuccessCallback - 消息发送成功回调,返回 V2NIMSendMessageResult
      failure V2NIMFailureCallback - 消息发送失败回调,返回 错误码
      progress V2NIMProgressCallback null 附件上传进度回调,用于图片、语音、视频、文件类型消息。
      iOS
      参数名称 类型 是否必填 默认值 描述
      message V2NIMMessage - 消息对象,通过调用 V2NIMMessageCreator 中的接口创建。如果为空或不存在则返回 191004 参数错误。
      conversationId String - 会话 ID,通过调用 V2NIMConversationIdUtil 的对应函数创建。
    • 组成方式:用户账号(accid)|会话类型( V2NIMConversationType)|聊天对象账号(accid)或群组 ID。
    • 如果为空或不存在则返回 191004 参数错误。
    • params V2NIMSendMessageParams null 消息发送配置参数,包括发送、推送、抄送、反垃圾等配置。
      success V2NIMSuccessCallback - 消息发送成功回调,返回 V2NIMSendMessageResult
      failure V2NIMFailureCallback - 消息发送失败回调,返回 错误码
      progress V2NIMProgressCallback null 附件上传进度回调,用于图片、语音、视频、文件类型消息。
      macOS/Windows
      参数名称 类型 是否必填 默认值 描述
      message V2NIMMessage - 消息对象,通过调用 V2NIMMessageCreator 中的接口创建。如果为空或不存在则返回 191004 参数错误。
      conversationId String - 会话 ID,通过调用 V2NIMConversationIdUtil 的对应函数创建。
    • 组成方式:用户账号(accid)|会话类型( V2NIMConversationType)|聊天对象账号(accid)或群组 ID。
    • 如果为空或不存在则返回 191004 参数错误。
    • params V2NIMSendMessageParams null 消息发送配置参数,包括发送、推送、抄送、反垃圾等配置。
      success V2NIMSuccessCallback - 消息发送成功回调,返回 V2NIMSendMessageResult
      failure V2NIMFailureCallback - 消息发送失败回调,返回 错误码
      progress V2NIMProgressCallback null 附件上传进度回调,用于图片、语音、视频、文件类型消息。
      Web/uni-app/小程序
      参数名称 类型 是否必填 默认值 描述
      message V2NIMMessage - 消息对象,通过调用 V2NIMMessageCreator 中的接口创建。如果为空或不存在则返回 191004 参数错误。
      conversationId String - 会话 ID,通过调用 V2NIMConversationIdUtil 的对应函数创建。
    • 组成方式:用户账号(accid)|会话类型( V2NIMConversationType)|聊天对象账号(accid)或群组 ID。
    • 如果为空或不存在则返回 191004 参数错误。
    • params V2NIMSendMessageParams null 消息发送配置参数,包括发送、推送、抄送、反垃圾等配置。
      Harmony
      参数名称 类型 是否必填 默认值 描述
      message V2NIMMessage - 消息对象,通过调用 V2NIMMessageCreator 中的接口创建。如果为空或不存在则返回 191004 参数错误。
      conversationId String - 会话 ID,通过调用 V2NIMConversationIdUtil 的对应函数创建。
    • 组成方式:用户账号(accid)|会话类型( V2NIMConversationType)|聊天对象账号(accid)或群组 ID。
    • 如果为空或不存在则返回 191004 参数错误。
    • params V2NIMSendMessageParams null 消息发送配置参数,包括发送、推送、抄送、反垃圾等配置。
    • V2NIMSendMessageParams 消息配置参数说明

      名称 类型 是否必填 默认值 描述
      messageConfig V2NIMMessageConfig - 消息相关配置
      routeConfig routeConfig - 消息路由(抄送)相关配置
      pushConfig V2NIMMessagePushConfig - 消息第三方推送相关配置
      antispamConfig V2NIMMessageAntispamConfig - 消息反垃圾相关配置,包括本地反垃圾或安全通配置。
      robotConfig V2NIMMessageRobotConfig - 消息机器人相关配置
    • 示例代码

      以单聊消息为例,发送富媒体消息的示例代码如下:

      Android
      javaV2NIMMessageService v2MessageService = NIMClient.getService(V2NIMMessageService.class);
      // 以单聊类型为例
      String conversationId = V2NIMConversationIdUtil.conversationId("xxx", V2NIMConversationType.V2NIM_CONVERSATION_TYPE_P2P);
      // 根据实际情况配置
      V2NIMMessageAntispamConfig antispamConfig = V2NIMMessageAntispamConfig.V2NIMMessageAntispamConfigBuilder.builder()
      .withAntispamBusinessId()
      .withAntispamCheating()
      .withAntispamCustomMessage()
      .withAntispamEnabled()
      .withAntispamExtension()
      .build();
      
      // 根据实际情况配置
      V2NIMMessageConfig messageConfig = V2NIMMessageConfig.V2NIMMessageConfigBuilder.builder()
      .withConversationUpdateEnabled()
      .withHistoryEnabled()
      .withOfflineEnabled()
      .withOnlineSyncEnabled()
      .withReadReceiptEnabled()
      .withRoamingEnabled()
      .withUnreadEnabled()
      .build();
      // 根据实际情况配置
      V2NIMMessagePushConfig pushConfig = V2NIMMessagePushConfig.V2NIMMessagePushConfigBuilder.builder()
      .withContent()
      .withForcePush()
      .withForcePushAccountIds()
      .withForcePushContent()
      .withPayload()
      .withPushEnabled()
      .withPushNickEnabled()
      .build();
      // 根据实际情况配置
      V2NIMMessageRobotConfig robotConfig = V2NIMMessageRobotConfig.V2NIMMessageRobotConfigBuilder.builder()
      .withAccountId()
      .withCustomContent()
      .withFunction()
      .withTopic()
      .build();
      // 根据实际情况配置
      V2NIMMessageRouteConfig routeConfig = V2NIMMessageRouteConfig.V2NIMMessageRouteConfigBuilder.builder()
      .withRouteEnabled()
      .withRouteEnvironment()
      .build();
      // 根据实际情况配置
      V2NIMSendMessageParams sendMessageParams = V2NIMSendMessageParams.V2NIMSendMessageParamsBuilder.builder()
      .withAntispamConfig(antispamConfig)
      .withClientAntispamEnabled()
      .withClientAntispamReplace()
      .withMessageConfig(messageConfig)
      .withPushConfig(pushConfig)
      .withRobotConfig(robotConfig)
      .withRouteConfig(routeConfig)
      .build();
      // 发送消息
      v2MessageService.sendMessage(v2Message, conversationId, sendMessageParams,
          new V2NIMSuccessCallback<V2NIMSendMessageResult>() {
              @Override
              public void onSuccess(V2NIMSendMessageResult v2NIMSendMessageResult) {
                  // TODO: 发送成功
              }
          },
          new V2NIMFailureCallback() {
              @Override
              public void onFailure(V2NIMError error) {
                  // TODO: 发送失败
              }
          },
          new V2NIMProgressCallback() {
              @Override
              public void onProgress(int progress) {
                  // TODO: 发送进度
              }
          });
      }
      
      iOS
      objective-cV2NIMSendMessageParams *params = [[V2NIMSendMessageParams alloc] init];
      // 发送消息
      [[[NIMSDK sharedSDK] v2MessageService] sendMessage:message 
                                          conversationId:@"conversationId"
                                                  params:params
                                              success:^(V2NIMSendMessageResult * _Nonull result) {
                                                  // 发送成功回调
                                                  }
                                              failure:^(V2NIMError * _Nonnull error) {
                                                  // 发送失败回调, error 包含错误原因
                                                  }
                                              progress:^(NSUInteger) {
                                                  // 发送进度
      }];                        
      
      macOS/Windows
      cpp// 以单聊类型为例
      auto conversationId = V2NIMConversationIdUtil::p2pConversationId("target_account_id");
      auto params = V2NIMSendMessageParams();
      // 发送消息
      messageService.sendMessage(
          message,
          conversationId,
          params,
          [](V2NIMSendMessageResult result) {
              // send message succeeded
          },
          [](V2NIMError error) {
              // send message failed, handle error
          },
          [](uint32_t progress) {
              // upload progress
          });
      
      Web/uni-app/小程序
      typescripttry {
      // 发送消息
      const res: V2NIMSendMessageResult = await nim.V2NIMMessageService.sendMessage(message, 'test1|1|test2')
      // todo Success
      } catch (err) {
      // todo error
      }
      
      Harmony
      typescripttry {
      const message: V2NIMMessage = nim.messageCreator.createTextMessage("hello")
      const res: V2NIMSendMessageResult = await nim.messageService.sendMessage(message, 'test1|1|test2')
      // todo Success
      } catch (err) {
      // todo error
      }
      
  2. 接收方通过 onReceiveMessages 回调收到富媒体消息。

    富媒体资源一般默认自动下载,具体的默认下载策略请参见下表:

    消息类型 默认资源下载策略
    图片/视频消息 SDK 在收到消息时,自动下载缩略图和封面图片
    语音消息 SDK 在收到消息时,自动下载原音频
    文件消息 SDK 默认不下载原文件
    • 如果需要下载文件消息的文件资源,可调用downloadFile方法手动下载(仅支持移动端)。其他类型富媒体消息的资源如自动下载失败,也可调用该方法手动重新下载。
    • 如需自主选择下载时机,需将初始化配置参数 SDKOptions - preloadAttach 设置为 false,关闭默认资源下载策略,再在合适的时机调用 downloadFile 方法。
    • 下载完成后,通过富媒体消息对应的附件基类 V2NIMMessageFileAttachment 获取具体的附件内容,该类继承自 V2NIMMessageAttachment

    手动下载富媒体资源示例如下:

    Android
    javaString url = "https://www.abc.com/ttt.txt";
    // 设置文件存储位置
    String filePath = "xxx/ttt.txt";
    NIMClient.getService(V2NIMStorageService.class).downloadFile(url, filePath, new V2NIMSuccessCallback<String>() {
        @Override
        public void onSuccess(String filePath) {
            // 下载成功
        }
    }, new V2NIMFailureCallback() {
        @Override
        public void onFailure(V2NIMError error) {
            // 下载失败
        }
    }, new V2NIMProgressCallback() {
        @Override
        public void onProgress(int progress) {
            // 下载进度
        }
    });
    
    iOS
    objective-c// 按需配置远程目录
    NSString *url = @"https://www.abc.com/ttt.txt";
    // 按需配置存储目录
    NSString *filePath = @"Document/ttt.txt";
    [[NIMSDK sharedSDK].v2StorageService downloadFile:url filePath:filePath success:^() {
        // 成功回调
    } failure:^(V2NIMError *error) {
        // 失败回调
    } progress:^(NSUInteger progress) {
        // 进度回调
    }]; 
    
  3. (可选)如发送图片消息、视频消息或文件消息,发送后可调用 cancelMessageAttachmentUpload 方法取消附件的上传。

    如果附件已经上传成功,操作将会失败。如果成功取消了附件的上传,对应的消息会发送失败,消息状态是 V2NIM_MESSAGE_SENDING_STATE_FAILED(2),附件上传状态是 V2NIM_MESSAGE_ATTACHMENT_UPLOAD_STATE_FAILED(2)

    Android
    javaV2NIMMessageService v2MessageService = NIMClient.getService(V2NIMMessageService.class);
    
    v2MessageService.cancelMessageAttachmentUpload(message,
            new V2NIMSuccessCallback<Void>() {
                @Override
                public void onSuccess(Void unused) {
                // cancel succeeded
                }
            },
            new V2NIMFailureCallback() {
                @Override
                public void onFailure(V2NIMError error) {
                // cancel failed, handle error
                }
            });
    
    iOS
    objective-c[[[NIMSDK sharedSDK] v2MessageService] cancelMessageAttachmentUpload:message
                                                                success:^{
        // cancel succeeded
    }
                                                                failure:^(V2NIMError * _Nonnull error) {
        // cancel failed, handle error
    }];
    
    macOS/Windows
    cppV2NIMMessage message;
    // more code
    messageService.cancelMessageAttachmentUpload(
        message,
        []() {
            // cancel message attachment upload succeeded
        },
        [](V2NIMError error) {
            // cancel message attachment upload failed, handle error
        });
    
    Web/uni-app/小程序
    typescripttry {
    await nim.V2NIMMessageService.cancelMessageAttachmentUpload(message)
    // todo Success
    } catch (err) {
    // todo error
    }
    
    Harmony
    typescripttry {
    await nim.messageService.cancelMessageAttachmentUpload(message)
    // todo Success
    } catch (err) {
    // todo error
    }
    

实现地理位置消息收发

地理位置消息收发流程与文本消息收发流程基本一致,区别在于构建消息的调用方法不同(需调用 createLocationMessage)。本节仅简要展示相关调用示例,具体实现流程请参考实现文本消息收发

API 调用时序

uml diagram

实现步骤

  1. 接收方注册消息监听器,监听消息接收回调事件。

    示例代码请参考实现文本消息收发的实现步骤 1。

  2. 发送方调用 createLocationMessage 方法,构建一条地理位置消息。

    Android
    javaV2NIMMessage v2LocationMessage = V2NIMMessageCreator.createLocationMessage(latitude,longitude, address);
    
    iOS
    objective-cV2NIMMessage *message = [V2NIMMessageCreator createLocationMessage:37.787359
                                                            longitude:-122.408227
                                                            address:@"杭州滨江区网商路399号"];
    
    macOS/Windows
    cppauto locationMessage = V2NIMMessageCreator::createLocationMessage(100, 100, "address");
    if(!locationMessage) {
        // create location message failed
    }
    
    Web/uni-app/小程序
    typescripttry {
        const message = nim.V2NIMMessageCreator.createLocationMessage(30.25, 120.166664, "HangZhou")
    } catch(err) {
        // todo error
    }
    
    Harmony
    typescripttry {
        const message = nim.messageCreator.createLocationMessage(30.25, 120.166664, "HangZhou")
    } catch(err) {
        // todo error
    }
    
  3. 发送方调用 sendMessage 方法,发送已构建的地理位置消息。

  4. 接收方通过 onReceiveMessages 回调收到地理位置消息。

实现提示消息收发

提示消息(又称 Tip 消息)主要用于会话内的通知提醒。与自定义消息的区别在于,提示消息不支持设置附件。

提示消息的典型使用场景包括进入会话时出现的欢迎消息、会话过程中命中敏感词后的提示等。

API 调用时序

uml diagram

实现步骤

  1. 接收方注册消息监听器,监听消息接收回调事件。

    示例代码请参考实现文本消息收发的实现步骤 1。

  2. 发送方调用 createTipsMessage 方法,构建一条提示消息。

    Android
    javaV2NIMMessage v2TipMessage = V2NIMMessageCreator.createTipsMessage("tip content");
    
    iOS
    objective-cV2NIMMessage *message = [V2NIMMessageCreator createTipsMessage:"tip text"];
    
    macOS/Windows
    cppauto tipMessage = V2NIMMessageCreator::createTipsMessage("text");
    if(!tipMessage) {
        // create tip message failed
    }
    
    Web/uni-app/小程序
    typescripttry {
        const newMessage = nim.V2NIMMessageCreator.createTipsMessage("hint")
    } catch(err) {
        // todo error
    }
    
    Harmony
    typescripttry {
        const newMessage = nim.messageCreator.createTipsMessage("hint")
    } catch(err) {
        // todo error
    }
    
  3. 发送方调用 sendMessage 方法,发送已构建的提示消息。

    • 参数说明:参考[#实现文本消息收发]。

    • 示例代码:参考[#实现文本消息收发]。

  4. 接收方通过 onReceiveMessages 回调收到提示消息。

实现通知消息接收

通知消息区别于系统通知,属于会话内消息,是云信服务器针对一些特定场景事件预置的消息,目前主要用于群和聊天室的事件通知。当事件发生时服务器下发通知消息到 SDK,您需要解析消息中附带的信息来获取通知内容。例如群通知消息,当有新成员进群时,群内成员将收到“新成员进群”的通知消息。

  1. 接收方注册消息监听器,监听消息接收回调事件。

    示例代码请参考实现文本消息收发的实现步骤 1。

  2. 解析通知消息,具体请参见群组通知消息

实现自定义消息收发

除了上述内置消息类型外,NIM SDK 还支持自定义消息类型。

SDK 不负责定义和解析自定义消息,您需要自行完成。自定义消息存入消息数据库,会和内置消息一并展现在消息记录中。

实现步骤

  1. 调用 createCustomMessage 构建自定义消息。

    Android
    javaV2NIMMessage v2CustomMessage = V2NIMMessageCreator.createCustomMessage(text, rawAttachment);
    
    iOS
    objective-cV2NIMMessage *message = [V2NIMMessageCreator createCustomMessage:@"text"
                                                    rawAttachment:@"custoom JSON String"];
    
    macOS/Windows
    cppauto customMessage = V2NIMMessageCreator::createCustomMessage("text", R"({"key": "value"})");
    if(!customMessage) {
        // create custom message failed
    }
    
    Web/uni-app/小程序
    typescripttry {
        const message = nim.V2NIMMessageCreator.createCustomMessage("text", JSON.stringify({
            strategy: 1    
        }))
    } catch(err) {
        // todo error
    }
    
    Harmony
    typescripttry {
        const message = nim.messageCreator.createCustomMessage("text", JSON.stringify({
            strategy: 1    
        }))
    } catch(err) {
        // todo error
    }
    
  2. 发送方调用 sendMessage 方法,发送已构建的自定义消息。

    • 参数说明:参考[#实现文本消息收发]。

    • 示例代码:参考[#实现文本消息收发]。

  3. 接收方通过 onReceiveMessages 回调收到自定义消息。

场景功能

发送消息后获取消息内容

调用 sendMessage 发送消息时,设置消息发送成功回调参数 success。如果消息发送成功,通过 V2NIMSuccessCallback 回调返回的 V2NIMSendMessageResult 接收 V2NIMMessage 对象。

发送消息后确认消息是否发送成功

发送消息时,设置消息发送成功回调参数 success 和消息发送失败参数 failure,监听消息发送是否成功。如果收到 V2NIMSuccessCallback 回调,则消息发送成功。

设置消息的扩展字段

会话内消息具有服务端扩展字段和客户端扩展字段。服务端扩展字段仅能在消息发送前设置,会多端同步;客户端扩展字段在消息发送前后均可设置,不会多端同步。

  • 扩展字段必须使用 JSON 格式封装,并传入非格式化的 JSON 字符串。
  • 最大长度为 1024 字节,可通过云信控制台 IM 即时通讯下基础功能 > 消息扩展字段上限调整修改长度上限。
更新客户端扩展字段
  • 发送消息前设置:构造 V2NIMMessage 对象时,通过 localExtension 设置客户端扩展字段。

  • 发送消息后设置:调用 updateMessageLocalExtension 方法更新消息的本地扩展字段。

更新服务端扩展字段

构造 V2NIMMessage 对象时,通过 serverExtension 设置服务端端扩展字段。

插入本地消息

当有业务场景需要插入一条消息至本地数据库内而不发出时,可以通过 insertMessageToLocal 方法实现。例如本地提示类消息的 UI 展示,向群里插入一条“群创建成功”的提示消息。

该功能不支持 Web 端。

  1. 接收方注册消息监听器,监听消息接收回调事件。

    示例代码请参考实现文本消息收发的实现步骤 1。

  2. 调用 createXXXMessage 方法,构建一条消息。

  3. 调用 insertMessageToLocal 方法,向本地数据库插入一条已构建的消息。插入消息成功后,本端会收到消息接收回调 onReceiveMessages 并通知 UI 界面更新。

    • 如果为单聊场景,可以插入一条发送或接收的消息。
    • 如果为群聊场景,可以插入一条任意群成员的消息。

    以文本消息为例:

    Android
    javaV2NIMMessageService v2MessageService = NIMClient.getService(V2NIMMessageService.class);
    
    // 构建被插入的消息
    V2NIMMessage v2NIMMessage = V2NIMMessageCreator.createTextMessage("xxx");
    
    V2NIMConversationType conversationType = V2NIMConversationType.V2NIM_CONVERSATION_TYPE_P2P;
    String conversationId = V2NIMConversationIdUtil.conversationId("xxx", conversationType);
    
    v2MessageService.insertMessageToLocal(v2NIMMessage, conversationId, "xxx", 0,
            new V2NIMSuccessCallback<NIMMessage>() {
                @Override
                public void onSuccess(NIMMessage nimMessage) {
    
                }
            },
            new V2NIMFailureCallback() {
                @Override
                public void onFailure(V2NIMError error) {
                    
                }
            });
    
    iOS
    objective-c[[[NIMSDK sharedSDK] v2MessageService] insertMessageToLocal:message
                                            conversationId:@"conversaionId"
                                                    senderId:@"senderId"
                                                createTime:1698809881
                                                    success:^(V2NIMMessage * _Nonnull result) {
        // result 插入消息成功
    } failure:^(V2NIMError * _Nonnull error) {
        // error 包含错误原因
    }];
    
    macOS/Windows
    cppauto conversationId = V2NIMConversationIdUtil::p2pConversationId("target_account_id");
    auto message = V2NIMMessageCreator::createTextMessage("hello world");
    messageService.insertMessageToLocal(
        message,
        conversationId,
        "target_account_id",
        0,
        [](V2NIMMessage message) {
            // Insert local message succeeded
        },
        [](V2NIMError error) {
            // Insert local message failed, handle error
    });
    
    Harmony
    typescriptconst messageResult:V2NIMMessage = await nim.messageService.insertMessageToLocal(message, conversationId)
    

重发消息

如因网络等原因消息发送失败,您可以再次调用 sendMessage 方法重发消息。SDK 会判断本地或缓存中是否有该消息,如有则视为消息重发。

相关信息

此文档是否对你有帮助?
有帮助
去反馈
  • 技术原理
  • 消息收发流程图
  • 关键接口说明
  • 前提条件
  • 频控限制
  • 实现文本消息收发
  • API 调用时序
  • 实现步骤
  • 实现富媒体消息收发
  • API 调用时序
  • 实现步骤
  • 实现地理位置消息收发
  • API 调用时序
  • 实现步骤
  • 实现提示消息收发
  • API 调用时序
  • 实现步骤
  • 实现通知消息接收
  • 实现自定义消息收发
  • 实现步骤
  • 场景功能
  • 发送消息后获取消息内容
  • 发送消息后确认消息是否发送成功
  • 设置消息的扩展字段
  • 插入本地消息
  • 重发消息
  • 相关信息