socketRocket 封装,添加重连机制,block回调

一、简单介绍

SocketRocket是一个WebSocket客户端(WebSocket是适用于Web应用的下一代全双工通讯协议,被成为“Web的TCP”,它实现了浏览器与服务器的双向通信),采用Object-C编写。SocketRocket遵循最新的WebSocket规范RFC 6455

这里是开发者描述的其一些特性/设计:

支持TLS (wss)。
使用NSStream/CFNetworking。
使用ARC。
采用并行架构。大部分的工作由后端的工作队列(worker queues)完成。
基于委托编程。

SocketRocket支持iOS 4.x系统(应该也可以运行于OS X),不需要任何UI包依赖。详细信息可以查看此文介绍

socketRocket 传送门

二、如何使用

  • socketRocket 支持pod,因此直接添加然后install,文件不多喔~

Paste_Image.png
  • 简单使用socketRocket实现通信的话,只需要用那么几个API就行了

1.创建一个请求:(有多种方法)

- (id)initWithURLRequest:(NSURLRequest *)request;

2.遵守并指定代理

@property (nonatomic, weak) id <SRWebSocketDelegate> delegate;

3.打开连接加载请求

- (void)open;

4.关闭连接

- (void)close;

5.发送消息

// Send a UTF8 String or Data.
- (void)send:(id)data;
// Send Data (can be nil) in a ping message.
- (void)sendPing:(NSData *)data;

6.监听socketRocket是通过代理方法来实现的

