iOS

# 消息通道

透明通道消息主要包含通话内消息和在线消息,具体使用要求和场景举例参考下表:

在线消息 通话内消息
一对一发送 支持 支持
群发消息 不支持 支持
是否支持异步发送结果上报 支持 不支持
是否需要登录
是否需要建立通话
使用场景举例 1、实现不依赖通话的一对一聊天;2、实现一些通话前的自定义信令交互,比如呼叫、拒接/接听等等; 1、实现通话中的一些自定义信令、通知等;2、实现通话中单聊和群聊;
消息内容支持 只支持文本消息 只支持文本消息
消息内容大小最大支持(bit) 4K 4K

# 1. 通话内消息

img

调用 JRTCGuest (opens new window) 下的 sendMessage (opens new window) 方法

/**
 * 发送消息,消息内容不能大于4K
 *
 * 通话建立后,调用此接口发送消息,指定成员会收到 {@link JRTCGuestCallback.onMessageReceived:content:fromUserId: onMessageReceived} 或 {@link JRTCAgentCallback.onMessageReceived:content:fromUserId: onMessageReceived} 回调
 * @param contentType 消息内容类型
 * @param content 消息内容
 * @param toUserId 指定成员的用户ID,传 nil 等同于调用 {@link sendMessage:content: sendMessage} 接口,即给通话中全部成员发送消息
 * @return 接口调用结果
 * - true: 接口调用成功
 * - false: 接口调用异常
 */
- (bool)sendMessage:(NSString *)contentType content:(NSString *)content toUserId:(nullable NSString *)toUserId;

接收消息通过实现 JRTCGuestCallback (opens new window) 中的 onMessageReceived (opens new window) 接口上报。

/**
 * 收到消息回调
 *
 * 通话中的访客和座席可分别调用 {@link JRTCGuest.sendMessage:content:toUserId: sendMessage} 和 {@link JRTCAgent.sendMessage:content:toUserId: sendMessage} 接口给通话中的指定成员或全体成员发送消息,接收消息的成员会收到此回调,由此获取消息具体信息。
 * @param contentType 消息内容类型
 * @param messageType 消息归属类型
 * - @ref MessageType1To1 : 一对一消息
 * - @ref MessageTypeGroup : 群发消息(发送给通话中所有成员)
 * @param fromUserId 发送方的用户ID
 */
- (void)onMessageReceived:(NSString *)content contentType:(NSString *)contentType messageType:(MessageType)messageType fromUserId:(NSString *)fromUserId;

示例代码:

// 给成员 agent1 发送消息
[_guest sendMessage:@"text" content:@"content" toUserId:@"agent1"];
// 给通话中所有成员发送消息
[_guest sendMessage:@"text" content:@"content" toUserId:nil];
// 收到消息
- (void)onMessageReceived:(NSString *)type content:(NSString *)content fromUserId:(NSString *)fromUserId {
 	// 收到消息,消息内容为 content,消息来自 fromUserId  
}

# 2. 在线消息

img

只要登录到 Juphoon RTC 平台就可以通过 JRTCClient (opens new window)sendOnlineMessage (opens new window) 接口实现在线消息的发送,消息内容不能大于4K。

/**
 * 发送在线消息,消息内容不能大于4K
 *
 * @param message 消息内容
 * @param userId 对端的用户名
 * @return 接口调用结果
 * - 操作ID: 接口调用成功,对应 {@link JRTCClientCallback.onOnlineMessageSendResult:operatorId: onOnlineMessageSendResult} 回调的 operatorId 参数
 * - -1: 接口调用异常,不会收到回调
 */
- (int)sendOnlineMessage:(NSString* _Nonnull)message userId:(NSString* _Nonnull)userId;

在线消息发送结果通过 onOnlineMessageSendResult (opens new window) 回调通知。

/**
 * 在线消息发送结果回调
 * @param result 发送结果是否成功
 * - true:发送成功
 * - false:发送失败
 * @param operatorId 操作ID,对应 {@link JRTCClient#sendOnlineMessage:userId: sendOnlineMessage} 的返回值
 */
- (void)onOnlineMessageSendResult:(bool)result operatorId:(int)operatorId;

在线消息接收者会收到 onOnlineMessageReceived (opens new window) 回调通知。

/**
 * 收到在线消息回调
 *
 * @param message 消息内容
 * @param userId  对方userId
 */
- (void)onOnlineMessageReceived:(NSString *)message userId:(NSString *)userId;

示例代码:

