Web Socket原理和使用

Web Socket

Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询、Comet技术、WebSocket技术、SSE(Server-sent Events)。

Web Socket(套接字)的目标是通过一个长时连接实现在用户的浏览器和服务器之间打开双工、双向通讯会话。

Web Socket使用了自定义协议,所以 URL方案稍有变化:不能再使用 http://或 https://,而要使用 ws://和 wss://。前者是不安全的连接,后者是安全连接。
WebSocket 与 HTTP 和 HTTPS 使用相同的 TCP 端口,可以绕过大多数防火墙的限制。

创建Web Scocket对象

创建一个新的 Web Socket,就要实例化一个 WebSocket 对象并传入提供连接的 URL:

let socket = new WebSocket("ws://www.example.com/server.php")

必须给 WebSocket 构造函数传入一个绝对 URL。同源策略不适用于 Web Socket,因此可以打开到任意站点的连接。

浏览器会在初始化 WebSocket 对象之后立即创建连接

与 XHR 类似,WebSocket 也有一个readyState 属性表示当前状态。

 WebSocket.OPENING(0):连接正在建立。
 WebSocket.OPEN(1):连接已经建立。
 WebSocket.CLOSING(2):连接正在关闭。
 WebSocket.CLOSE(3):连接已经关闭。

WebSocket 对象没有 readystatechange 事件,而是有与上述不同状态对应的其他事件。
readyState 值从 0 开始。
任何时候都可以调用 close()方法关闭 Web Socket 连接:socket.close();
调用 close()之后,readyState 立即变为 2(连接正在关闭),并会在关闭后变为 3(连接已经关闭)。

发送和接收数据

除了文本,WebSocket消息还可以处理二进制数据,这种数据作为Blob消息或ArrayBuffer消息。
打开 Web Socket 之后,要向服务器发送数据,使用 send()方法并传入一个字符串、ArrayBuffer 或 Blob,如下所示:

let socket = new WebSocket("ws://www.example.com/server.php"); 
let stringData = "Hello world!"; 
let arrayBufferData = Uint8Array.from(['f', 'o', 'o']); 
let blobData = new Blob(['f', 'o', 'o']); 
socket.send(stringData); 
socket.send(arrayBufferData.buffer); 
socket.send(blobData); 

接收到来自服务端的消息时,WebSocket 对象上会触发 message事件。这个 message 事件与其他消息协议类似,可以通过 event.data 属性访问到有效载荷:

socket.onmessage = function(event) { 
 let data = event.data; 
 // 对数据执行某些操作
}; 

其他事件

open:在连接成功建立时触发。
error:在发生错误时触发。连接无法存续。
close:在连接关闭时触发。

let socket = new WebSocket("ws://www.example.com/server.php"); 
socket.onopen = function() { 
 alert("与服务端连接打开"); 
}; 

在这些事件中,只有 close 事件的 event 对象上有额外信息。这个对象上有 3 个额外属性: wasClean、code 和 reason。其中,wasClean 是一个布尔值,表示连接是否干净地关闭;code 是一 个来自服务器的数值状态码;reason 是一个字符串,包含服务器发来的消息。可以将这些信息显示给 用户或记录到日志:

socket.onclose = function(event) { 
 console.log(`as clean? ${event.wasClean} Code=${event.code} Reason=${ 
 event.reason}`); 
}; 

总结

优点:

  1. 实时性:WebSocket提供了实时的双向数据传输,能够实现高效的实时通信,而不需要通过轮询或长轮询等间接方式。
  2. 低延迟:由于WebSocket建立在TCP连接上,并且使用更轻量级的协议头部,因此可以减少数据传输的延迟,提供更快速的响应时间。
  3. 节省带宽:WebSocket使用较少的网络流量,因为它使用更紧凑和有效的数据帧格式,并且可以使用二进制数据传输,而不仅仅是文本数据。
  4. 更强大的功能:相比于HTTP请求-响应模型,WebSocket支持服务器主动推送数据到客户端,从而能够实现实时更新、即时聊天、多人协作和实时数据展示等功能。
  5. 兼容性:WebSocket协议被广泛支持,并且现代的Web浏览器都原生支持WebSocket,无需任何额外插件或库。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。

WebSocket被广泛应用于实时数据传输、在线聊天、多人游戏、实时协作、股票行情、推送通知、实时监控等场景,为Web应用程序提供了更好的用户体验和功能扩展性。

扩展: WebSocket与SockJs、STOMP关系

由于一些浏览器不支持WebSocket协议,所以在项目中经常使用SockJs结合STOMP来实现WebSocket订阅消息!在此不详细介绍使用方法,简单了解下是什么吧~

SockJS

是一个JavaScript库,为了应对许多浏览器不支持WebSocket协议的问题,设计了备选SockJs。SockJS 是 WebSocket 技术的一种模拟。SockJS会尽可能对应 WebSocket API,但如果WebSocket 技术不可用的话,会自动降为轮询的方式。

SockJS的url是http、https协议,而不是 ws,提供Websocket兼容性实现方法。
new WebSocket(url) url必须是以ws://或者wss://开始的一个完全限定URL。

SockJS会优先选择WebSocket进行连接,但是当服务器或客户端不支持WebSocket时,会自动在 XHR流、XDR流、iFrame事件源、iFrame HTML文件、XHR轮询、XDR轮询、iFrame XHR轮询、JSONP轮询 这几个方案中择优进行连接。

直接使用 WebSocket(SockJS) 就很类似于 使用 TCP 套接字来编写 web 应用,因为没有高层协议,就需要我们定义应用间所发送消息的语义,还需要确保连接的两端都能遵循这些语义。

STOMP

STOMP(-面向消息的简单文本协议)在WebSocket之上提供了一个基于帧的线路格式层,用来定义消息的语义
STOMP帧由命令、一个或多个头信息以及负载所组成。
前后端websocket都用stomp才有意义!

总结:WebSocket 是底层协议,SockJS 是WebSocket 的备选方案,也是底层协议,而 STOMP 是基于 WebSocket(SockJS)的上层协议。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值