一. 为什么需要 WebSocket?
在开发的过程中,如开发聊天室,或者客服聊天系统时,常常有新的客户端(用户)连接进来,也有老的客户端(用户)退出,
客户端A进行群发消息,其他的客户端进行展示客户端A发送的消息,
采用Http 协议进行处理时,需要在客户端发送一个请求,然后服务器进行响应数据,客户端拿着服务器响应过来的数据,
进行处理,最后展示处理好的数据。 请求是单向的,如果不发送请求,就不能获取数据。
为了更快,更准确地显示消息,我们常常采用轮询的方式,从服务器获取数据。
轮询方式指的是在JS客户端编写定时程序,每隔固定的一段时间往服务器发送请求,询问服务器是否有新消息。
如 每隔10s,采用ajax的方式,往服务器发送一条请求,获取服务器新的消息。
这种方式,实时性不够,另外,频繁地请求,也会给服务器造成巨大的压力。
我们希望,有一种新的模式,不仅仅是客户端请求服务器端的响应数据,也可以让服务器端自动推送最新的消息。
当有新的用户连接进来时(服务器最先知道客户端连接进来了),服务器自动把这个新连接用户连接进来的消息,推送给客户端,
即 服务器告诉客户端,“Xxx连接进来了”。
当有老的用户退出时,服务器自动把这个消息推送给客户端,即服务器告诉客户端,“Xxx退出了”。
当客户端A发送消息之后,服务器自动把这个消息推送给其他的客户端, 即服务器告诉客户端,“Xxx 发送了一条新消息: Xxx发送的消息内容”。
这样,实时性会显著地提升,而且也会减轻服务器的压力。(以前,每隔10s,不管有没有用户的状态发生改变,都会进行请求,现在,如果用户的状态没有改变,服务器就不进行处理。 1分钟用户状态没有改变,那么这一分钟服务器就不进行任何操作,10分钟用户状态不改变,那么这10分钟服务器就不进行任何操作)
这样的技术,叫做 WebSocket。
WebSocket 于2011年被IETF定为标准RFC 6455, 是在 Html5 时出现的一种新的标准,允许服务器向客户端推送数据。
在WebSocket里,浏览器和服务器只需要一次握手,就可以创建持久性连接,并且允许双向传输数据。
二. WebSocket 的 API
二.一 WebSocket 的协议地址写法
以前 Http的协议是, http://example.com:80/context/path
加密之后的,是 https://example.com:80/context/path
WebSocket 协议是, ws://example.com:80/context/path, ws 是 websocket的简写。
也可以进行加密, wss://example.com:80/context/path
加密和不加密的区别:
二.二 创建 WebSocket 对象
var webSocket=new WebSocket(ws协议的url);
如 创建 本地 ip地址的 WebSocket对象
var webSocket=new WebSocket("ws://127.0.0.1:80/WebSocket/websocket/chat");
WebSocket 对象,需要浏览器的支持
- Chrome
- Firefox
- IE >= 10
- Sarafi >= 6
- Android >= 4.4
- iOS >= 8
建议使用 Chrome 和 Firefox 浏览器 。
二.三 WebSocket 的状态值 readyState
WebSocket对象,有一个属性 readyState, 该属性有四个值,0,1,2,3 代表不同的状态。
可以通过 WebSocket创建出来的对象, 即 webSocket.readyState 即可取出状态。
二.四 WebSocket的四种事件
二.四.一 四种事件
WebSocket共提供了四种事件,来接收处理服务器对客户端的响应处理。
- open 事件,连接建立时触发
- close 事件, 连接关闭时触发,包括手动退出和浏览器关闭
- message 事件 客户端接收服务器数据时触发
- error 事件, 通信遇到错误时,触发
这四种事件,分别对应了四种事件的处理程序。 (仍然使用的是二.二 创建的 webSocket 对象)。
open 事件 对应 webSocket.onopen
close 事件 对应 webSocket.onclose
message 事件对应 webSocket.onmessage
error 事件对应 webSocket.onerror
二.四.二 事件处理代码
以 open 事件进行举例。
二.四.二.一 普通方式
//创建 WebSocket 对象 var webSocket=new WebSocket("ws://127.0.0.1:80/WebSocket/websocket/chat"); webSocket.onopen = function () { webSocket.send('Hello WebSocket!'); console.log("连接建立"); }
二.四.二.二 addEventListener() 方式
//创建 WebSocket 对象 var webSocket=new WebSocket("ws://127.0.0.1:80/WebSocket/websocket/chat"); webSocket.addEventListener('open', function (event) { webSocket.send('Hello WebSocket!'); console.log("连接建立"); });
通常采用第一种方式即可。
二.五 WebSocket的方法 send()和close()
WebSocket 提供了两种方法,
一种是 send(text) 方法, 用于向服务器端发送数据,
如:
webSocket.send("你好啊服务器,我是两个蝴蝶飞");
另外一种是 close() 方法, 用于手动关闭浏览器连接
如:
webSocket.close();
三. WebSocket 流程分析
(参考了 黑马培训教程的 即时通信技术-Websocket实现在线聊天室 资料)
三.一 浏览器端发送请求
HEA: GET WebSocket/websocket/chat HTTP/l.l Host: localhost Upgrade: webaocket Conection: Upqrade oriqin: http://127.0.0.1:80 Pragma: no-cache Cache-Control: no-cache Seo-WebSocket-Key:. tSYYnx6EFK/hevZE8JbLaQ-- Sec-KebSocket -Version: 13 vindow. bits. -webkit-deflate-frame Hoøt: 127.0.0.1:10000 Sec-WebSocket -Extenaiona: permeaaqe-deflater elient. aж Uaer-Agenti Mozilla/5.0 (Windown NT 6.1; WOW64) AppleMebKit/537.36 (KHTNL, 1ike Gecko) Chrome/35.0.1916.138 safari/537.36
解释字段如下:
(1)、Upgrade:表示的意思是“客户端准备使用websocket协议进行通信,服务端如果支持的话,咱们就换websocket协议吧!”。 (2)、sec-websocket-version: 是指浏览器支持的websocket版本号。需注意的是这里不会出现912的版本号, 因为websocket协议规定9- 12是保留字段。 (3)、sec-websocket -key:是一一种验证服务 端是不是支持websocket的验证算法。 与Response中的sec-websocket -accept是对应的。 (4)、sec-websocket-accept 与sec-websocket-key的对应算法是: sec . websocket -accept = base64 (hsal (sec websocket -key+ 258EAFA5-E914-47DA-95CA C5AB0DC85B11)) 如果返回的sec-websocket-accept不对,在chrome下 会出现Sec-WebSocket -Accept dismatch的错误。 (5)、HTTP Staus: Response返回的是101, 代表服务端说“我们双方后面就按照websocket协议来进行数据传输吧!”
三.二 服务器解析
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: server-random-string
三.三 传输数据,双向传输
客户端发送数据: 服务器, 两个蝴蝶飞您好 待编码数据:两个蝴蝶飞您好 回复客户端数据: 两个蝴蝶飞您好
三.四 客户端主动断开连接和服务器端主动断开连接
当客户端主动断开连接时,客户端会发送http请求,请求断开连接,服务器端接收请求之后,断开连接。
当服务器主动断开连接时,直接断开连接,所有客户端得到通知。
谢谢您的观看!!!