因为websocket的内容比较多,所以准备分解将基础篇主要讨论一下websocket的概念,websocket和http协议的区别,客户端的websocket以及服务端的websocket,中间穿插着一些实例,最后以一个基本的实例还结束基础篇。扩展篇讨论一下nodejs中socket及其应用。下面我们就来进入正式话题

一、websocket的介绍

1.1 websocket概念

websocketHTML5中新引进的一种协议,它是一种协议就像(HTTP,FTP在tcp/ip协议栈中属于应用层)而不是简单的一个函数。它本身及基于TCP协议的一种新的协议。

1.2 websocket的产生

websocket是基于web的实时性而产生的,说到这里就不得不要追溯一下web的历史了,在2005年(也就是ajax还没诞生)以前,我们如果想要在一个页面显示显示不同的内容,或者说页面内跳转,只能是通过点击然后路由跳转,在ajax诞生之后,网页开始变得动态了。但是所有的HTTP通信还都是由客户端控制的,这就要需要长连接定期轮询或者流操作,来和服务器沟通来更新数据。下面来介绍一下这三种操作
☞定期轮询(ajax轮询):浏览器在特定的时间给服务器发送请求,查看服务器是否有信息数据。情况类似下图:

☞长连接:其实和上面的原理差不多,是对ajax轮询进行了改进和提高。客户端和服务端建立连接之后,一直保持通信(阻塞模式),如果服务器没有新消息就一直保持通信,知道服务器有新的消息,然后返回给客户端,客户端与服务器断开连接,此时客户端可以继续和服务器进行连接。情况类似图2:

☞流操作:常就是在客户端的页面使用一个隐藏的窗口向服务端发出一个长连接的请求。服务器端接到这个请求后作出回应并不断更新连接状态以保证客户端和服务 器端的连接不过期。通过这种机制可以将服务器端的信息源源不断地推向客户端。[1]情况类似图三:

当然每一种新技术的兴起,都会引领一种潮流,就像05年ajax产生的前端大改革,正式那群有思想的人驱动了历史的改革,但是前浪终究会被拍在沙滩上,就像当今的ajax快被websocket替代了一样。
结合上面的解释我们来分析一下这三种方式缺点:
☛ajax轮询:这种方式带来了没必要的网络传输,是一种最低效的实时方案
☛长期轮询:虽然减少了无效的客户端和服务端的交互,但是数据更新频繁的时候效率并没有明显的增加
☛流操作:这种方式就不言而喻了,对服务器的资源是巨大的考验呀
这几种还是有一个共同的特点就是客户端是主动的,服务器是被动的这也不能说是个确定,但是在通信这方面如果服务器有资源就通知客户端这种模式还是为上上策呀,这就催生可websocket的产生:WebSocket通过浏览器提供的API真正实现了具备像C/S架构下的桌面系统的实时通讯能 力。其原理是使用JavaScript调用浏览器的API发出一个WebSocket请求至服务器,经过三次握手,和服务器建立了TCP通讯,因为它本质 上是一个TCP连接,所以数据传输的稳定性强和数据传输量比较小。[2]

1.3 websocket解决的问题

1.3.1 解决的持久性连接

JavaScript调用浏览器的API发出一个WebSocket请求至服务器,经过三次握手,和服务器建立了TCP通讯,因为它本质 上是一个TCP连接.
为什么要建立持久性连接呢?
这是因为HTTP协议是无状态的,简单来说就是穿了裤子就不认人了(连接断开之后就在也不知道刚才的客户端是谁了)。
websocket这就避免了HTTP的非状态性,服务端会一直知道你的信息,直到你关闭请求。

1.3.2 解决耗时和浪费资源

自从有了websocket现在的情况就变为了下图所示的情况:

只要经过一次HTTP请求当服务器的数据更新的时候,消息就能推送到了客户端,这个过程我们通常是通过回调函数是实现的。

1.3.3 服务器反客为主

当服务器充http进化为websocket时,服务端就可以主动推送信息给客户端啦。
这就实现了服务器的反客为主,客户端通过回调就能实时的捕捉到服务器传来的信息。
这样就解决了,客户端向服务器请求数据的时候收到503(服务器为找到)的返回码,也就是解决了下图的问题:

1.4 WebSocket 协议

上面BB了一大堆历史性的问题,下面来正式说一下websocket这个协议
WebSocket 协议本质上是一个基于 TCP 的协议。为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息”Upgrade: WebSocket”表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。

客户端发到服务器的内容:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这个比普通的http多了几个陌生的字段,我们来看http协议的的报文:

    GET /socket.io/1/xhr-polling/oiO9akCJzXsaVw2GxyoO?t=1464277248268 HTTP/1.1\r\n
    Host: s3-im-notify.csdn.net\r\n
    Connection: keep-alive\r\n
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

当然一些太没有必要的字段就没有贴出免得占文章篇幅。
我看来看websocket多出的几个字段:
Upgrade: websocket表示这是一个特殊的 HTTP 请求,请求的目的就是要将客户端和服务器端的通讯协议从 HTTP 协议升级到 WebSocket 协议.
Sec-WebSocket-Key: 是一个Base64 encode的值,这个是浏览器随机生成,告诉服务器,我来验证一下你,是不是能和我进行websocket通信
Sec_WebSocket-Protocol:是一个用户定义的字符串,用来区分同URL下,不同的服务所需要的协议
Sec-WebSocket-Version:告诉服务器所使用的协议版本
我们来看一下服务器给客户端返回的:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

这里主要介绍一下Sec-WebSocket-Accept这个字段:经过服务器确认,并且加密过后的 Sec-WebSocket-Key。用来证明客户端和服务器之间能进行通信了。
这个会在后面深入讨论

1.5 websocket和http协议的关系

在1.4中已经介绍了http和websocket,
他们之间的关系可以用下图表示:

再次的理论内容比较强,下次就会结合代码一起讨论

via http://blog.csdn.net/woshinannan741/article/details/51470830

Websocket详细讲解(基础篇一)
标签: