Starscream 是一个符合规范的 WebSocket (RFC 6455) 客户端库,使用 Swift 语言编写。
它的 Objective-C 版本可以在这里找到:Jetfire
首先要做的是导入框架。请参阅安装说明,了解如何将框架添加到您的项目中。
import Starscream
导入后,您可以打开与 WebSocket 服务器的连接。请注意,最好将 socket
设置为属性,这样它就不会在设置后立即被释放。
socket = WebSocket(url: URL(string: "ws://:8080/")!)
socket.delegate = self
socket.connect()
连接成功后,我们需要实现一些委托方法。
当客户端连接到服务器后,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 协议并设置额外的委托,例如: 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()
还有一点:您可以通过通知监听套接字连接和断开连接。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.disconnect()
可以通过指定超时时间(以毫秒为单位)来强制关闭套接字。超时时间为零也会立即关闭套接字,而无需等待服务器。
socket.disconnect(forceTimeout: 10, closeCode: CloseCode.normal.rawValue)
返回套接字是否已连接。
if socket.isConnected {
// do cool stuff.
}
您还可以使用您自己的自定义标头覆盖默认的 websocket 标头,如下所示
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 证书锁定。
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
bool 值决定是使用证书进行验证还是使用公钥。如果选择 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
如果您的应用程序正在传输已压缩、随机或其他不可压缩的数据,则应禁用压缩。
可以指定在调用委托方法时使用的自定义队列。默认情况下使用 DispatchQueue.main
,因此所有委托方法调用都在主线程上运行。重要的是要注意,所有 WebSocket 处理都在后台线程上完成,只有在修改队列时才会更改委托方法调用。实际处理始终在后台线程上进行,不会暂停您的应用程序。
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/框架支持。要在目标为 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
框架已经使用共享方案进行了设置。
您可以使用 Homebrew 使用以下命令安装 Carthage
$ brew update
$ brew install carthage
要使用 Carthage 将 Starscream 集成到您的 Xcode 项目中,请在您的 Cartfile
中指定它
github "daltoniam/Starscream" >= 3.0.2
首先查看 安装文档,了解如何安装 Rogue。
要安装 Starscream,请在您创建 rogue 文件的目录中运行以下命令。
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)
]
只需获取框架(通过 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
。
高级委托的行为与更简单的委托类似,但提供有关连接和传入帧的一些其他信息。
socket.advancedDelegate = self
在大多数情况下,您不需要额外的信息,应该使用普通委托。
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 upgrade 请求和响应返回时被调用。
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 证书锁定。在 watchOS 上设置的所有这些值都将不起作用。SSLCiphers
。Starscream 在 Apache v2 许可证下获得许可。