iOS WebSocket(STOMP协议)使用对接

本片我们说下WebSocket,之前项目中有几个轮询的情况,使用基于http协议的接口,每隔几秒调用一下,感觉有点浪费资源。Http1.0默认是短连接,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接客户端主动请求,请求过后关闭,这样每隔几秒钟都要去进行三次握手,请求打开-关闭操作很浪费资源。Http1.1之后,默认使用长连接,用以保持连接特性,虽然可以使用Http的长连接来实现但是也有弊端总会造成双方资源的浪费,还有也牵扯H5浏览器,所以经过调研,觉得使用WebSocket来处理轮询的接口。
首先大家要知道什么是协议呢?我们只有了解了网络协议才能对我们接下来的内容理解有帮助,才不会迷茫,那么我们通过一张图来说明下


你不懂我,我不懂你

这就是两个人不在同一频道,各自说各自的,也不懂的对方的,协议可以说是规则。

网络协议:计算机双方必须共同遵从的一组约定。如怎么样建立连接、怎么样互相识别等。只有遵守这个约定,计算机之间才能相互通信交流。它的三要素是:语法、语义、时序。

首先我们先来了解几个概念:

Http协议:HTTP属于应用层协议,HTTP的长连接和短连接本质上是TCP长连接和短连接。
TCP协议:TCP协议属于传输层,TCP协议是可靠的、面向连接的。主要解决如何在IP层之上可靠地传递数据包,使得网络上接收端收到发送端所发出的所有包,并且顺序与发送顺序一致。TCP连接的建立依靠“三次握手”,而释放则需要“四次握手”。
IP协议:IP协议属于网络层,主要解决网络路由和寻址问题。
WebSocket协议:也是基于TCP的长连接,目的就是解决网络传输中的双向通信的问题,就是取代Http在双向通信场景下的使用,而且它的实现方式有些也是基于HTTP的(WS的默认端口是80和443),WebSocket协议有两部分组成:握手和数据传输。Websocket是一个持久化的协议,相对于HTTP这种是非持久的协议。Http协议是被动性的,也就是只能客户端发起。
Http协议双向通讯解决方案:

1.轮询(polling),轮询就会造成对网络和通信双方的资源的浪费,且非实时。
2.长轮询,客户端发送一个超时时间很长的Request,服务器hold住这个连接,在有新数据到达时返回Response,相比#1,占用的网络带宽少了,其他类似。
3.长连接,这里讲的其实是HTTP的长连接,本质上还是Request/Response消息对,仍然会造成资源的浪费、实时性不强等问题。
*长连接短连接操作过程
短连接的操作步骤是:
建立连接——数据传输——关闭连接...建立连接——数据传输——关闭连接
长连接的操作步骤是:
建立连接——数据传输...(保持连接)...数据传输——关闭连接
上面我们对一些协议做了了解。

以上的使用Http方案会有弊端,这里我们使用WebSocket协议来替代轮询的
*还有一点需要说明的地方就是WebSocket与Socket是没什么关系的,WebSocket协议和Http协议是在应用层,二Socket是对TCP/IP 协议的封装,也就是只是接口(类似于得底层的封装),让你在使用的时候更方便操作。

到这里我们对网络七层概念、及各个协议在哪个层和他们之间的协同工作原理有了了解。这样才会让我们去使用它们的时候会更高效。

*我们借用知乎上大佬的例子来理解下WebSocket执行工作原理:

----首先,被动性,当服务器完成协议升级后(HTTP->Websocket),服务端就可以主动推送信息给客户端啦。所以上面的情景可以做如下修改。
客户端:啦啦啦,我要建立Websocket协议,需要的服务:chat,Websocket协议版本:17(HTTP Request)
服务端:ok,确认,已升级为Websocket协议(HTTP Protocols Switched)
客户端:麻烦你有信息的时候推送给我噢。。
服务端:ok,有的时候会告诉你的。
服务端:balabalabalabala
服务端:balabalabalabala
服务端:哈哈哈哈哈啊哈哈哈哈
服务端:笑死我了哈哈哈哈哈哈哈
就变成了这样只需要经过一次HTTP请求,就可以做到源源不断的信息传送了。(在程序设计中,这种设计叫做回调,即:你有信息了再来通知我,而不是我傻乎乎的每次跑来问你)这样的协议解决了同步有延迟,而且还非常消耗资源的这种情况。