@protocol SRWebSocketDelegate <NSObject>
// message will either be an NSString if the server is using text
// or NSData if the server is using binary.
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message;
@optional
- (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;
// Return YES to convert messages sent as Text to an NSString. Return NO to skip NSData -> NSString conversion for Text messages. Defaults to YES.
- (BOOL)webSocketShouldConvertTextFrameToString:(SRWebSocket *)webSocket;
  • 注意:发送的参数必须跟后台商量,保持一致才能发送,不然一发送就自动关闭连接的

三、封装隔离

  • 为什么要封装

  • 我就按上面的6个步骤就可以实现通信了,不用考虑太多的逻辑处理,但我还是觉得有点麻烦,我希望一句代码就搞定,使用代理就实现不了。

  • 第三方框架必须要封装隔离,不然Facebook突然改了这个框架的API,那么你项目多次使用的话,改动工作量就非常大了。

  • 我需要它有个重连机制,如果连接失败或者系统异常原因导致连接关闭的话,它会自动重连,如果是用户手动关闭,则不需要重连,直到下次重新打开。

  • 封装思路

  • 需要单例工具类,管理socket的状态,当然状态是不允许外界修改,因此是readonly

  • 对外提供超时重连的时间,允许外界修改

  • 对外提供开启连接方法,使用block进行回调,不使用代理,实现一句代码创建并监听

  • 有开启必须有关闭连接的方法,同样使用block回调,告诉调用者关闭的状态码以及原因

  • 当然需要一个发送方法,参数模仿框架,传id类型就行

  • 封装后的API(.h文件)

自定义的枚举,socket状态,比框架多一个枚举是用户关闭

/**
 *  @author 孔凡列, 16-09-21 07:09:52
 *
 *  socket状态
 */
typedef NS_ENUM(NSInteger,FLSocketStatus){
    FLSocketStatusConnected,// 已连接
    FLSocketStatusFailed,// 失败
    FLSocketStatusClosedByServer,// 系统关闭
    FLSocketStatusClosedByUser,// 用户关闭
    FLSocketStatusReceived// 接收消息
};
/**
 *  @author 孔凡列, 16-09-21 07:09:52
 *
 *  消息类型
 */
typedef NS_ENUM(NSInteger,FLSocketReceiveType){
    FLSocketReceiveTypeForMessage,
    FLSocketReceiveTypeForPong
};

连接回调,成功连接后执行


/**
 *  @author 孔凡列, 16-09-21 08:09:06
 *
 *  连接回调
 */
@property (nonatomic,copy)FLSocketDidConnectBlock connect;

接收到socket消息的时候就会执行

/**
 *  @author 孔凡列, 16-09-21 08:09:06
 *
 *  接收消息回调
 */
@property (nonatomic,copy)FLSocketDidReceiveBlock receive;

连接或发送失败会执行

/**
 *  @author 孔凡列, 16-09-21 08:09:06
 *
 *  失败回调
 */
@property (nonatomic,copy)FLSocketDidFailBlock failure;

用户手动关闭或者系统关闭的时候会调用

/**
 *  @author 孔凡列, 16-09-21 08:09:06
 *
 *  关闭回调
 */
@property (nonatomic,copy)FLSocketDidCloseBlock close;

socket状态,一共有5个状态

/**
 *  @author 孔凡列, 16-09-21 08:09:28
 *
 *  当前的socket状态
 */
@property (nonatomic,assign,readonly)FLSocketStatus fl_socketStatus;

超时重连时间,默认一秒重连(框架没有,自己添加的)

/**
 *  @author 孔凡列, 16-09-21 08:09:40
 *
 *  超时重连时间,默认1秒
 */
@property (nonatomic,assign)NSTimeInterval overtime;

超时重连次数,默认5次(框架没有,自己添加的)

/**
 *  @author Clarence
 *
 *  重连次数,默认5次
 */
@property (nonatomic, assign)NSUInteger reconnectCount;

单例创建管理类,项目中唯一,方便管理

/**
 *  @author 孔凡列, 16-09-21 08:09:06
 *
 *  单例调用
 */
+ (instancetype)shareManager;

开启socket,block监听

/**
 *  @author 孔凡列, 16-09-21 08:09:16
 *
 *  开启socket
 *
 *  @param urlStr  服务器地址
 *  @param connect 连接成功回调
 *  @param receive 接收消息回调
 *  @param failure 失败回调
 */
- (void)fl_open:(NSString *)urlStr connect:(FLSocketDidConnectBlock)connect receive:(FLSocketDidReceiveBlock)receive failure:(FLSocketDidFailBlock)failure;

关闭socket,有两个状态,一个是用户关闭,一个是系统关闭

/**
 *  @author 孔凡列, 16-09-21 08:09:06
 *
 *  关闭socket
 *
 *  @param close 关闭回调
 */
- (void)fl_close:(FLSocketDidCloseBlock)close;

发送消息,可发送NSString 或者 NSData

/**
 *  @author 孔凡列, 16-09-21 08:09:25
 *
 *  发送消息,NSString 或者 NSData
 *
 *  @param data Send a UTF8 String or Data.
 */
- (void)fl_send:(id)data;

四、调用

1、开启连接并监听

   NSString *url = @"服务器给你的地址";
   [[FLSocketManager shareManager] fl_open:url connect:^{
        NSLog(@"成功连接");
    } receive:^(id message, FLSocketReceiveType type) {
        if (type == FLSocketReceiveTypeForMessage) {
            NSLog(@"接收 类型1--%@",message);
        }
        else if (type == FLSocketReceiveTypeForPong){
            NSLog(@"接收 类型2--%@",message);
        }
    } failure:^(NSError *error) {
        NSLog(@"连接失败");
    }];

2、发送消息

[[FLSocketManager shareManager] fl_send:@"hello world"];

3、关闭连接

[[FLSocketManager shareManager] fl_close:^(NSInteger code, NSString *reason, BOOL wasClean) {
        NSLog(@"code = %zd,reason = %@",code,reason);
    }];

五、总结

  • 使用block回调,用法只需要三步,监听都在同一个方法里面,方便管理,关键是看起来简单,用起来爽,而且不怕框架API修改

  • 有重连机制,连接失败或者系统异常原因导致关闭的就会自动重连,默认一秒就重连,如果调用者手动关闭就不重连,有最大重连次数,可自定义,默认5次

  • 实现部分的代码就拷贝上来了,喜欢的话就去clone吧,demo没有给服务器地址,实测没问题的

  • 一般socket开启后就不用关闭,此时作者封装的这个block是单例对象的,因此如果另一个控制器监听了接收block,那么前一个控制器就没办法监听接收,建议大家使用通知去实现,只需要在一个控制器去做监听,然后发通知,其他控制器监听这个通知就行,这样就可以实现整个项目多个控制器都能同时监听socket改变

gitHub地址 欢迎大家关注我,随时发干货,喜欢就给个star && like,有问题留言哟~~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,265评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,274评论 1 288
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,087评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,479评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,782评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,218评论 1 207
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,594评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,316评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,955评论 1 237
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,274评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,803评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,177评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,732评论 3 229
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,953评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,687评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,263评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,189评论 2 258

推荐阅读更多精彩内容