iOS--SocketRocket框架的使用及测试服务器的搭建

2,637 阅读4分钟

###什么是socket? Socket 其实并不是一个协议。它工作在 OSI 模型会话层(第5层),是为了方便大家直接使用更底层协议(一般是TCP 或 UDP )而存在的一个抽象层。Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API)。

20160526230432824.png
Socket通常也称作”套接字”,用于描述IP地址和端口,是一个通信链的句柄。网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket,一个Socket由一个IP地址和一个端口号唯一确定。应用程序通常通过”套接字”向网络发出请求或者应答网络请求。 Socket在通讯过程中,服务端监听某个端口是否有连接请求,客户端向服务端发送连接请求,服务端收到连接请求向客户端发出接收消息,这样一个连接就建立起来了。客户端和服务端也都可以相互发送消息与对方进行通讯,直到双方连接断开。

什么是WebSocket?

Websocket是应用层第七层上的一个应用层协议,它必须依赖 HTTP 协议进行一次握手 ,握手成功后,数据就直接从 TCP 通道传输,与 HTTP 无关了。 Websocket的数据传输是frame形式传输的,比如会将一条消息分为几个frame,按照先后顺序传输出去。这样做会有几个好处: 1 大数据的传输可以分片传输,不用考虑到数据大小导致的长度标志位不足够的情况。 2 和http的chunk一样,可以边生成数据边传递消息,即提高传输效率。

SocketRocket框架

使用cocoapods导入SocketRocket框架

platform :ios,"7.0"

target "WebScoketTest" do
pod 'SocketRocket'

end

框架并不开源,我们只能看到对外封装的一些方法。 一部分为SRWebSocket的初始化,以及连接,关闭连接,发送消息等方法。另一部分为SRWebSocketDelegate,其中包括一些回调:收到消息的回调,连接失败的回调,关闭连接的回调,收到pong的回调,是否需要把data消息转换成string的代理方法。

使用框架

点击下载例子 其中包括了一个简单的心跳,重连机制和websocket封装好的pingpong机制 部分代码:

D5EEF738-B9B9-411C-A065-3CCAF17F3B54.png

BBC96522-2A6E-4CC5-BD67-6150E6ABFF10.png
#####(1)什么是心跳?  简单的来说,心跳就是用来检测TCP连接的双方是否可用。那又会有人要问了,TCP不是本身就自带一个KeepAlive机制吗?  这里我们需要说明的是TCP的KeepAlive机制只能保证连接的存在,但是并不能保证客户端以及服务端的可用性.  我们客户端发起心跳Ping(一般都是客户端),假如设置在10秒后如果没有收到回调,那么说明服务器或者客户端某一方出现问题,这时候我们需要主动断开连接。  服务端也是一样,会维护一个socket的心跳间隔,当约定时间内,没有收到客户端发来的心跳,我们会知道该连接已经失效,然后主动断开连接。  国内移动无线网络运营商在链路上一段时间内没有数据通讯后, 会淘汰NAT表中的对应项, 造成链路中断。而国内的运营商一般NAT超时的时间为5分钟,所以通常我们心跳设置的时间间隔为3-5分钟。

(2)什么是pingpong机制?

2702646-6e51be4cf4ba7b11.jpg
  当服务端发出一个Ping,客户端没有在约定的时间内返回响应的ack,则认为客户端已经不在线,这时我们Server端会主动断开Scoket连接,并且改由APNS推送的方式发送消息。   同样的是,当客户端去发送一个消息,因为我们迟迟无法收到服务端的响应ack包,则表明客户端或者服务端已不在线,我们也会显示消息发送失败,并且断开Scoket连接。   还记得我们之前CocoaSyncSockt的例子所讲的获取消息超时就断开吗?其实它就是一个PingPong机制的客户端实现。我们每次可以在发送消息成功后,调用这个超时读取的方法,如果一段时间没收到服务器的响应,那么说明连接不可用,则断开Scoket连接

(3)什么是重连机制?

理论上,我们自己主动去断开的Scoket连接(例如退出账号,APP退出到后台等等),不需要重连。其他的连接断开,我们都需要进行断线重连。  一般解决方案是尝试重连几次,如果仍旧无法重连成功,那么不再进行重连。

webSocket服务端的实现

(1)安装Homebrew

终端运行:

// 链接1
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
(2)成功后,安装node

$ brew install node

(3)安装ws模块

$ npm install ws 此时如果出现错误

npm WARN enoent ENOENT: no such file or directory

可以使用$ npm init -f命令生成一下

(4)cd到下载的js文件路径下

执行$ node 文件名.js 此时运行下载的demo,试试看吧!