为什么要引入websocket?
http协议只能由客户端向服务器端发送请求!服务器端无法向客户端主动发送信息。每个http响应对应一个http请求。
这种单向请求的特点,对于会发生连续变化的状态,客户端想要得知就非常麻烦,只能依靠http长轮询或者http短轮询来不断地向服务器发送请求去获取状态。这样做很浪费带宽和时间。
websocket的出现就解决了这个问题。websocket是提供全双工通信,只需要建立一次连接,就可以一直保持连接状态。客户端可以主动地向服务器发送信息,服务器可以主动的推送消息给客户端。
websocket创建之后,会有一个http请求发送到浏览器发起连接。在获得服务器响应连接成功之后。建立的连接会使用http升级从http协议交换为websocket协议。由于websocket使用了自定义的协议,所以url模式也不太相同。未加密的连接不再是http://而是ws://,加密的连接也不再是https://而是ws://。
使用自定义协议而非http协议的好处是:能够在客户端和服务器端发送少量的数据,而不必担心http那样子节级的开销。由于传送的数据包很小,因此websocket非常适合移动应用。
1.WebSocket API
var scoket=new WebSocket("wss://echo.websocket.org");
这里的url必须是绝对url。websocket不受同源策略影响,它可以访问任何位置的站点信息。即便是跨域。
websocket也有readystate属性,他有四个值分别是:
websocket.opening(0):表示正在建立连接;
websocket.open(1):表示已经建立连接;
websocket.closing(2):表示连接正在关闭;
websocket.close(3):表示连接已经关闭。
要关闭websocket连接就要调用websocket.close()方法。
调用了websocket.close()方法后readystate的值就会变为2,当连接关闭之后就会变为3.
2.发送和接收数据
发送数据
scoket.send(JSON.stringify(msg));
websocket只能连接发送纯文本数据,所以复杂类型的数据必须进行序列化。下面是一个例子,将要发送的复杂数据序列化为一个JSON字符串,在发送给服务器。
var msg={
time:new Date(),
text:"hello",
clientId:"acssdas"
}
scoket.send(JSON.stringify(msg));
服务器要读取其中的数据就会将JSON字符转解析。
当服务器向客户端推送消息时,会触发websocket.onmessge事件。会把返回的数据保存在event.daya中
scoket.onmessage=function(event){
console.log(event.data)
}
3.其他事件
websocket对象还有其他事件,在连接生命周期的不同阶段触发。
open:在成功建立连接时触发。
error:在发生错误时触发,连接不能持续
close:在连接关闭时触发
在这三个事件中只有close事件的event对象有额外的信息。这个时间的事件对象有三个额外属性wasClean,code和reason。wasClean
是一个布尔值,用来表示当前是否处于连接状态;code是服务器返回的数值状态吗;而reason是一个字符串,是服务器返回的信息。
<script>
var scoket=new WebSocket("wss://echo.websocket.org");
var msg={
time:new Date(),
text:"hello",
clientId:"acssdas"
}
scoket.onopen=function(){
console.log("连接成功");
scoket.send(JSON.stringify(msg));
}
scoket.onmessage=function(event){
console.log(event.data)
scoket.close();
}
scoket.onclose=function(){
console.log("连接关闭");
}
</script>