简介
WebSocket
规范定义了一种 API,可在网络浏览器和服务器之间建立“套接字”连接。
SocketRocket
是facebook
的开源框架,使在iOS,MAC,TV端使用WebSocket
技术成为可能。
前期准备
编译工具:xcode8.2.1
语言:swift3.1
系统环境:Mac OS
客户端
创建一个iOS工程
引入SocketRocket库
使用pod
集成SocketRocket
库。
不详细介绍,不了解的请参考文章在swift调用OC的第三方库
集成完毕项目结合如下图:
API分析
SocketRocket
暴露的接口并不多
首先看属性:
//设置代理
@property (nonatomic, weak) id <SRWebSocketDelegate> delegate;
//只读,当前处于的状态
typedef NS_ENUM(NSInteger, SRReadyState) {
SR_CONNECTING = 0, 连接状态
SR_OPEN = 1, 打开状态
SR_CLOSING = 2, 正在关闭状态
SR_CLOSED = 3, 已经关闭状态
};
@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;
开启关闭:
//打开连接,只能执行一次
- (void)open;
//关闭连接
- (void)close;
//关闭原因和code
- (void)closeWithCode:(NSInteger)code reason:(NSString *)reason;
// 发送消息给服务器(允许UTF8字符串或者Data)
- (void)send:(id)data;
//发送一个心跳消息ping,可以为参数可以为nil(用来确定客户端未丢失。)
- (void)sendPing:(NSData *)data;
协议:
//当使用open的时候,如果连接成功回调
- (void)webSocketDidOpen:(SRWebSocket *)webSocket;
//当服务器拒绝,或者发生错误的时候回调
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;
//服务器关闭的时候回调
- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean;
//服务器心跳回调
- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload;
// 当为yes,则将data转为string,no的时候不进行转换。
- (BOOL)webSocketShouldConvertTextFrameToString:(SRWebSocket *)webSocket;
写一个简单小Demo
,ws://echo.websocket.org
地址可以免费查看你的Demo
是否已经正常,返回值为发送的值
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服务器
系统环境:Mac OS
①使用brew install node
安装node
②创建一个自定义的文件夹,并且cd
进入本文件夹,使用命令行npm install ws
,npm install node-uuid
创建两个模块作为依赖。
这边出现的WARN不需要处理,也可以先npm init
来初始化,生成一个package.json,不过本示例不需要。
创建一个文件,命名为server_test.js
写一段简单的服务器Demo
,实现将前端传来的数据传回。
//导入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
端项目和服务器端简单的项目,以供参考!有误请留言,谢谢!