iOS 長(zhǎng)鏈接WebSocket應(yīng)用之SocketRocket
Facebook家的SocketRocket應(yīng)該是OC語(yǔ)言里針對(duì)WebSocket最好的框架啦剿另,因?yàn)闃I(yè)務(wù)需求,我們把應(yīng)用的部分請(qǐng)求更換成了長(zhǎng)鏈接,以下是使用總結(jié)。
至于為什么要使用WebSocket?當(dāng)然是為了與服務(wù)器更方便快捷地進(jìn)行通訊,不用每次請(qǐng)求都得客戶(hù)端先給服務(wù)器發(fā)一個(gè)Request舰始,然后等待服務(wù)器對(duì)應(yīng)的response;而可以由服務(wù)端決定什么時(shí)候給你推送什么消息咽袜,這點(diǎn)對(duì)于某些通信類(lèi)的功能模塊是很方便的丸卷。
如果你想深入了解下Websocket的原理,可以看這篇WebSocket 是什么原理询刹?為什么可以實(shí)現(xiàn)持久連接谜嫉?
接下來(lái)談?wù)刉ebSocket的使用,因?yàn)檎麄€(gè)SocketRocket就只有一個(gè).h和.m文件范抓,所以socket的使用也相對(duì)簡(jiǎn)單骄恶。
1.首先建造一個(gè)SocketRocketUtility單例以便整個(gè)項(xiàng)目使用WebSocket來(lái)通信
@implementationSocketRocketUtility
+(SocketRocketUtility *)instance{
staticSocketRocketUtility *Instance =nil;
staticdispatch_once_tonce;
dispatch_once(&once, ^{??
? Instance = [[SocketRocketUtility alloc]init];?
?}
}
2.然后創(chuàng)建一個(gè)Socket來(lái)建立通信
在.m文件中添加類(lèi)的Extension
@interfaceSocketRocketUtility()
@property(nonatomic,strong) SRWebSocket *socket;
@end
創(chuàng)建socket并建立連接
- (void) SRWebSocketOpen{
self.socket =[[SRWebSocket alloc] initWithURLRequest:[NSURLRequestrequestWithURL:[NSURLURLWithString:@"your string "]]];
self.socket.delegate =self;??
?[self.socket open];}
然后處理socket連接的結(jié)果,監(jiān)聽(tīng)連接是否成功的回調(diào)
#pragmamark - socket delegate
如果連接建立成功
- (void)webSocketDidOpen:(SRWebSocket *)webSocket {
//開(kāi)啟心跳
[selfinitHeartBeat];
if(webSocket ==self.socket) {
NSLog(@"************************** socket 連接成功************************** ");?
?}
?}
如果連接建立失敗
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError*)error {
if(webSocket ==self.socket) {
NSLog(@"************************** socket 連接失敗************************** ");
?? _socket =nil;//連接失敗就重連[selfreConnect];?? } }
這里有個(gè)心跳規(guī)則匕垫,其實(shí)一般的Websocket的第三方框架會(huì)自帶這個(gè)并不需要自己做特別處理僧鲁,只要與服務(wù)器商量好時(shí)間,定時(shí)地向服務(wù)器發(fā)送ping消息象泵,服務(wù)器會(huì)返回相應(yīng)地pong消息寞秃,表示我們的連接還在
- (void) initHeartBeat{?
heartBeat = [NSTimertimerWithTimeInterval:10target:selfselector:@selector(ping)? userInfo:nilrepeats:YES];?
[[NSRunLoopcurrentRunLoop] addTimer:heartBeat forMode:NSRunLoopCommonModes];
?}
這里用了NSTimer,所以要注意對(duì)應(yīng)所在線程的runloop偶惠;正常情況下春寿,將NSTimer添加到主線程的runloop中,為了確保這段代碼在主行程中執(zhí)行忽孽,我們添加一段宏
#define dispatch_main_async_safe(block)\if([NSThreadisMainThread]) {\? ? block();\}else{\dispatch_async(dispatch_get_main_queue(), block);\}
然后將上面的代碼改成
dispatch_main_async_safe(^{? ?? heartBeat = [NSTimertimerWithTimeInterval:10target:selfselector:@selector(ping) userInfo:nilrepeats:YES];? ? [[NSRunLoopcurrentRunLoop]addTimer:heartBeat forMode:NSRunLoopCommonModes];
})
具體的ping方法就是調(diào)用第三方框提供的方法
- (void) ping{if(self.socket.readyState == SR_OPEN){? [self.socket sendPing:nil]; }}
4.就是想服務(wù)器發(fā)送數(shù)據(jù)绑改,一般跟服務(wù)器通信傳遞的數(shù)據(jù)是json格式谢床,所以記得把之前字典里的信息以及服務(wù)器要求的一些相關(guān)字段轉(zhuǎn)換成json格式,然后send:
- (void)sendData{dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{if(weakself.socket !=nil) {
// 只有 SR_OPEN 開(kāi)啟狀態(tài)才能調(diào) send 方法啊厘线,不然要崩
if(weakself.socket.readyState == SR_OPEN) {? ? ?
?? ? ? [weakself.socket send:data];
// 發(fā)送數(shù)據(jù)
}elseif(weakself.socket.readyState == SR_CONNECTING) {? ?
?? ? ? ? ? ? ? [selfreConnect];? ? ? ? ? ??
? ? ? ? }elseif(weakself.socket.readyState == SR_CLOSING || weakself.socket.readyState == SR_CLOSED) {
// websocket 斷開(kāi)了识腿,調(diào)用 reConnect 方法重連[selfreConnect];??
? ? ? }?
?? }else{
//如果在發(fā)送數(shù)據(jù),但是socket已經(jīng)關(guān)閉造壮,可以在再次打開(kāi)[selfSRWebSocketOpen];
}
?});
}
5.接收服務(wù)器信息
#pragma mark - 收到的回調(diào)
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message? {
if(webSocket ==self.socket) {
NSLog(@"message:%@",message);
if(!message){
return;?
?? }
//收到的數(shù)據(jù)格式也是json格式的渡讼,可以用MJExtension里字典轉(zhuǎn)模型的方法更改為自定義的數(shù)據(jù)格式//這里要將接收到的消息專(zhuān)遞出去,可以用block或者通知的形式耳璧;個(gè)人偏好block一點(diǎn)
[selfhandleReceivedMessage:message];?
?? }
}
6.關(guān)閉Socket連接
最后可以選擇在合適的時(shí)候關(guān)閉長(zhǎng)連接
-(void)SRWebSocketClose{
if(self.socket){??
? [self.socket close];
self.socket =nil;
//斷開(kāi)連接時(shí)銷(xiāo)毀心跳
[selfdestoryHeartBeat];??
? }
}
0人點(diǎn)贊
作者:零度_不結(jié)冰
鏈接:http://www.reibang.com/p/322a399df503
來(lái)源:簡(jiǎn)書(shū)
著作權(quán)歸作者所有成箫。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處旨枯。