WebSocket协议有很多种
这边我们使用的是STOMP协议,STOMP定义了客户端和服务器之间以Frame进行同行,Frame的格式为:

COMMAND
header1:value1
header2:value2

Body^@
COMMAND分为CONNECT、SEND、SUBSCRIBE、UNSUBSCRIBE、BEGIN、COMMIT、ABORT、ACK、NACK、DISCONNECT这几种。COMMAND之后下一行紧跟着的是头部的键值对,之后加入一条空行,空行之后为body,即传递的消息实体。
本文的核心内容:通俗点stomp协议就是(本人亲自Debug获取,绝对通俗易懂):
\x0A 16进制是\n
\x00 16进制是0
COMMAND + \x0A + 循环添加传递的headerdic参数(key+ : + value + \x0A )循环完后+\x0A + 若果有body需要加body + \x00
之后再utf-8编码

COMMAND可以为:CONNECT、SEND、SUBSCRIBE、UNSUBSCRIBE、BEGIN、COMMIT、ABORT、ACK、NACK、DISCONNECT、CONNECTED、ERROR、MESSAGE、RECEIPT

其实我们也可以自己定义规则类似于STOMP的协议,只要前后端等定义相同的规则,按照所定义的规则实现,统一解析一样就可以。

iOS客户端处理WebSocket可以使用第三方库jetfireSocketRocket,但是要想处理STOMP协议或者其他协议的就要自己写个实现类,来处理拼接、解析逻辑。这里我们先来看下基于SocketRocket的实现STOMP协议WebSocket的流程:

流程图

1.打开请求URL
2.得到回调webSocketDidOpen
3.连接Connect,发送连接消息
核心发送消息代码,不管事要连接还是要处理发送各种Command都需要使用:

 private func sendFrame(command: String?, header: [String: String]?, body: AnyObject?) {
        if socket?.readyState == .OPEN {
            var frameString = ""
            if command != nil {
                frameString = command! + "\n"
            }
            
            if let header = header {
                for (key, value) in header {
                    frameString += key
                    frameString += ":"
                    frameString += value
                    frameString += "\n"
                }
            }
            
            if let body = body as? String {
                frameString += "\n"
                frameString += body
            } else if let _ = body as? NSData {
                
            }
            
            if body == nil {
                frameString += "\n"
            }
            
            frameString += StompCommands.controlChar
            
            if socket?.readyState == .OPEN {
                socket?.send(frameString)
            } else {
                print("no socket connection")
                if let delegate = delegate {
                    DispatchQueue.main.async(execute: {
                        delegate.stompClientDidDisconnect(client: self)
                    })
                    
                    
                }
            }
        }
    }

仔细看下这段代码你会觉得跟我之前说的通俗规则是不是一样呢?可以对比下。
4.发送后就是等着服务端回调给我们消息,不过也可能是失败的消息.
5.连接完成后基本操作实现就是send和subscribe
6.如果不用的时候可以取消连接disConnect
之前网上找了好多第三方库都是说可以实现Stomp协议,但是我使用后都不可以,最后亲身测试一下两个是完全可以的。通过验证也得出了上边的协议规则。
下边是github上的两个实现库
WebsocketStompKitStompClientLib
也可以使用pod ZMBase(Swift)或者OTBase(OC),里边抽出了实现的类

pod 'ZMBase', '~> 0.1.1'
pod 'OTBase', '~> 0.1.1'

这里整理了一个包含iOS(OC、Swift)、Android的实现Demo,如果需要请点击。
感谢大家阅读!喜欢的点个赞、关注一波!

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

推荐阅读更多精彩内容

  • 1. webSocket介绍1.1. 轮询1.2. 长链接1.3. websocket 2.STOMP传输协议介绍...
    JimmyOu阅读 31,719评论 2 12
  • 什么是WebSocket? WebSocket是html5开始提供的一种全双工网络通信协议,全双工是指WebSoc...
    c梦2019阅读 2,674评论 0 0
  • 一、WebSocket是什么? WebSocket 是一种网络通信协议。RFC6455定义了它的通信标准。 Web...
    dingFY阅读 260评论 0 1
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,523评论 28 53
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,181评论 4 8