一。 前言:
WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——可以通俗的解释为服务器主动发送信息给客户端。
区别于MQTT、XMPP等聊天的应用层协议,它是一个传输通讯协议。它有着自己一套连接握手,以及数据传输的规范。
而本文要讲到的SRWebSocket就是iOS中使用websocket必用的一个框架,它是用Facebook提供的。
关于WebSocket起源与发展,是怎么由:轮询、长轮询、再到websocket的,可以看看冰霜这篇文章:
微信,QQ这类IM app怎么做——谈谈Websocket
关于SRWebSocket的API用法,可以看看楼主之前这篇文章:
iOS即时通讯,从入门到“放弃”?
二。 SRWebSocket的对外的业务流程:
首先贴一段SRWebSocket的API调用代码:
//初始化socket并且连接
- (void)connectServer:(NSString *)server port:(NSString *)port
{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@“ws://%@:%@”,server,port]]];
_socket = [[SRWebSocket alloc] initWithURLRequest:request];
_socket.delegate = self;
[_socket open];
}
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message
{
}
- (void)webSocketDidOpen:(SRWebSocket *)webSocket
{
}
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error
{
}
- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean
{
}
要简单使用起来,总共就4行代码,并且实现你需要的代理即可,整个业务逻辑非常简洁。
但是就这么几个对外的方法,SRWebSocket.m里面用了2000行代码来进行封装,那么它到底做了什么?我们接着往下看:
三。 SRWebSocket的初始化以及连接流程:
1首先我们初始化:
//初始化
- (void)_SR_commonInit;
{
//得到url schem小写
NSString *scheme = _url.scheme.lowercaseString;
//如果不是这几种,则断言错误
assert([scheme isEqualToString:@“ws”] || [scheme isEqualToString:@“http”] || [scheme isEqualToString:@“wss”] || [scheme isEqualToString:@“https”]);
_readyState = SR_CONNECTING;
_webSocketVersion = 13;
//初始化工作的队列,串行
_workQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
//给队列设置一个标识,标识为指向自己的,上下文对象为这个队列
dispatch_queue_set_specific(_workQueue, (__bridge void *)self, maybe_bridge(_workQueue), NULL);
//设置代理queue为主队列
_delegateDispatchQueue = dispatch_get_main_queue();
//retain主队列?
sr_dispatch_retain(_delegateDispatchQueue);
//读Buffer
_readBuffer = [[NSMutableData alloc] init];
//输出Buffer
_outputBuffer = [[NSMutableData alloc] init];
//当前数据帧
_currentFrameData = [[NSMutableData alloc] init];
//消费者数据帧的对象
_consumers = [[NSMutableArray alloc] init];
_consumerPool = [[SRIOConsumerPool alloc] init];
//注册的runloop
_scheduledRunloops = [[NSMutableSet alloc] init];
。。.。省略了一部分代码
}
会初始化一些属性:
包括对schem进行断言,只支持ws/wss/http/https四种。
当前socket状态,是正在连接,还是已连接、断开等等。
初始化工作队列,以及流回调线程等等。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !