TSStarscream 3.1.1

TSStarscream 3.1.1

Anna TechSee 维护。



starscream

Starscream 是一个符合 WebSocket (RFC 6455) 规范的 Swift 客户端库。

其 Objective-C 对应版本可在以下位置找到:Jetfire

特点

  • 符合所有的 Autobahn 测试套件 的基础。
  • 非阻塞。所有操作都后台执行,归功于 GCD。
  • 支持 TLS/WSS。
  • 支持压缩扩展 (RFC 7692)
  • 代码库简洁精炼,仅数百行代码。

示例

首先需要导入框架。请参阅安装说明了解如何将框架添加到项目中。

import Starscream

导入之后,您可以打开到 WebSocket 服务器的连接。请注意,socket最好作为属性,这样在设置之后不会立即释放。

socket = WebSocket(url: URL(string: "ws://:8080/")!)
socket.delegate = self
socket.connect()

连接后,我们需要实现一些代理方法。

websocketDidConnect

当客户端连接到服务器时,websocketDidConnect 即将被调用。

func websocketDidConnect(socket: WebSocketClient) {
    print("websocket is connected")
}

websocketDidDisconnect

当客户端与服务器断开连接时,会立即调用websocketDidDisconnect。

func websocketDidDisconnect(socket: WebSocketClient, error: Error?) {
	print("websocket is disconnected: \(error?.localizedDescription)")
}

websocketDidReceiveMessage

当客户端从连接中获得文本帧时,会调用websocketDidReceiveMessage。

func websocketDidReceiveMessage(socket: WebSocketClient, text: String) {
	print("got some text: \(text)")
}

websocketDidReceiveData

当客户端从连接中获得二进制帧时,会调用websocketDidReceiveData。

func websocketDidReceiveData(socket: WebSocketClient, data: Data) {
	print("got some data: \(data.count)")
}

可选:websocketDidReceivePong (所需协议:WebSocketPongDelegate)

当客户端从连接中获得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发布WebsocketDidConnectNotificationWebsocketDidDisconnectNotification。您可以通过访问通知userInfo中的WebsocketDisconnectionErrorKeyName找到导致断开连接的错误Error

زیر antidepressants methods شما راهی ساده برای پردازش داده‌های سرور ارائه می‌دهد، اما چگونه می‌توانید داده‌ها را ارسال کنید؟

اطمینان‌بخشی یک فریم دوsetState

روش writeData داده‌های Data (دوające) ساده‌ای برای ارسال به سرور ارائه می‌دهد.

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 است، اما یک لاکتوس کنترلی را ارسال می‌کند.

socket.write(ping: Data()) //example on how to write a ping control frame over the socket!

编写一个pong帧

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)

isConnected

返回套接字是否已连接。

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)

自定义HTTP方法

服务器在连接websocket时可能会使用不同的HTTP方法。

var request = URLRequest(url: URL(string: "ws://:8080/")!)
request.httpMethod = "POST"
request.timeoutInterval = 5
let socket = WebSocket(request: request)

协议

如果您需要指定协议,可以简单地将其添加到初始化中。

//chat and superchat are the example protocols here
socket = WebSocket(url: URL(string: "ws://:8080/")!, protocols: ["chat","superchat"])
socket.delegate = self
socket.connect()

自签名SSL

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

SSL Pinning

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,或者如果您有一个要使用的公钥,您可以使用 SecKeyRefusePublicKeys 布尔值表示是否使用证书进行验证或使用公钥。如果选择 usePublicKeys,公钥将自动从证书中提取。

SSL 加密套件

要使用 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 实验室并检查结果。

压缩扩展

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")

示例项目

查看示例目录中的 SimpleTest 项目,了解如何设置简单的 WebSocket 服务器连接。

要求

Starscream 兼容 iOS 7/OSX 10.9 及以上版本。建议使用 iOS 8/10.10 或以上版本以支持 CocoaPods/框架。要使 Starscream 在针对 iOS 7 的项目中使用,你必须直接在项目中包含所有 Swift 文件。

安装

CocoaPods

查看cocoapods.org上的“入门”标签。

要在项目中使用 Starscream,请在项目中添加以下 'Podfile' 文件

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
use_frameworks!

pod 'Starscream', '~> 3.0.2'

然后运行

pod install

Carthage

查看如何在Carthage中添加和安装的文档。Starscream 框架已经配置了共享方案。

Carthage 安装

您可以使用以下命令使用 Homebrew 安装 Carthage

$ brew update
$ brew install carthage

要在 Xcode 项目中集成 Starscream 并使用 Carthage,请在您的 Cartfile 中指定它

github "daltoniam/Starscream" >= 3.0.2

Accio

查看如何添加 Accio 安装的 Accio 文档。

将以下内容添加到您的 Package.swift 中

.package(url: "https://github.com/daltoniam/Starscream.git", .upToNextMajor(from: "3.1.0")),

然后,将 Starscream 添加到您的 App targets 依赖,方法如下

.target(
    name: "App",
    dependencies: [
        "Starscream",
    ]
),

然后运行 accio update

Rogue

首先查阅 Rogue 的安装文档,了解如何安装 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 包管理器

Swift包管理器( Swift Package Manager)是一个自动化Swift代码分发的工具,并且与swift编译器集成。

一旦你的Swift包配置完成,将Starscream添加为依赖就像将它添加到Package.swiftdependencies值一样简单。

dependencies: [
    .Package(url: "https://github.com/daltoniam/Starscream.git", majorVersion: 3)
]

其他

只需简单地获取框架(无论是通过git子模块还是另一个包管理器)。

Starscream.xcodeproj添加到你的Xcode项目中。完成后,在“构建阶段”中,将Starscream.framework添加到“链接二进制与库”阶段。

添加复制框架阶段

如果你在一个OSX应用程序或真实iOS设备上运行此应用程序,需要确保将Starscream.framework包含在你的应用程序包中。为此,在Xcode中,通过单击蓝色的项目图标,然后在侧边栏的“目标”下选择应用程序目标,来访问目标配置窗口。在该窗口的顶部工具栏中,打开“构建阶段”面板。展开“链接二进制与库”组,并添加Starscream.framework。单击面板左上角的+按钮,并选择“新建复制文件阶段”。将此新阶段重命名为“复制框架”,将“目的地”设置为“框架”,并分别添加Starscream.framework

WebSocketAdvancedDelegate

高级代理行为与简单的代理相同,但提供有关连接和传入帧的一些额外信息。

socket.advancedDelegate = self

在大多数情况下,你不需要额外的信息,应使用标准代理。

websocketDidReceiveMessage

func websocketDidReceiveMessage(socket: WebSocketClient, text: String, response: WebSocket.WSResponse) {
	print("got some text: \(text)")
	print("First frame for this message arrived on \(response.firstFrame)")
}

websocketDidReceiveData

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")
}

websocketHttpUpgrade

这些方法在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.")
}

Swift版本

  • Swift 4.2 - 3.0.6

已知问题

  • WatchOS 没有CFNetwork的字符串常量来修改流的安全行为,它将使用默认的Foundation安全行为。这意味着WatchOS 不能使用 SSLCiphersdisableSSLCertValidation 或SSL固定。所有在watchOS上设置的这些值都将没有任何效果。
  • Linux没有安全框架,因此也无法使用SSL固定或SSLCiphers

待办事项

  • 添加单元测试 - 对Autobahn的本地WebSocket服务器

许可协议

Starscream的许可协议是Apache v2许可证。

联系方式

Dalton Cherry

Austin Cherry