iOS 上的 WebSocket 框架 Starscream
Starscream实现Websocket通讯
1.Starscream 简介
2.Starscream 使用
2.1 Starscream基本使用
2.2 Starscream高阶使用
2.2.1 判断是否连接
2.2.2 自定义头文件
2.2.3 自定义HTTP方法
2.2.4 协议
2.2.5 自签名 SSL
2.2.5.1 SSL引脚
2.2.5.2 SSL密码套件
2.2.6 压缩扩展
2.2.7 自定义队列
2.2.8 高级代理
3.Starscream 使用Demo
1.Starscream 简介
Starscream的特征:
Conforms to all of the base Autobahn test suite.
Nonblocking. Everything happens in the background, thanks to GCD.
TLS/WSS support.
Compression Extensions support (RFC 7692)
Simple concise codebase at just a few hundred LOC.
什么是websocket:
WebSocket protocol 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信(full-duplex)。
在 WebSocket API,浏览器和服务器只需要要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
HTTP 第一次出现是 1991 年,它设计为一种请求/响应式的通讯机制。Web 浏览器用这种机制工作良好,用户请求 web 页,服务器返回内容。但某些时候,需要有新数据时不经过用户请求就通知用户——也就是,服务器推。
HTTP 协议无法很好地解决推模型。在 websocket 出现前,web 服务通过一系列浏览器刷新机制来实现推模型,但效率无法让人满意。
webSocket 实现了服务端推机制。新的 web 浏览器全都支持 WebSocket,这使得它的使用超级简单。通过 WebSocket 能够打开持久连接,大部分网络都能轻松处理 WebSocket 连接。
WebSocket 通常应用在某些数据经常性或频繁改变的场景。例如 Facebook 中的 web 通知、Slack 中的实时聊天、交易系统中的变化的股票价格
socket通讯过程:
集成Websocket:
开发中推荐使用Starscream框架。通过pod 方式导入:
pod 'Starscream'
1
Starscream 使用swift版本为4.2
2.Starscream 使用
2.1 Starscream基本使用
import UIKit
import Starscream
@objc public protocol DSWebSocketDelegate: NSObjectProtocol{
/**websocket 连接成功*/
optional func websocketDidConnect(sock: DSWebSocket)
/**websocket 连接失败*/
optional func websocketDidDisconnect(socket: DSWebSocket, error: NSError?)
/**websocket 接受文字信息*/
func websocketDidReceiveMessage(socket: DSWebSocket, text: String)
/ **websocket 接受二进制信息*/
optional func websocketDidReceiveData(socket: DSWebSocket, data: NSData)
}
public class DSWebSocket: NSObject,WebSocketDelegate {
var socket:WebSocket!
weak var webSocketDelegate: DSWebSocketDelegate?
//单例
class func sharedInstance() -> DSWebSocket
{
return manger
}
static let manger: DSWebSocket = {
return DSWebSocket()
}()
//MARK:- 链接服务器
func connectSever(){
socket = WebSocket(url: NSURL(string: 你的URL网址如:ws://192.168.3.209:8080/shop))
socket.delegate = self
socket.connect()
}
//发送文字消息
func sendBrandStr(brandID:String){
socket.writeString(brandID))
}
//MARK:- 关闭消息
func disconnect(){
socket.disconnect()
}
//MARK: - WebSocketDelegate
//客户端连接到服务器时,websocketDidConnect将被调用。
public func websocketDidConnect(socket: WebSocket){
debugPrint("连接成功了: \(error?.localizedDescription)")
webSocketDelegate?.websocketDidConnect!(self)
}
//客户端与服务器断开连接后,将立即调用 websocketDidDisconnect。
public func websocketDidDisconnect(socket: WebSocket, error: NSError?){
debugPrint("连接失败了: \(error?.localizedDescription)")
webSocketDelegate?.websocketDidDisconnect!(self, error: error)
}
//当客户端从连接获取一个文本框时,调用 websocketDidReceiveMessage。
//注:一般返回的都是字符串
public func websocketDidReceiveMessage(socket: WebSocket, text: String){
debugPrint("接受到消息了: \(error?.localizedDescription)")
webSocketDelegate?.websocketDidReceiveMessage!(self, text: text)
}
public func websocketDidReceiveData(socket: WebSocket, data: NSData){
debugPrint("data数据")
webSocketDelegate?.websocketDidReceiveData!(self, data: data)
}
}
编写一个pong框架
writePong方法与writePing相同,但发送一个pong控制帧。
socket.write(pong: Data()) //example on how to write a pong control frame over the socket!
1
Starscream会自动响应传入的ping 控制帧,这样你就不需要手动发送 pong。
但是,如果出于某些原因需要控制这个 prosses,你可以通过禁用 respondToPingWithPong 来关闭自动 ping 响应。
socket.respondToPingWithPong=false//Do not automaticaly respond to incoming pings with pongs.
1
当客户端从连接获得一个pong响应时,调用 websocketDidReceivePong。 你需要实现WebSocketPongDelegate协议并设置一个额外的委托,例如: socket.pongDelegate = self
funcwebsocketDidReceivePong(socket: WebSocketClient, data: Data?) {
print("Got pong! Maybe some data: (data?.count)")
}
2.2 Starscream高阶使用
2.2.1 判断是否连接
if socket.isConnected {
// do cool stuff.
}
2.2.2 自定义头文件
你可以使用自己自定义的web socket标头覆盖默认的web socket标头,如下所示:
var request = URLRequest(url: URL(string: "ws://localhost: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)
2.2.3 自定义HTTP方法
你的服务器在连接到 web socket时可能会使用不同的HTTP方法:
var request = URLRequest(url: URL(string: "ws://localhost:8080/")!)
request.httpMethod = "POST"
request.timeoutInterval = 5
let socket = WebSocket(request: request)
2.2.4 协议
如果需要指定协议,简单地将它的添加到 init:
//chat and superchat are the example protocols here
socket = WebSocket(url: URL(string: "ws://localhost:8080/")!, protocols: ["chat","superchat"])
socket.delegate = self
socket.connect()
2.2.5 自签名 SSL
socket = WebSocket(url: URL(string: "ws://localhost: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
2.2.5.1 SSL引脚
Starscream还支持SSL固定。
socket = WebSocket(url: URL(string: "ws://localhost: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 小区,否则你可以使用 SecKeyRef,如果你想要使用 public 键。 usePublicKeys bool是使用证书进行验证还是使用 public 键。 如果选择 usePublicKeys,将自动从证书中提取 public 密钥。
2.2.5.2 SSL密码套件
要使用SSL加密连接,你需要告诉小红你的服务器支持的密码套件。
socket = WebSocket(url: URL(string: "wss://localhost: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
2.2.6 压缩扩展
Starscream支持压缩扩展( RFC 7692 )。 默认情况下,压缩是启用的,但是只有当服务器支持压缩时才会使用压缩。 你可以通过 .enableCompression 属性启用或者禁用压缩:
socket = WebSocket(url: URL(string: "ws://localhost:8080/")!)
socket.enableCompression = false
如果应用程序正在传输已经压缩。随机或者其他uncompressable数据,则应禁用压缩。
2.2.7 自定义队列
调用委托方法时可以指定自定义队列。 默认使用 DispatchQueue.main,因此使所有委托方法调用都在主线程上运行。 重要的是要注意,所有 web socket处理都是在后台线程上完成的,只有修改队列时才更改委托方法。 实际的处理总是在后台线程上,不会暂停你的应用程序。
socket = WebSocket(url: URL(string: "ws://localhost:8080/")!, protocols: ["chat","superchat"])
//create a custom queue
socket.callbackQueue = DispatchQueue(label: "com.vluxe.starscream.myapp")
2.2.8 高级代理
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.")
————————————————
原文链接:https://blog.csdn.net/kyl282889543/article/details/100655005