使用 Swift 部署声网 Token 服务器

简介

使用声网平台时,如果你想为推流增加一层安全保障,可以添加一个 Token 服务。

本教程会教大家如何从运行声网 Token 服务器的 Web 服务中获取声网 token。

要想直接了解一个完整的 iOS app 如何通过特定的声网 token 服务器获取 token,点击查看 iOS 示例项目


前期准备


项目创建

可以阅读这篇文章查看如何创建 Token 服务器,该 GitHub 库包含帮大家快速创建 Token 服务器的所有代码。

完成 Token 服务器的创建之后,把它拉入应用程序中,本教程会示范怎么在 Swift 中做到这一点。


获取 Token

只有完整的 URL 才能访问 Token 服务。在我的例子中,该服务是在本地计算机上运行的,​​所以我访问的是 "http://localhost:8080/...",并且以 my-channel 作为频道名称、以 0 作为 userId。

如果你想在计算机上搭建服务器,但从 iOS 设备获取 Token,你可以使用 ngrok 之类的服务将请求路由到 localhost。

guard let tokenServerURL = URL(
    string: "http://localhost:8080/rtc/my-channel/publisher/uid/0/"
) else {
    return
}

接下来,我们需提出一个请求。我使用的是 Foundation 的 URLRequest将请求的 httpMethod 设成 GET,用 URLSession.shared.dataTask 创建任务,然后用 task.resume() 启动任务,如下所示:

var request = URLRequest(url: tokenServerURL, timeoutInterval: 10)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(
    with: request
) { data, response, err in
    // data task body here
}
task.resume()

我们可以在数据任务主体内部获取返回的 Token,可以这样写:

guard let data = data else {
    // No data, no token
    return
}
// parse response into json
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
// check that json has key "rtcToken"
let responseJSON = try? JSONSerialization.jsonObject(
    with: data, options: []
) as? [String: Any]
if let token = responseJSON?["rtcToken"] as? String {
    // Key "rtcToken" found in response, assigning to tokenToReturn
    print("the token is: \(token)")
}

当 Token 抵达我们的设备时,main 方法可能已经返回了,因此我在下面的完整示例中添加了 DispatchSemaphore,用来保留 main 方法直至获得响应。这样我们就可以直接从方法中返回 Token,但这样可能会造成阻塞,所以如非必要,不要在主线程上运行此代码。


保持连接状态

通过此方法提供的所有 Token 都有有效期限,Token 服务器可以设置它们的有效期限,如果要更改,可以将其设置为请求中发送的参数。

如果已连接的用户的 Token 将在 30 秒后过期,就会调用 AgoraRtcEngineDelegate 的回调,这是再次连接 Token 服务器并请求更新 Token 的一种比较好的办法,无须使用 AgoraRtcEngineKit.renewToken(:String) 断开与频道的连接就能命令 RTC 引擎更新 Token。


完整示例

import Foundation
import Dispatch

/// - Parameters:
///   - domain: Domain which is hosting the Agora Token Server (ie http://localhost:8080)
///   - channelName: Name of the channel the token will allow the user to access
///   - userId: User ID requesting to join the server. A value of 0 works for all users.
/// - Returns: A new token which will expire in 24 Hours, or however specified by the token server.
///            An empty string response means that this function has failed.
func fetchRTCToken(domain: String, channelName: String, userId: UInt = 0) -> String {
    // Construct the endpoint URL
    guard let tokenServerURL = URL(string: "\(domain)/rtc/\(channelName)/publisher/uid/\(userId)/") else {
        return ""
    }
    /// semaphore is used to wait for the request to complete, before returning the token.
    let semaphore = DispatchSemaphore(value: 0)
    var request = URLRequest(url: tokenServerURL, timeoutInterval: 10)
    request.httpMethod = "GET"
    var tokenToReturn = ""
    
    // Construct the GET request
    let task = URLSession.shared.dataTask(with: request) { data, response, err in
        defer {
            // Signal that the request has completed
            semaphore.signal()
        }
        guard let data = data else {
            // No data, no token
            return
        }
        let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
        if let responseDict = responseJSON as? [String: Any], let token = responseDict["rtcToken"] as? String {
            // Key "rtcToken" found in response, assigning to tokenToReturn
            tokenToReturn = token
        }
    }
    
    task.resume()
    
    // Waiting for signal found inside the GET request handler
    semaphore.wait()
    return tokenToReturn
}

将以上代码添加到项目中时,请务必确保使用其他两个参数(response 和 err),因为它们能确保你的 Token 服务器的响应的有效性,还能帮你调试 bug。

我们要使用 joinChannel 发送加入频道的请求,获取到 Token 之后,将 Token 和加入频道的请求一起发送(查看声网——使用 Token 加入频道)。

要想查看从服务器获取 token 并 Token 失效前刷新 token 的 iOS 完整运行示例,可以点击查看声网 iOS Swift 示例项目

上述项目中的 token 可以在声网 Token.swift 文件中获取和应用。

如果你已安装 Xcode,可以尝试在 Agora-Token-Swift 库中找到的 Agora-Swift-Token.playground 文件。你可以在自己的电脑上执行上述方法,查看从服务器中检索到的 token。


原文作者:Max Cobb
原文链接:https://www.agora.io/en/blog/connecting-to-agora-with-tokens-using-swift/
推荐阅读
相关专栏
SDK 教程
164 文章
本专栏仅用于分享音视频相关的技术文章,与其他开发者和声网 研发团队交流、分享行业前沿技术、资讯。发帖前,请参考「社区发帖指南」,方便您更好的展示所发表的文章和内容。