Starscream 是一个符合 WebSocket (RFC 6455) 协议的 Swift 客户端库。
它的 Objective-C 版本在这里:Jetfire
首先需要导入 framework。请查看安装说明,了解如何将 framework 添加到你的项目中。
import Starscream
导入后,你可以打开到 WebSocket 服务器的连接。请注意,最好将 socket
设置为属性,这样它才不会在设置后立即被释放。
socket = WebSocket(url: URL(string: "ws://:8080/")!)
socket.delegate = self
socket.connect()
连接之后,我们需要实现一些 delegate 方法。
当客户端连接到服务器时,会立即调用 websocketDidConnect。
func websocketDidConnect(socket: WebSocketClient) {
print("websocket is connected")
}
当客户端与服务器断开连接时,会立即调用 websocketDidDisconnect。
func websocketDidDisconnect(socket: WebSocketClient, error: Error?) {
print("websocket is disconnected: \(error?.localizedDescription)")
}
当客户端从连接接收到文本帧时,会调用 websocketDidReceiveMessage。
func websocketDidReceiveMessage(socket: WebSocketClient, text: String) {
print("got some text: \(text)")
}
当客户端从连接接收到二进制帧时,会调用 websocketDidReceiveData。
func websocketDidReceiveData(socket: WebSocketClient, data: Data) {
print("got some data: \(data.count)")
}
当客户端从连接接收到 pong 响应时,会调用 websocketDidReceivePong。你需要实现 WebSocketPongDelegate 协议并设置一个额外的 delegate,例如:socket.pongDelegate = self
func websocketDidReceivePong(socket: WebSocketClient, data: Data?) {
print("Got pong! Maybe some data: \(data?.count)")
}
或者你可以使用闭包。
socket = WebSocket(url: URL(string: "ws://:8080/")!)
//websocketDidConnect
socket.onConnect = {
print("websocket is connected")
}
//websocketDidDisconnect
socket.onDisconnect = { (error: Error?) in
print("websocket is disconnected: \(error?.localizedDescription)")
}
//websocketDidReceiveMessage
socket.onText = { (text: String) in
print("got some text: \(text)")
}
//websocketDidReceiveData
socket.onData = { (data: Data) in
print("got some data: \(data.count)")
}
//you could do onPong as well.
socket.connect()
还有一点:你可以通过通知监听 socket 的连接和断开连接。 Starscream 会发布 WebsocketDidConnectNotification
和 WebsocketDidDisconnectNotification
。你可以通过访问通知 userInfo
中的 WebsocketDisconnectionErrorKeyName
找到导致断开连接的 Error
。
writeData 方法提供了一种简单的方式来向服务器发送 Data
(二进制)数据。
socket.write(data: data) //write some Data over the socket!
writeString 方法与 writeData 相同,但发送的是文本/字符串。
socket.write(string: "Hi Server!") //example on how to write text over the socket!
writePing 方法与 write 相同,但发送的是 ping 控制帧。
socket.write(ping: Data()) //example on how to write a ping control frame over the socket!
writePong 方法与 writePing 相同,但发送的是 pong 控制帧。
socket.write(pong: Data()) //example on how to write a pong control frame over the socket!
Starscream 会自动响应收到的 ping
控制帧,所以你不需要手动发送 pong
。
但是,如果出于某种原因你需要控制这个过程,你可以通过禁用 respondToPingWithPong
来关闭自动 ping
响应。
socket.respondToPingWithPong = false //Do not automaticaly respond to incoming pings with pongs.
在大多数情况下,你不需要这样做。
disconnect 方法会执行你期望的操作并关闭 socket。
socket.disconnect()
返回 socket 是否已连接。
if socket.isConnected {
// do cool stuff.
}
你还可以使用你自己的自定义 header 覆盖默认的 WebSocket header,如下所示
var request = URLRequest(url: URL(string: "ws://:8080/")!)
request.timeoutInterval = 5
request.setValue("someother protocols", forHTTPHeaderField: "Sec-WebSocket-Protocol")
request.setValue("14", forHTTPHeaderField: "Sec-WebSocket-Version")
request.setValue("Everything is Awesome!", forHTTPHeaderField: "My-Awesome-Header")
let socket = WebSocket(request: request)
你的服务器在连接到 WebSocket 时可能使用不同的 HTTP 方法
var request = URLRequest(url: URL(string: "ws://:8080/")!)
request.httpMethod = "POST"
request.timeoutInterval = 5
let socket = WebSocket(request: request)
如果你需要指定协议,只需将其添加到 init 中
//chat and superchat are the example protocols here
socket = WebSocket(url: URL(string: "ws://:8080/")!, protocols: ["chat","superchat"])
socket.delegate = self
socket.connect()
socket = WebSocket(url: URL(string: "ws://:8080/")!, protocols: ["chat","superchat"])
//set this if you want to ignore SSL cert validation, so a self signed SSL certificate can be used.
socket.disableSSLCertValidation = true
Starscream 也支持 SSL Pinning。
socket = WebSocket(url: URL(string: "ws://:8080/")!, protocols: ["chat","superchat"])
let data = ... //load your certificate from disk
socket.security = SSLSecurity(certs: [SSLCert(data: data)], usePublicKeys: true)
//socket.security = SSLSecurity() //uses the .cer files in your app's bundle
你可以加载证书的 Data
blob,或者如果你有想要使用的公钥,可以使用 SecKeyRef
。usePublicKeys
布尔值决定是使用证书进行验证还是使用公钥。如果选择了 usePublicKeys
,则会自动从证书中提取公钥。
要使用 SSL 加密连接,你需要告诉 Starscream 你的服务器支持的密码套件。
socket = WebSocket(url: URL(string: "wss://:8080/")!, protocols: ["chat","superchat"])
// Set enabled cipher suites to AES 256 and AES 128
socket.enabledSSLCipherSuites = [TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
如果你不知道你的服务器支持哪些密码套件,你可以尝试使用 SSL Labs 对其进行测试并查看结果。
Starscream 支持压缩扩展 (RFC 7692)。默认情况下启用压缩,但是只有在服务器也支持的情况下才会使用压缩。你可以通过 .enableCompression
属性启用或禁用压缩。
socket = WebSocket(url: URL(string: "ws://:8080/")!)
socket.enableCompression = false
如果你的应用程序传输的是已经压缩的、随机的或其他不可压缩的数据,则应禁用压缩。
可以在调用 delegate 方法时指定自定义队列。默认情况下使用 DispatchQueue.main
,因此所有 delegate 方法调用都在主线程上运行。重要的是要注意,所有 WebSocket 处理都在后台线程上完成,只有在修改队列时才会更改 delegate 方法调用。实际处理始终在后台线程上,不会暂停你的应用程序。
socket = WebSocket(url: URL(string: "ws://:8080/")!, protocols: ["chat","superchat"])
//create a custom queue
socket.callbackQueue = DispatchQueue(label: "com.vluxe.starscream.myapp")
查看 examples 目录中的 SimpleTest 项目,了解如何设置与 WebSocket 服务器的简单连接。
Starscream 适用于 iOS 7/OSX 10.9 或更高版本。建议使用 iOS 8/10.10 或更高版本以获得 CocoaPods/framework 支持。 要在以 iOS 7 为目标的项目中使用 Starscream,你必须将所有 Swift 文件直接包含在你的项目中。
查看 cocoapods.org 上的 Get Started 选项卡。
要在你的项目中使用 Starscream,请将以下 'Podfile' 添加到你的项目
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
use_frameworks!
pod 'Starscream', '~> 3.0.2'
然后运行
pod install
查看 Carthage 文档,了解如何添加安装。Starscream
framework 已经设置了共享 scheme。
你可以使用 Homebrew 使用以下命令安装 Carthage
$ brew update
$ brew install carthage
要使用 Carthage 将 Starscream 集成到你的 Xcode 项目中,请在你的 Cartfile
中指定它
github "daltoniam/Starscream" >= 3.0.2
首先查看 安装文档,了解如何安装 Rogue。
要在你创建 rogue 文件的目录中安装 Starscream,请运行以下命令。
rogue add https://github.com/daltoniam/Starscream
接下来,打开 libs
文件夹并将 Starscream.xcodeproj
添加到你的 Xcode 项目。完成后,在你的 "Build Phases" 中,将 Starscream.framework
添加到你的 "Link Binary with Libraries" 阶段。请确保将 libs
文件夹添加到你的 .gitignore
文件中。
Swift Package Manager 是一种用于自动化 Swift 代码分发的工具,它已集成到 swift
编译器中。
设置好 Swift 包后,将 Starscream 添加为依赖项就像将其添加到 Package.swift
的 dependencies
值一样简单。
dependencies: [
.Package(url: "https://github.com/daltoniam/Starscream.git", majorVersion: 3)
]
只需获取 framework(通过 git submodule 或其他包管理器)。
将 Starscream.xcodeproj
添加到你的 Xcode 项目。完成后,在你的 "Build Phases" 中,将 Starscream.framework
添加到你的 "Link Binary with Libraries" 阶段。
如果你在 OSX 应用程序中或在物理 iOS 设备上运行此程序,你需要确保将 Starscream.framework
添加到你的应用程序包中。 为此,在 Xcode 中,通过单击蓝色项目图标并选择侧边栏中“Targets”标题下的应用程序目标来导航到目标配置窗口。 在该窗口顶部的选项卡栏中,打开“Build Phases”面板。 展开“Link Binary with Libraries”组,然后添加 Starscream.framework
。 单击面板左上角的 + 按钮,然后选择“New Copy Files Phase”。 将此新阶段重命名为“Copy Frameworks”,将“Destination”设置为“Frameworks”,并分别添加 Starscream.framework
。
高级 delegate 的作用与更简单的 delegate 相同,但提供了有关连接和传入帧的一些其他信息。
socket.advancedDelegate = self
在大多数情况下,你不需要额外的信息,应该使用普通的 delegate。
func websocketDidReceiveMessage(socket: WebSocketClient, text: String, response: WebSocket.WSResponse) {
print("got some text: \(text)")
print("First frame for this message arrived on \(response.firstFrame)")
}
func websocketDidReceiveData(socket: WebSocketClient, data: Date, response: WebSocket.WSResponse) {
print("got some data it long: \(data.count)")
print("A total of \(response.frameCount) frames were used to send this data")
}
这些方法在发送 HTTP 升级请求和返回响应时调用。
func websocketHttpUpgrade(socket: WebSocketClient, request: CFHTTPMessage) {
print("the http request was sent we can check the raw http if we need to")
}
func websocketHttpUpgrade(socket: WebSocketClient, response: CFHTTPMessage) {
print("the http response has returned.")
}
SSLCiphers
、disableSSLCertValidation
或 SSL pinning。在 watchOS 上设置的所有这些值都将不起作用。SSLCiphers
。Starscream 在 Apache v2 许可证下获得许可。