摘自:www.jianshu.com/p/4d421f79e…
1. Socket 和 WebSocket 有哪些区别和联系?
就像Java和JavaScript,北大和北大青鸟,雷锋和雷峰塔一样,没有什么关系,除了在名字上沾亲带故的以外,就是两个完全不同的东西。
WebSocket
WebSocket一种在单个TCP连接上进行全双工通讯的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并被RFC7936所补充规范。WebSocket API也被W3C定为标准。——维基百科
背景 现在,很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的时间间隔(如每1秒)由客户端对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端。这种传统的模式带来很明显的缺点,即客户端需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
而比较新的技术去做轮询的效果是Comet。这种技术虽然可以双向通信,但依然需要反复发出请求。而且在Comet中,普遍采用的长链接,也会消耗服务器资源。 在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。 Websocket使用ws或wss的统一资源标志符,类似于HTTPS,其中wss表示在TLS之上的Websocket。如:
ws://example.com/wsapi
wss://secure.example.com/
Websocket使用和 HTTP 相同的 TCP 端口,可以绕过大多数防火墙的限制。默认情况下,Websocket协议使用80端口;运行在TLS之上时,默认使用443端口。
WebSocket出现的目的:即时通讯,替代HTTP轮询
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
(1)最初的轮询(polling)阶段
上图表明,客户端发送一个request,服务器不管有没有新消息,都会立即返回一个response,然后关闭连接,这次HTTP请求结束。请记住 Request = Response , 在HTTP1.0和HTTP1.1中都是这样,也就是说一个request只能有一个response对应。客户端需要不断执行这个请求过程(也就是轮询),查询服务端有没有新的消息(数据)。
轮询场景:
Client:亲亲,有没有新消息(Request)
Server:木有(Response)
Client:亲亲,有没有新消息(Request)
Server:木有。。(Response)
Client:亲亲,有没有新消息(Request)
Server:好烦,没有。。(Response)
Client:那个。。有没有新消息(Request)
Server: 有啦,给你(Response)
Client:亲亲,有没有新消息(Request)
Server:。。没。。。没有(Response)
...
...
从上面可以看出来,客户端不断的建立HTTP连接,然后等待服务端处理,可以提现HTTP协议的另一个缺陷:被动性,也就是服务端不能主动联系客户端,只能有客户端发起。而且,HTTP request的Header是很长的,为了传输一个很小的数据却占用了很多的带宽流量去传输Header。可见,轮询需要服务器有很快的处理速度,且非常消耗资源,也不具备即时性。
(2)长轮询 (Long polling) 阶段
Long Polling 是对 Polling 的改进,原理跟 Polling 相似,都是采用轮询的方式,不过Long Polling 采取的是阻塞模型:客户端发起连接后,如果服务端没有新消息,就一直不返回Response给客户端。直到有新消息或者超时才返回给客户端,返回之后这次请求结束。客户端再次建立连接,重复这个过程。。。。
情景:
Client:亲亲,有没有新消息? 没有的话,等有了再给我吧 (Request)
Server:额。。。~~~ (1小时后) ~~~ 有新消息了,给你 (Response)
...
...
相比于 Polling ,Long Polling 在某种程度上减小了对网络宽带的消耗等问题,但缺陷也很明显:假设服务器端的数据更新速度很快,服务器在传送一个数据包给客户端后必须等待客户端的下一个Get请求到来,才能传递第二个更新的数据包给客户端,那么这样的话,客户端显示实时数据最快的时间为2×RTT(往返时间),而且如果在网络拥塞的情况下,这个时间用户是不能接受的,比如在股市的的报价上;另外,由于http数据包的头部数据量往往很大(通常有400多个字节),但是真正被服务器需要的数据却很少(有时只有10个字节左右),这样的数据包在网络上周期性的传输,难免对网络带宽是一种浪费;而且 Long Polling 要求服务器具有高并发性,也就是同时接待大量客户端的能力。
(3)WebSocket 从上面分析可以看出,Polling ,Long Polling 不是最好的方式,Polling 需要服务端更快的处理速度,Long Polling 需要高并发性。在这种情况下,WebSocket出现,解决了上面提到的 HTTP 协议存在的几个缺陷。
####2.WebSocket 和 HTTP 有什么关系?
相同点: WebSocket 和 HTTP 都是基于TCP的应用层协议,都是可靠性传输协议。
不同点:
- 本来就是两种完全不同的协议。。。
- WebSocket 是全双工协议,可以双向发送或接受信息,连接建立之后,通信双方都可以在任何时刻向另一方发送数据。HTTP请求需要等待客户端发起请求服务端才能响应。
- 与 HTTP 不同的是,Websocket 需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)
- Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
- HTTP 协议要不断的建立,关闭Request,由于HTTP是无状态协议,每一次发送都是一次新的开始,所以每次都要重新传输identity info (鉴别信息),来告诉服务端你是谁。Websocket 只需要一次HTTP握手,所以说整个通讯过程是建立在一次连接状态中,也就避免了HTTP的非状态性,服务端会一直知道你的信息,直到你关闭请求,这样就可以避免反复解析HTTP协议,还要查看identity info(鉴别信息)。
联系: Websocket 通过 HTTP/1.1 协议的101状态码进行握手。 为了创建Websocket连接,需要通过客户端发出请求,之后服务器进行回应,这个过程通常称为“握手”(handshaking)。
虽然WebSocket在握手的时候是通过 HTTP 进行的(为了兼容性考虑,也许以后WebSocket会有自己的握手方式),但也仅仅是这样而已,它们就是两种不同的应用层协议。
3. WebSocket 和 HTML5 是什么关系?
HTML5是指的一系列新的API,或者说新规范,新技术。而WebSocket就是HTML5中出的的一种协议。
4. 什么是 长连接/短连接、长轮询/短轮询?
查了许多资料,于是总结一下自己的理解:
长连接/短连接,长轮询/短轮询 本身就是不同层次的概念。
长/短连接 是针对TCP传输层的概念,也就是,TCP连接才有长/短连接之说。
短连接是指通讯双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此连接,即每次连接只完成一项业务的发送。
长连接指在一个TCP连接上可以连续发送多个数据包,在连接保持期间,如果没有数据包发送,需要TCP keep alive。TCP keep alive 的两种方式:
- 应用层面的心跳机制 自定义心跳消息头 : 一般客户端主动发送, 服务器接收后进行回应(也可以不回应).
- TCP协议自带的 keep alive:打开keep-alive功能即可. 具体属性也可以通过API设定.
TCP KeepAlive 是用于检测TCP连接的状态,而心跳机制有两个作用:一是检测TCP的状态,二是检测通讯双方的状体。
考虑一种情况,某台服务器因为某些原因导致负载超高,CPU 100%,无法响应任何业务请求,但是使用 TCP 探针则仍旧能够确定连接状态,这就是典型的连接活着但业务提供方已死的状态,对客户端而言,这时的最好选择就是断线后重新连接其他服务器,而不是一直认为当前服务器是可用状态,一直向当前服务器发送些必然会失败的请求。
从上面我们可以知道,KeepAlive 并不适用于检测双方存活的场景,这种场景还得依赖于应用层的心跳。应用层心跳有着更大的灵活性,可以控制检测时机,间隔和处理流程,甚至可以在心跳包上附带额外信息。从这个角度而言,应用层的心跳的确是最佳实践。
写到这顺便说一下 HTTP Keep Alive 和 TCP keep alive 这两个看上去肯定有点儿啥关系的概念。事实上,HTTP keep-alive与TCP keep-alive 是两个完全没有关系的东西。
HTTP keep-alive是HTTP协议的一个特性,目的是为了让TCP连接保持的更久一点,以便客户端/服务端在同一个TCP连接上可以发送多个HTTP request/response。
TCP keep-alive是一种检测连接状况的保活机制。It keeps TCP connection opened by sending small packets. 当网络两端建立了TCP连接之后,闲置idle(双方没有任何数据流发送往来)了tcp_keepalive_time后,服务器内核就会尝试向客户端发送侦测包,来判断TCP连接状况(有可能客户端崩溃、强制关闭了应用、主机不可达等等)。如果没有收到对方的回答(ack包),则会在 tcp_keepalive_intvl后再次尝试发送侦测包,直到收到对对方的ack,如果一直没有收到对方的ack,一共会尝试 tcp_keepalive_probes次,每次的间隔时间在这里分别是15s, 30s, 45s, 60s, 75s。如果尝试tcp_keepalive_probes,依然没有收到对方的ack包,则会丢弃该TCP连接。TCP连接默认闲置时间是2小时,一般设置为30分钟足够了。
既然长/短连接是针对TCP的概念,但是我们却经常看到HTTP 长连接(HTTP persistent connection)这样的说法,到底什么鬼?憋急,先看一段解释:
HTTP persistent connection, also called HTTP keep-alive, or HTTP connection reuse, is the idea of using a single TCP connection to send and receive multiple HTTP requests/responses, as opposed to opening a new connection for every single request/response pair. The newer HTTP/2 protocol uses the same idea and takes it further to allow multiple concurrent requests/responses to be multiplexed over a single connection.
—— From Wikipedia, the free encyclopedia
可以发现,HTTP persistent connection就是上面我们解释的HTTP Keep Alive。其实很简单,TCP长连接是针对TCP层的概念,就是让一个TCP连接长时间保持不要断开。HTTP的长连接(keep alive)是HTTP协议的一个特性,也是希望保持住长时间的TCP连接,才能在这个TCP通道上发送多个HTTP请求,而不必每次请求都打开一个新的TCP连接。
长轮询/短轮询 在上文已经介绍了,它是服务器的实现方式!由服务端编写的代码决定。
5. WebSocket在哪些场景下使用?
1.社交聊天
最著名的就是微信,QQ,这一类社交聊天的app。这一类聊天app的特点是低延迟,高即时。即时是这里面要求最高的,如果有一个紧急的事情,通过IM软件通知你,假设网络环境良好的情况下,这条message还无法立即送达到你的客户端上,紧急的事情都结束了,你才收到消息,那么这个软件肯定是失败的。
2.弹幕
说到这里,大家一定里面想到了A站和B站了。确实,他们的弹幕一直是一种特色。而且弹幕对于一个视频来说,很可能弹幕才是精华。发弹幕需要实时显示,也需要和聊天一样,需要即时。
3.多玩家游戏
4.协同编辑
现在很多开源项目都是分散在世界各地的开发者一起协同开发,此时就会用到版本控制系统,比如Git,SVN去合并冲突。但是如果有一份文档,支持多人实时在线协同编辑,那么此时就会用到比如WebSocket了,它可以保证各个编辑者都在编辑同一个文档,此时不需要用到Git,SVN这些版本控制,因为在协同编辑界面就会实时看到对方编辑了什么,谁在修改哪些段落和文字。
5.股票基金实时报价
金融界瞬息万变——几乎是每毫秒都在变化。如果采用的网络架构无法满足实时性,那么就会给客户带来巨大的损失。几毫秒钱股票开始大跌,几秒以后才刷新数据,一秒钟的时间内,很可能用户就已经损失巨大财产了。
6.体育实况更新
全世界的球迷,体育爱好者特别多,当然大家在关心自己喜欢的体育活动的时候,比赛实时的赛况是他们最最关心的事情。这类新闻中最好的体验就是利用Websocket达到实时的更新!
7.视频会议/聊天
视频会议并不能代替和真人相见,但是他能让分布在全球天涯海角的人聚在电脑前一起开会。既能节省大家聚在一起路上花费的时间,讨论聚会地点的纠结,还能随时随地,只要有网络就可以开会。
8.基于位置的应用
越来越多的开发者借用移动设备的GPS功能来实现他们基于位置的网络应用。如果你一直记录用户的位置(比如运行应用来记录运动轨迹),你可以收集到更加细致化的数据。
9.在线教育
在线教育近几年也发展迅速。优点很多,免去了场地的限制,能让名师的资源合理的分配给全国各地想要学习知识的同学手上,Websocket是个不错的选择,可以视频聊天、即时聊天以及其与别人合作一起在网上讨论问题…
10.智能家居
这也是我一毕业加入的一个伟大的物联网智能家居的公司。考虑到家里的智能设备的状态必须需要实时的展现在手机app客户端上,毫无疑问选择了Websocket。
从上面我列举的这些场景来看,一个共同点就是,高实时性!
6. 如果想做IOS的即时通讯,是使用Socket还是WebSocket?
使用 Socket 和 WebSocket 都可以做即时通讯。具体怎么做呢?公司项目IOS端使用了第三方库 CocoaAsynSocket ,它是对socket的OC封装,支持TCP、UDP连接。