Websocket

初次接触Websocket的人,都会有一个问题:我们已经有了HTTP协议,为什么还需要另外一个协议?它能带来什么好处?

答案很简单,因为HTTP协议有一个缺陷通信只能由客户端发起。HTTP协议做不到服务器主动向客户端推送信息。

Websocket协议最大的特点就是:服务器可以主动向客户端推送消息客户端也可以主动向服务器发送消息是真正的双向平等对话,属于服务器推送技术的一种

 

一.传统的实现即时通信的方式

  1.Ajax轮询:Ajax轮询的原理很简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新消息。

    优点:程序编写比较简单

    缺点:需要服务器有很快的处理速度,请求中有大半是无用的,浪费带宽和服务器资源。

    实例:适用于小型应用

  2.long poll(长轮询):long poll其实原理和Ajax轮询差不多,都是采用轮询的方式,不过采用的是阻塞模型,也就是说,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。

    优点:在无消息的情况下不会频繁的请求,耗费资源小

    缺点:服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。

    实例:WebQQ

  3.长连接:在HTTP1.0和1.1及后面的版本都有对长连接的支持。其中HTTP1.0需要在请求头部增加”Connection:Keep-alive“才能够支持,而HTTP1.1及后面的版本默认支持。

    优点:消息即时到达,不发无用请求,管理起来相对方便。

    缺点:服务器维护一个长连接会增加开销。

    实例:Gmail聊天

  4.Flash Socket:在页面中内嵌一个使用了Socket类的Flash程序JavaScript通过调用此Flash程序提供的Socket接口与服务器端的Socket接口进行通信,JavaScript在收到服务器端传送的信息后控制页面的显示。

    优点:实现真正的即时通信,而不是伪即时。

    缺点:客户端必须安装Flash插件,非HTTP协议,无法自动穿越防火墙。

    实例:网络互动游戏

 

二.Websocket的方式实现服务端消息推送

  在网络中的两个应用程序(进程)需要全双工相互通信(全双工即双方可同时向对方发送消息),需要用到的就是socket,它能够提供端对端通信,对于程序员来讲,他只需要在某个应用程序的一端(暂且称之为客户端)创建一个socket实例并且提供它所要连接一端(暂且称之为服务端)的IP地址和端口,而另外一端(服务端)创建一个socket实例并绑定本地端口进行监听,然后客户端进行连接服务端,服务端接收连接后双方建立了一个端对端的TCP连接,在该连接上就可以双向通讯了,而且一旦建立这个连接之后,通信双方就没有客户端服务端之分了,提供的就是端对端通信了。从本质上来说,socket并不是一个新的协议,它只是为了便于程序员进行网络编程而对TCP/IP协议族通信机制的一种封装。

 

  Websocket是html5规范中的一部分,它借鉴了socket这种思想,为web应用程序客户端和服务端之间提供了一种全双工通信机制。同时,它又是一种新的应用层协议,Websocket协议是为了提供web应用程序客户端和服务端全双工通信而专门制定的一种应用层协议,通常它表示为:ws://echo.websocket.org/?encoding=text HTTP/1.1,可以看到除了前面的协议名和HTTP不同之外,它的表示地址就是传统的URL地址。

  Websocket其实是一种新协议,跟HTTP协议基本没有关系,只是为了兼容现有浏览器的握手规范而已,也就是说它是HTTP协议上的一种补充。

 

  Websocket具有以下几个方面的优势:

  1. 建立在TCP协议之上,服务器端实现比较容易
  2. 与HTTP协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用了HTTP协议,因此握手时不容易被屏蔽,能通过各种HTTP代理服务器。
  3. 数据格式比较轻量,性能开销小,通信高效。
  4. 可以发送文本,也可以发送二进制数据。
  5. 没有同源限制,客户端可以与任意服务器通信。
  6. 协议标识符是ws(如果加密是wss)服务器网址就是URL。 

 

三.Websocket的通信原理和机制

  当客户端连接服务器的时候,会向服务器发送一个类似下面的报文:

  Websocket

 

   

  Websocket

 

   这个是Websocket的核心了,告诉Apache,Nginx等服务器,发起的是Websocket协议

  Websocket

 

   首先,Sec-WebSocket-Key 是一个Base64 encode的值,这个是浏览器随机生成的。

  然后,Sec-WebSocket-Protocol 是一个用户定义的字符串,用来区分同URL下,不同的服务所需要的协议。

  最后,Sec-WebSocket-Version 是告诉服务器所使用的Websocket Draft(协议版本)。

 

  然后服务器会返回下列东西,表示已经接受到请求,成功建立Websocket啦。

  Websocket

 

   依然是固定的,告诉客户端即将升级的是Websocket协议,而不是其他协议(mozillasocket,lurnarsocket,shitsocket)

  Sec-WebSocket-Accept 这个则是经过服务器确认,并且加密过后的 Sec-WebSocket-Key。

  Sec-WebSocket-Protocol 则是表示最终使用的协议。

  返回的状态码为101,表示同意客户端协议转换请求,并将它转换为Websocket协议。以上过程都是利用HTTP通信完成的。称之为Websocket握手协议,经过握手后,客户端和服务器就建立了Websocket连接,以后的通信都走的是Websocket协议了。

  总结就是Wobsocket协议握手需要借助于HTTP协议,建立连接后通信过程使用Websocket协议。同时需要了解的是,该Websocket连接还是基于刚才发起的HTTP连接的TCP连接。Websocket提供了两种数据传输:文本数据和二进制数据。

 

四.Websocket的创建和常用属性方法

  以下API用于创建 Websocket 对象。

  var Socket = new WebSocket(url,[protocol]);

  第一个参数url指定连接的URL。第二个参数是可选的,指定了可接受的子协议。

 

  WebSocket 属性

  以下是WebSocket 对象的属性。假定我们使用以上代码创建了 Socket 对象。

  WebSocket.readyState:只读属性 readyState 表示连接状态,可以是以下值:

  • 0 - 表示连接尚未建立。
  • 1 - 表示连接已建立,可以进行通信。
  • 2 - 表示连接正在进行关闭。
  • 3 - 表示连接已经关闭或者连接不能打开。

  WebSocket.bufferedAmount:只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。

  Websocket

 

   可以看到,当onopen触发时,对应的就是readyState的OPEN状态,不包含OPENING,onclose触发时,对应的就是CLOSED状态,不包含CLOSING状态。

 

  WebSocket 事件

  以下是WebSocket对象的相关事件。假定我们使用了以上代码创建的 Socket 对象。

  Websocket

 

   

  WebSocket 方法

  以下是WebSocket对象的相关方法。假定我们使用了以上代码创建的 Socket 对象。

  Websocket

 

 

  用WebSocket发送接收二进制数据

  WebSocket 可以通过 ArrayBuffer ,发送或接收二进制数据。

   Websocket

 

 

  目前WebSocket的缺点是不兼容低版本的浏览器。

Websocket

上一篇:spoj Corporative Network


下一篇:asp.net core OSS STS 上传 Excel 文件