// 给用户 7777 发送在线消息
self.operatorId ==  = [_client sendOnlineMessage:@"消息内容" userId:@"7777"];
// 给用户 7777 发送在线消息结果
- (void)onOnlineMessageSendResult:(bool)result operatorId:(int)operatorId {
    if (self.operatorId == operatorId) {
        if (result == true) {
        	// 在线消息发送成功
    	} 
    	else {
        	// 在线消息发送失败   
    	}
    }
}

// 收到在线消息
- (void)onOnlineMessageReceived:(NSString *)message userId:(NSString *)userId {
    // 收到来自 userId 的消息,消息内容为 message  
}

# 3. 事件消息

该接口主要用于访客和座席之间的一些事件消息传递,用于增加用户体验

/**
 * 发送事件通知消息,消息内容不能大于4K
 *
 * 通话中的其他成员会收到 {@link JRTCGuestCallback.onNotifyMessageReceived:fromUserId: onNotifyMessageReceived} 或 {@link JRTCAgentCallback.onNotifyMessageReceived:fromUserId: onNotifyMessageReceived} 回调
 * @param notifyMessage 事件通知实体对象
 * @param userId  指定成员的用户ID,传 nil 即给通话中全部成员发送通知消息
 * @return 接口调用结果
 * - true: 接口调用成功
 * - false: 接口调用异常
 */
- (bool)sendNotifyMessage:(JRTCNotifyMessage *)notifyMessage toUserId:(NSString *__nullable)userId;

事件消息回调

/**
 * 收到事件通知消息回调
 *
 * 通话中的访客和座席可分别调用 {@link JRTCGuest.sendNotifyMessage:toUserId: sendNotifyMessage} 和 {@link JRTCAgent.sendNotifyMessage:toUserId: sendNotifyMessage} 接口给通话中的指定成员或全体成员发送通知消息,接收消息的成员会收到此回调,由此获取消息具体信息。
 * @param notifyMessage   事件通知实体类
 * @param fromUserId    发送方的用户ID
 */
- (void)onNotifyMessageReceived:(JRTCNotifyMessage *)notifyMessage fromUserId:(NSString *)fromUserId;

集成中常见的影响用户体验的事件消息如下,也是我们 Windows 座席插件已经集成的事件消息:

  • 当访客进入后台,视频画面静止,需要通知座席,如果对端座席是我们提供的 Windows 插件,该事件会在插件提示;

示例代码:

// 监听app前后台切换事件
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationEnterForeGround:) name:UIApplicationWillEnterForegroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];

- (void)applicationEnterForeGround:(NSNotification *)notify {
    //应用回到前台
    JRTCNotifyMessage *notifyMessage = [JRTCNotifyMessage new];
    notifyMessage.eventCode = C21_DEVICE_BACK_FOREGROUND;
    notifyMessage.desc = @"应用进入前台";
    [guest sendNotifyMessage:notifyMessage toUserId:@"座席用户ID"];
}

- (void)applicationEnterBackground:(NSNotification *)notify {
    JRTCNotifyMessage *notifyMessage = [JRTCNotifyMessage new];
    notifyMessage.eventCode = C21_DEVICE_ENTER_BACKGROUND;
    notifyMessage.desc = @"应用进入后台";
    [guest sendNotifyMessage:notifyMessage toUserId:@"座席用户ID"];
}
// JRTCAgentCallback
- (void)onNotifyMessageReceived:(JRTCNotifyMessage *)notifyMessage fromUserId:(NSString *)fromUserId {
    //先过滤是访客端发送过来的消息
    if ([fromUserId isEqualToString: guestParticipant.userId]) {
        //判断事件码
        if (notifyMessage.eventCode == C21_DEVICE_ENTER_BACKGROUND) {
            //访客端进入后台
        } else if (notifyMessage.eventCode == C21_DEVICE_BACK_FOREGROUND) {
            //访客端回到前台
        }
    }
}
  • 当访客收到系统来电,座席端听不到访客声音,需要通知座席,如果对端座席是我们提供的 Windows 插件,该事件会在插件提示;

示例代码:

// SDK 提供了 JRTCSystemPhone 模块用于监听系统来电
- (void)onSystemPhoneStateChanged:(SystemPhoneState)newState oldState:(SystemPhoneState)oldState {
    if ([self.engine getCallState] != CallStateTalking) {
        return;
    }
    JRTCNotifyMessage *notifyMessage = [JRTCNotifyMessage new];
    switch (newState) {
        case SystemPhoneStateIdle:
            notifyMessage.eventCode = C22_SYSTEM_PHONE_IDLE;
            notifyMessage.desc = @"系统通话状态空闲";
            break;
        case SystemPhoneStateRing:
            notifyMessage.eventCode = C22_SYSTEM_PHONE_RING;
            notifyMessage.desc = @"收到系统来电";
            break;
        case SystemPhoneStateOffhook:
            notifyMessage.eventCode = C22_SYSTEM_PHONE_TALKING;
            notifyMessage.desc = @"系统通话中";
            break;
        default:
            return;
    }
    NSDictionary *dic = @{@"newState": @(newState), @"oldState": @(oldState)};
    NSString *extra = [JRTCJson objToJson:dic];
    notifyMessage.extra = extra;
    [guest sendNotifyMessage:notifyMessage toUserId:@"座席用户ID"];
}
// JRTCAgentCallback
- (void)onNotifyMessageReceived:(JRTCNotifyMessage *)notifyMessage fromUserId:(NSString *)fromUserId {
    //先过滤是访客端发送过来的消息
    if ([fromUserId isEqualToString: guestParticipant.userId]) {
        //判断事件码
        if (notifyMessage.eventCode == C22_SYSTEM_PHONE_RING) {
            //访客端收到系统来电
        } else if (notifyMessage.eventCode == C22_SYSTEM_PHONE_TALKING) {
            //访客端系统通话中
        } else if (notifyMessage.eventCode == C22_SYSTEM_PHONE_IDLE) {
            //访客端系统通话结束
        }
    }
}
  • 当访客端出现音频异常或者视频异常,需要通知座席,如果对端座席是我们提供的 Windows 插件,该事件会在插件提示;

示例代码:

//JRTCMediaDeviceCallback
- (void)videoError:(NSString *)error {
    JRTCNotifyMessage *message = [[JRTCNotifyMessage alloc] init];
    message.eventCode = C21_AUDIO_ERROR_CALLBACK;
    message.desc = @"音频设备异常";
    message.extra = error;
    [guest sendNotifyMessage:message toUserId:@"座席用户ID"];
}

- (void)onCallVideoError:(NSString *)error {
    JRTCNotifyMessage *message = [[JRTCNotifyMessage alloc] init];
    message.eventCode = C21_VIDEO_ERROR_CALLBACK;
    message.desc = @"视频设备异常";
    message.extra = error;
    [guest sendNotifyMessage:message toUserId:@"座席用户ID"];
}
// JRTCAgentCallback
- (void)onNotifyMessageReceived:(JRTCNotifyMessage *)notifyMessage fromUserId:(NSString *)fromUserId {
    //先过滤是访客端发送过来的消息
    if ([fromUserId isEqualToString: guestParticipant.userId]) {
        //判断事件码
        if (notifyMessage.eventCode == C21_AUDIO_ERROR_CALLBACK) {
            //访客端音频异常
        } else if (notifyMessage.eventCode == C21_VIDEO_ERROR_CALLBACK) {
            //访客端视频异常
        }
    }
}
  • 当访客端出现内存不足时可能会引发一些异常,需要通知座席,如果对端座席是我们提供的 Windows 插件,该事件会在插件提示;

示例代码:

//JRTCMediaDeviceCallback
- (void)onMemoryAvailable:(double)memorySize {
    NSString* tipString;
    if (memorySize < 300) {
        tipString = @"剩余内存低,已不足300M";
    } else if (memorySize < 200) {
        tipString = @"剩余内存紧张,已不足200M";
    } else if (memorySize < 100) {
        tipString = @"内存已严重不足,已不足100M,可能影响软件正常使用";
    } else {
        return;
    }
    JRTCNotifyMessage *message = [[JRTCNotifyMessage alloc] init];
    message.eventCode = C21_MEMORY_LOW;
    message.desc = tipString;
    [guest sendNotifyMessage:message toUserId:@"座席用户ID"];
}
// JRTCAgentCallback
// JRTCAgentCallback
- (void)onNotifyMessageReceived:(JRTCNotifyMessage *)notifyMessage fromUserId:(NSString *)fromUserId {
    //先过滤是访客端发送过来的消息
    if ([fromUserId isEqualToString: guestParticipant.userId]) {
        //判断事件码
        if (notifyMessage.eventCode == C21_MEMORY_LOW) {
            //访客端内存低提示
        }
    }
}
  • 其他事件用户可以自行定义,只要座席端和访客端自行协议好就行,自定义事件码范围159xxx(即159000~159999)****。