介绍
当使用Agora平台时,为推流增加一层安全保障的方法是添加一个Token服务。
通过本教程,你将会学到如何从运行Agora Token服务器的Web服务中获取Agora token。
要想直接了解一个完整的iOS app如何通过特定的Agora token服务器获取token,点击查看 iOS示例项目。
要求
- 一个Agora开发者账户(参阅:注册声网Agora账户)
- 利用Swift进行iOS开发的基础知识
- 最新版本的Xcode(可参阅:Apple Xcode)
- 一个本地或远程的Agora token服务器(请参阅:Agora Token服务示例代码)
- 分别使用Agora macOS或iOS SDK的macOS或iOS app
项目创建
该GitHub仓库包含所有代码,能帮助你快速创建Token服务器。
完成Tokenfu服务器的创建之后,你需要把它拉入应用程序中。本教程会向你示范怎样在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服务器的响应有效,并能帮你调试任何问题。
在得到获取Token的方法后,你需要用joinChannel与加入频道的请求一起发送。
要想查看一个完整的iOS运行示例,即从服务器获取token并在到期时刷新token,可以点击这里查看声网iOS Swift示例项目。
上述项目中的token在AgoraToken.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/