实现自定义信令

  • Android

更新时间不可用

了解 1v1 私密房三方信令方案在不同平台上的自定义信令方式,包括接入流程、关键配置和平台差异。

对于使用三方信令服务构建 1v1 私密房的开发者,在集成声网 CallAPI 后,还需要基于使用的三方信令服务实现一个自定义的信令管理类,来实现 1v1 私密房场景中的信令管理和消息收发等功能。本文以环信为例,展示如何将三方信令服务封装为可以与 CallAPI 搭配使用的自定义信令管理类。

注意

由于自定义的信令管理类基于三方信令 SDK 实现,且只实现了 CallAPI 需要的信令协议和消息收发功能,本文步骤及示例仅供参考,不保证其可用性和完整性。

示例项目

声网基于环信即时通讯 SDK 实现了一个信令管理类 CallEasemobSignalClient,你可以下载体验或参考源码。

前提条件

开始前,请确保满足如下前提条件:

实现步骤

1. 创建自定义信令管理类

以环信为例,创建一个 CallEasemobSignalClient 类,用来初始化并管理自定义的信令服务。

其中,CallBaseSignalClient 是一个基类,实现了 ISignalClient 的 addListener 和 removeListener 方法。

Kotlin
// 定义基于环信的自定义信令类 CallEasemobSignalClient
class CallEasemobSignalClient(
    private val context: Context,
    private val appKey: String,
    private val userId: Int = 0
): ISignalClient, CallBaseSignalClient() {
    // 此处省略其他初始化变量或参数
    init {
        val options = EMOptions()
        options.appKey = appKey
        // 调用环信 SDK 的 API 初始化环信信令服务
        EMClient.getInstance().init(context, options)
    }
}

2. 实现登录和登出等基本操作

由于 CallAPI 中不包含信令的连接状态,业务层还需要维护环信的状态。你可以参考如下代码,调用环信的这些方法在 CallEasemobSignalClient 中实现相关能力:

  • login:登录环信信令服务
  • logout:登出环信信令服务
  • renewToken:更新 Token
Kotlin
public fun login(completion: ((success: Boolean) -> Unit)?) {
    // 实现登录操作
}

public fun logout() {
    // 实现登出操作
}

public fun renew(token: String) {
    // 实现更新 Token 操作
}

// 此处省略其他业务层代码

3. 实现消息发送

调用环信 SDK 的代码实现消息发送功能。如下示例代码展示如何通过环信的 sendMessage 方法实现发送消息。

Kotlin
override fun sendMessage(
    userId: String,
    message: String,
    completion: ((AGError?) -> Unit)?
) {
    if (userId.isEmpty() || userId == "0") {
        val errorStr = "sendMessage fail, invalid userId[$userId]"
        completion?.invoke(AGError(errorStr, -1))
        return
    }
    innerSendMessage(userId, message, completion)
}

private fun innerSendMessage(
    userId: String,
    message: String,
    completion: ((AGError?) -> Unit)?
) {
    if (userId.isEmpty()) {
        completion?.invoke(AGError("send message fail! roomId is empty", -1))
        return
    }
    val options = PublishOptions()
    options.setChannelType(RtmConstants.RtmChannelType.USER)
    val startTime = System.currentTimeMillis()

    // `content` 为要发送的文本内容,`toChatUsername` 为对方的账号。
    val msg = EMMessage.createTextSendMessage(message, userId)
    // 会话类型:单聊为 EMMessage.ChatType.Chat
    msg.chatType = EMMessage.ChatType.Chat
    msg.deliverOnlineOnly(true)
    // 发送消息时可以设置 `EMCallBack` 的实例,获得消息发送的状态。可以在该回调中更新消息的显示状态。例如消息发送失败后的提示等等。
    msg.setMessageStatusCallback(object : EMCallBack {
        override fun onSuccess() {
            // 发送消息成功
            runOnUiThread { completion?.invoke(null) }
        }

        override fun onError(code: Int, error: String) {
            // 发送消息失败
            runOnUiThread { completion?.invoke(AGError(error, code)) }
        }

        override fun onProgress(progress: Int, status: String) {}
    })
    // 发送消息
    EMClient.getInstance().chatManager().sendMessage(msg)
}

4. 实现消息收发回调

由于消息是在回调中接收的,我们还需要注册相关的消息回调。下列示例代码展示如何通过环信 SDK 的 EMMessageListener 实现消息的接收和处理。

Kotlin
// ---------------- EMMessageListener ----------------
EMClient.getInstance().chatManager().addMessageListener(this)
override fun onMessageReceived(messages: MutableList<EMMessage>?) {
    runOnUiThread {
        messages?.forEach {
            val body = it.body as EMTextMessageBody
            listeners.forEach {
                it.onMessageReceive(body.message)
            }
        }
    }
}

5. (可选)实现网络状态回调

定义一个 ICallEasemobSignalClientListener 类,用于实现网络状态回调。对网络状态进行判断,可以使业务层更准确地识别和处理异常情况,从而提高系统的稳定性和效率。

Kotlin
// ---------------- EMConnectionListener ----------------
EMClient.getInstance().addConnectionListener(this)
override fun onConnected() {
    isConnected = true
}

override fun onDisconnected(errorCode: Int) {
    isConnected = false
}

后续步骤

完成自定义的信令管理类后,你可以在业务层中使用该类。参考如下文档使用该类和 CallAPI 共同搭建 1v1 私密房或秀场转 1v1: