iOS IM即时通讯小结:WebSocket

参考网站

即时通讯网

大牛博客
IM 即时通讯技术在多应用场景下的技术实现,以及性能调优

iOS即时通讯,从入门到“放弃”?

前言:要自己实现 IM 吗?

最近有项目涉及到聊天,Leader 决定要自己来实现 IM,不采用第三方的,像融云、环信等。其实,从心里我是拒绝的,因为作为一个IM的小白来说,一片空白,并且我们技术团队并没有很熟悉IM技术的人员,基本上算是从零开始,第三方的已经很成熟了,技术服务也很成熟完善了,相对于目前情况来说,对公司来说是最合适不过的了,时间金钱成本也是最合适的了,但是 Leader 已经决定了,要我们自己实现,以后还有项目中要用到,还想做一个 SDK 到时候开放,像 RongCloud 似的,呵呵,只是暂时说一下,先解决眼下的事情,也是一个锻炼学习的机会,第三方虽好,也不收费,但是在以后的某个时段,用户量达到一定量的时候,就需要 Money 了,毕竟都不是慈善机构,都要盈利的,有能力的话,最好是自己做了,定制型也强,想怎么玩就怎么玩,但这期间会遇到各种各样的问题困难,因为没有多少有价值的参考,很多东西都需要自己去摸索,需要浪费很多的时间精力。

用什么?

传输协议,TCP or UDP?

参考:
移动端IM/推送系统的协议选型:UDP还是TCP?

聊天协议?

协议名称 协议特点 第三方类库 优点 缺点
Socket 原生 Socket CocoaAsyncSocket 数据量小,性能高,扩展性比较强,比较知名的App如微信、QQ都基于此设计私有协议 开发量比较大,对开发者能力要求也比较高(没有发现连接时拼接参数的API)
WebSocket 基于 Socket 封装,传输通讯协议 SocketRocket(facebook)、Socket.IO-Client-Swift 同上 同上
XMPP 应用层的聊天协议 XMPPFramework 优点:协议开源,可拓展性强,在各个端(包括服务器)有各种语言的实现,开发者接入方便; 表现力弱、有太多冗余信息、流量大,
MQTT 同上 MQTTKit 协议简单,流量小,订阅+推送模式,适合滴滴、Uber实时获取位置 不适合于 IM 开发 ,适合用于推送,订阅
私有协议 一般都是基于 Socket 或 WebSocket 封装的协议 安全系数高,不容易被破解,主流 App 使用的方式

地址链接

CocoaAsyncSocket
SocketRocket
XMPPFramework
MQTTKit

Socket.IO-Client-Swift

Socket.io 功能非常强大,相对于上面的几个库,功能和 API 都这几个库要丰富完善的多;
Socket.io将 WebSocket 和轮询 (Polling)机制以及其它的实时通信方式封装成了通用的接口,并且在服务端实现了这些实时机制的相应代码。

注:
不过Socket.IO 对于 Swift 应该没有什么问题,OC 要做一些适配,还有版本的问题,主要是 Socket.IO 的SWIFT_VERSION 版本可能和当前工程的 SWIFT_VERSION 版本不匹配,或者是当前 Xcode 的版本已经不支持 Socket.IO 的 SWIFT_VERSION 等。不兼容的话,修改比较麻烦,OC要做一下适配,在之前我也有使用过,遇到过一些问题,在之前的文章中也简单介绍过。

最终就目前情况看,选择先使用 SocketRocket,功能和 API 比较简单,基于 SocketRocket 封装实现 Socket 的连接,监听,断开,重连等功能.

使用相关问题

1. WebSocket连接总是断开

  1. 连接总是断开,报这个错,code:1001,reason:Stream end encountered,wasClean:0,sendData:sendPing
    这个原因是因为,后台心跳检测一定时间内,服务端没有收到客户端发送的消息,就默认断开了与客户端的连接。

解决方法:

定时向服务单发送约定好的信息,心跳检测或者 sendPing 保证连接通畅(我自己理解的)。

- (void)dispatch_SourceTimerMethod
{
    //0.创建队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    //1.创建GCD中的定时器
    /*
     第一个参数:创建source的类型 DISPATCH_SOURCE_TYPE_TIMER:定时器
     第二个参数:0
     第三个参数:0
     第四个参数:队列
     */
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    
    //2.设置时间等
    /*
     第一个参数:定时器对象
     第二个参数:DISPATCH_TIME_NOW 表示从现在开始计时
     第三个参数:间隔时间 GCD里面的时间最小单位为 纳秒
     第四个参数:精准度(表示允许的误差,0表示绝对精准)
     */
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, HeartTime * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
    
    //3.要调用的任务
    dispatch_source_set_event_handler(timer, ^{
        NSLog(@"GCD-----%@",[NSThread currentThread]);
//        [self heartBeatData];
        [self sendPing];
    });
    
    //4.开始执行
    dispatch_resume(timer);
    
    //
    self.dispatch_SourceTimer = timer;
    
    // 需要取消的话:
//    dispatch_source_cancel(self.dispatch_SourceTimer);
//    此处注意一定要强引用定时器 ,否则定时器执行到 } 后将会被释放,无定时效果。
//    GCD定时器时间非常精准,最小的定时时间可以达到1纳秒,所以用在非常精确的定时场合。
}

/// PingPong
- (void)sendPing
{
    if (self.socket) {
        // 只有 SR_OPEN 开启状态才能调 send 方法啊,不然要崩
        if(self.socket.readyState==SR_OPEN) {
            NSLog(@"************Ping**************");
            NSString *pingMsg = @"ping";
            NSData *pingData = [pingMsg dataUsingEncoding:NSUTF8StringEncoding];
            [self.socket sendPing:pingData];

//            [self.socket sendPing:nil];
        }else{
            NSLog(@"连接未打开");
        }
    }
}

崩溃
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid State: Cannot call send: until connection is open'

连接未打开时,发送数据时就会崩溃,发送数据前要判断 Socket 的连接状态。

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

推荐阅读更多精彩内容

  • IM 的实现方式 使用第三方 IM 服务 在国内有很多的 IM 第三方服务商,底层协议基本上都是基于 TCP 的,...
    腾飞tengfei阅读 3,145评论 1 18
  • 即时通讯(Instant Messenger,简称IM)软件多是基于TCP/IP和UDP进行通讯的,TCP/IP和...
    xh_0129阅读 3,396评论 2 26
  • 生命力最顽强的植物──地衣 地衣绝对称得上是生命力最顽强的植物了,据试验,它能忍受70°左右的高温而不死亡,在零下...
    kitty_b21a阅读 310评论 0 0
  • 作者戚泽明 来源首席故事官CSO 作者 戚泽明:故事学院创始人&首席故事官,多位行业第一CEO的演讲设计师 ※本篇...
    Sting阅读 1,317评论 0 8
  • 1工作 按时完成工作。很不幸遇到了船拖班的问题,有的问题就怕是遇到了死结,每个人都觉得没有责任。客户觉得你没有按时...
    赵永奇_e0b9阅读 118评论 0 0