簡介
WebSocket
規(guī)范定義了一種 API,可在網(wǎng)絡瀏覽器和服務器之間建立“套接字”連接。
SocketRocket
是facebook
的開源框架,使在iOS鸣个,MAC羞反,TV端使用WebSocket
技術成為可能。
前期準備
編譯工具:xcode8.2.1
語言:swift3.1
系統(tǒng)環(huán)境:Mac OS
客戶端
創(chuàng)建一個iOS工程
引入SocketRocket庫
使用pod
集成SocketRocket
庫囤萤。
不詳細介紹昼窗,不了解的請參考文章在swift調(diào)用OC的第三方庫
集成完畢項目結合如下圖:
API分析
SocketRocket
暴露的接口并不多
首先看屬性:
//設置代理
@property (nonatomic, weak) id <SRWebSocketDelegate> delegate;
//只讀,當前處于的狀態(tài)
typedef NS_ENUM(NSInteger, SRReadyState) {
SR_CONNECTING = 0, 連接狀態(tài)
SR_OPEN = 1, 打開狀態(tài)
SR_CLOSING = 2, 正在關閉狀態(tài)
SR_CLOSED = 3, 已經(jīng)關閉狀態(tài)
};
@property (nonatomic, readonly) SRReadyState readyState;
//只讀涛舍,連接的URL
@property (nonatomic, readonly, retain) NSURL *url;
//只讀澄惊,接收到的http頭
@property (nonatomic, readonly) CFHTTPMessageRef receivedHTTPHeaders;
// 設置requestCookies,Web 服務器就可以使用這些信息來識別不同的用戶
@property (nonatomic, readwrite) NSArray * requestCookies;
初始化方法:
通過NSURLRequest
進行初始化:
-(id)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates;
-(id)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols;
-(id)initWithURLRequest:(NSURLRequest *)request;
通過NSURL
進行初始化
-(id)initWithURL:(NSURL *)url protocols:(NSArray *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates;
-(id)initWithURL:(NSURL *)url protocols:(NSArray *)protocols;
-(id)initWithURL:(NSURL *)url;
設置線程
//默認為主隊列富雅,兩個方法不能同時使用
- (void)setDelegateOperationQueue:(NSOperationQueue*) queue;
- (void)setDelegateDispatchQueue:(dispatch_queue_t) queue;
開啟關閉:
//打開連接掸驱,只能執(zhí)行一次
- (void)open;
//關閉連接
- (void)close;
//關閉原因和code
- (void)closeWithCode:(NSInteger)code reason:(NSString *)reason;
// 發(fā)送消息給服務器(允許UTF8字符串或者Data)
- (void)send:(id)data;
//發(fā)送一個心跳消息ping,可以為參數(shù)可以為nil(用來確定客戶端未丟失没佑。)
- (void)sendPing:(NSData *)data;
協(xié)議:
//當使用open的時候毕贼,如果連接成功回調(diào)
- (void)webSocketDidOpen:(SRWebSocket *)webSocket;
//當服務器拒絕,或者發(fā)生錯誤的時候回調(diào)
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;
//服務器關閉的時候回調(diào)
- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean;
//服務器心跳回調(diào)
- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload;
// 當為yes蛤奢,則將data轉為string鬼癣,no的時候不進行轉換。
- (BOOL)webSocketShouldConvertTextFrameToString:(SRWebSocket *)webSocket;
寫一個簡單小Demo
啤贩,ws://echo.websocket.org
地址可以免費查看你的Demo
是否已經(jīng)正常待秃,返回值為發(fā)送的值
class ViewController: UIViewController, SRWebSocketDelegate {
@IBOutlet weak var msgTextField: UITextField!
@IBOutlet weak var receiveLable: UILabel!
private var websocket: SRWebSocket?
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.reConnect()
}
@IBAction func sendMsgBtn(_ sender: Any) {
self.view.endEditing(true)
if let websoc = websocket {
websoc.send(self.msgTextField.text!)
}
}
private func reConnect() {
websocket?.delegate = nil
websocket?.close()
websocket = nil
websocket = SRWebSocket.init(urlRequest: URLRequest.init(url: URL.init(string: "ws://echo.websocket.org")!))
websocket?.delegate = self as SRWebSocketDelegate
websocket?.open()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
websocket?.delegate = nil
websocket?.close()
websocket = nil
}
// Implement agent
public func webSocket(_ webSocket: SRWebSocket!, didReceiveMessage message: Any!) {
if webSocket.readyState == .OPEN {
self.receiveLable.text = message as? String
}
}
func webSocket(_ webSocket: SRWebSocket!, didFailWithError error: Error!) {
print("\(error!.localizedDescription)")
}
func webSocketDidOpen(_ webSocket: SRWebSocket!) {
print("連接成功!")
}
func webSocket(_ webSocket: SRWebSocket!, didCloseWithCode code: Int, reason: String!, wasClean: Bool) {
print("連接關閉")
websocket = nil
}
func webSocket(_ webSocket: SRWebSocket!, didReceivePong pongPayload: Data!) {
}
@IBAction func closeSocketBtn(_ sender: Any) {
websocket?.delegate = nil
websocket?.close()
websocket = nil
}
}
服務器
上面使用的是一個簡單的測試服務器瓜晤,接下來我們自己搭建一個服務器用于有趣的測試锥余。
使用node搭建一個自己的Websocket服務器
系統(tǒng)環(huán)境:Mac OS
①使用brew install node
安裝node
②創(chuàng)建一個自定義的文件夾,并且cd
進入本文件夾腹纳,使用命令行npm install ws
,npm install node-uuid
創(chuàng)建兩個模塊作為依賴痢掠。
這邊出現(xiàn)的WARN不需要處理,也可以先npm init
來初始化,生成一個package.json嘲恍,不過本示例不需要足画。
創(chuàng)建一個文件,命名為server_test.js
寫一段簡單的服務器Demo
,實現(xiàn)將前端傳來的數(shù)據(jù)傳回佃牛。
//導入ws模塊
var webSocketServer = require('ws').Server
//用端口初始化一個對象
wss = new webSocketServer({port: 8181})
//連接中進行的操作
wss.on('connection', function (ws) {
console.log("client connected!")
ws.on("message", function (message) {
console.log(message)
ws.send(message)
})
})
啟動node
服務器
// /Users/nttdata/Desktop/Server/server_test.js是js路勁淹辞,開啟后不要關閉命令行工具
node /Users/nttdata/Desktop/Server/server_test.js
測試一下前后端是否暢通,請看圖:
OK俘侠!
附上iOS
端項目和服務器端簡單的項目象缀,以供參考!有誤請留言爷速,謝謝央星!