博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS WebSocket
阅读量:7105 次
发布时间:2019-06-28

本文共 4403 字,大约阅读时间需要 14 分钟。

WebSocket是什么

WebSocket是用于HTML的协议,可以在单个TCP连接进行全双工通信。不同于HTTP协议被动性,每次客户端先发起request,服务端再响应respon。而WebSocket是通过TCP有一个“握手”的连接后,客户端和服务端都可以向对方发送数据,类似socket的数据通信。WebSocket解决了HTTP非持久连接的问题,比通过轮询和长连接的方式更加高效、节省资源。

iOS WebSocket的使用

  • 使用的框架:
  • 封装一个单例:
@interface WebSocketHelper : NSObject+ (instancetype)helper;//开启连接- (void)connectWithURLString:(NSString *)urlString;//发送数据- (void)sendData:(id)data;//关闭连接- (void)closeWebSocket;@end#import "WebSocketHelper.h"#import "SocketRocket/SRWebSocket.h"@interface WebSocketHelper ()
{ NSTimer * _heartBeatTimer; NSTimeInterval _reConnectTime;}@property (nonatomic, strong) SRWebSocket *socket;@end@implementation WebSocketHelper+ (instancetype)helper { static WebSocketHelper *h = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ h = [[self alloc]init]; }); return h;}- (void)connectWithURLString:(NSString *)urlString { if (!urlString.length) { return; } if (self.socket) { return; } ///后台的websocket的地址 NSURLRequest *urlReq = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]; self.socket = [[SRWebSocket alloc]initWithURLRequest:urlReq]; self.socket.delegate = self; //开始连接 [self.socket open]; }#pragma mark - SRWebSocketDelegate- (void)webSocketDidOpen:(SRWebSocket *)webSocket { NSLog(@"连接成功"); _reConnectTime = 0; //开启心跳 心跳是发送pong的消息 我这里根据后台的要求发送data给后台 [self creatHeartBeat];}///连接失败- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error { NSLog(@"连接失败");}//被一方关闭连接了- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean{ NSLog(@"连接断开了");}///接收服务器的pong消息- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(nullable NSData *)pongData{ NSString *reply = [[NSString alloc] initWithData:pongData encoding:NSUTF8StringEncoding]; NSLog(@"接收到pong消息:%@",reply); }- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message { //收到服务器发过来的数据 NSLog(@"接收到发过来的消息%@",message); }#pragma mark - custom methods- (void)closeWebSocket { if (self.socket){ //断开连接 [self.socket close]; self.socket = nil; //断开连接时销毁心跳 [self cancelHeartBeat]; }}//重连,当发现客户端和服务端断开连接时发起重连- (void)reConnect{ [self closeWebSocket]; //超过一分钟就不再重连 所以只会重连5次 2^5 = 64 if (_reConnectTime > 64) { return; } dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_reConnectTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.socket open]; NSLog(@"重连"); }); //重连时间2的指数级增长 if (_reConnectTime == 0) { _reConnectTime = 2; }else{ _reConnectTime *= 2; }}//初始化心跳- (void)creatHeartBeat{ dispatch_async(dispatch_get_main_queue(), ^{ [self cancelHeartBeat]; __weak typeof(self) weakSelf = self; //心跳设置为3分钟,NAT超时一般为5分钟 self->_heartBeatTimer = [NSTimer scheduledTimerWithTimeInterval:3*60 repeats:YES block:^(NSTimer * _Nonnull timer) { NSLog(@"heart"); //发送心跳 [weakSelf sendData:@"heart"]; }]; [[NSRunLoop currentRunLoop]addTimer:self -> _heartBeatTimer forMode:NSRunLoopCommonModes]; }); }//取消心跳- (void)cancelHeartBeat{ dispatch_async(dispatch_get_main_queue(), ^{ if (self->_heartBeatTimer) { [self->_heartBeatTimer invalidate]; self->_heartBeatTimer = nil; } });}///发送数据- (void)sendData:(id)data { dispatch_queue_t queue = dispatch_queue_create("send.queue", NULL); __weak typeof(self) weakSelf = self; dispatch_async(queue, ^{ if (weakSelf.socket != nil) { // 只有 SR_OPEN 开启状态才能调 send 方法,不然要崩 if (weakSelf.socket.readyState == SR_OPEN) { NSError *error = nil; [weakSelf.socket sendData:data error:&error]; // 发送数据 } else if (weakSelf.socket.readyState == SR_CONNECTING) { NSLog(@"正在连接中"); [self reConnect]; } else if (weakSelf.socket.readyState == SR_CLOSING || weakSelf.socket.readyState == SR_CLOSED) { // websocket 断开了,调用 reConnect 方法重连 [self reConnect]; } } else { NSLog(@"没网络,发送失败"); } });}@end复制代码

注意:调用的sendPing、sendData方法之前,必须判断当前scoket是否连接,如果不是连接状态,否则程序会crash。

参考资料

转载地址:http://gmchl.baihongyu.com/

你可能感兴趣的文章
第五章:浏览器的嗅探和特征侦测
查看>>
去年这时候又辞退了一个老油条,不知道他现在是否在开公司了,可以对比一下混工资的水平...
查看>>
将Vi打造成一个IDE(适合新手和懒人)
查看>>
Solaris目录结构
查看>>
shell自动监控重启tomcat脚本
查看>>
邮箱验证js
查看>>
安装samba软件包失败,求解?
查看>>
企业要什么样的“云”
查看>>
组策略部署软件之四:部署Service pack和补丁
查看>>
【开篇导航】—Entity Framework实例详解
查看>>
SQL Server 环形缓冲区(Ring Buffer) -- SQL Server的Ring Buffer类型
查看>>
OutCallReceiver
查看>>
网络的理解2
查看>>
python中的map、filter、reduce函数
查看>>
Exchange 2016 之分层通讯簿
查看>>
【Java例题】4.3 3. 使用Gauss消元法求解n元一次方程组的根,
查看>>
SSH 认证
查看>>
MySQL学习总结(二)
查看>>
Android 开发环境搭建(MyEclipse+Android sdk+ADT环境)
查看>>
金蝶系统(V12),防火墙需要开启的端口
查看>>