WebSocket系列之基础知识以及设计思路

这篇具有很好参考价值的文章主要介绍了WebSocket系列之基础知识以及设计思路。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、WebSocket介绍

WebSockets 是一个可以创建和服务器间进行双向会话的高级技术。通过这个API你可以向服务器发送消息并接受基于事件驱动的响应,这样就不用向服务器轮询获取数据了。

双向会话 指的是客户端和服务端都能够通过WebSocket来进行数据的互相传递,即服务端可以给客户端推送数据,客户端也可以通过WebSocket来传递数据。例如,我们的一个聊天室功能就是一个典型的场景。

1.为什么要使用WebSocket

在不使用WebSocket时,如果我们需要建立一条长连接,有以下几种方法:

  • 轮询
  • 长轮询(常用)
  • SSE(Server Send Event)

下面,我们对这几个都进行简单的介绍。

  • 轮询
    轮询是最早在客户端用来模拟长连接的一种方式。他通过客户端定时向服务端发送HTTP请求来模拟客户端向服务端发送数据,而服务端的数据则是在客户端发送HTTP请求后跟随返回。

这种方案能够让客户端的数据几乎实时的到达,但是缺点也显而易见:服务端的数据需要在客户端的请求回来后才能带回。如果HTTP请求的间隔太短,则会导致大量的网络开销;如果间隔太长,这将导致数据传递的不及时。

  • 长轮询
    长轮询是在轮询的基础上改进的一种方式。在客户端发送HTTP请求且服务端收到请求时,服务端会先维持这个请求不返回。在特定的时间内(一般为30秒,因为通常HTTP判断超时时间为30秒),如果服务端没有数据,则回应这个请求;服务端有数据需要发送时,则立即通过HTTP请求的响应将数据传递给客户端。客户端收到响应后,立即发起下一次的HTTP请求。

这种方案能够解决轮询中带来的服务端数据不能及时传递的问题,但是带来的网络花销大的问题仍然无法解决。

  • SSE(Server Send Event)
    SSE是一个新的协议,作用为服务端向客户端推送数据。他通过自定义的SSE协议来实现单向的数据推送。SSE的缺点是数据只能从服务端像客户端传递,而数据不能通过客户端向服务端传递。

2.WebSocket能够有效的解决以下问题:

  • 带宽问题:WebSocket相对于HTTP来说协议头更加小,同时按需传递。
  • 数据实时性问题:WebSocket相对于轮询和长轮询来说,能够实时传递数据,延迟更小。
  • 状态问题:相较于HTTP的无状态请求,WebSocket在建立连接后能够维持特定的状态。

二、WebSocket协议内容

WebSocket协议是通过HTTP协议升级而来。只需要在HTTP协议基础上增加两次握手,即可建立WebSocket连接(如果是需要通过SSL加密,则还需要进行SSL握手过程),下面我们简单介绍以下Header相关字段。

1.请求Header

请求Header如下:

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

其中:

  • Host: server.example.com:表示将要连接的WebSocket地址。
  • Connection: Upgrade:需要升级HTTP连接。
  • Upgrade: websocket:将HTTP连接升级至WebSocket连接。
  • Sec-WebSocket-Key:dGhlIHNhbXBsZSBub25jZQ== :客户端生成的WebSocket连接密钥。
  • Sec-WebSocket-Protocol: chat, superchat:指定哪些协议是客户端可以接受的。
  • Sec-WebSocket-Version: 13:WebSocket版本号。

2.响应Header

响应Header如下:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

其中:

  • Upgrade: websocket:确认将HTTP连接升级至WebSocket连接。
    -Connection: Upgrade :确认升级HTTP连接。
  • Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo:服务端根据客户端的连接密钥生成的服务端密钥。
  • Sec-WebSocket-Protocol: chat:选择的WebSocket协议。

三、WebSocket API介绍

对WebSocket的协议有了一个初步的了解,下面让我们看下,在具体的使用场景中,如何使用WebSocket。

WebSocket的API不多,下面我们就根据使用的顺序:

  • 建立连接
  • 收到消息
  • 发送消息
  • 关闭连接

1.建立连接

WebSocket通过初始化实例来建立连接,通过 open 事件回调函数来确认连接建立成功,具体示例如下:

const webSocket = new WebSocket('ws://server.example.com');

webSocket.addEventListener('open', (event) => {
    // 建立连接成功
});

在WebSocket建立ws连接时,url可以是域名或者IP地址;但是当建立的连接是wss(加密WebSocket)时,url必须是域名,因为需要配置相应的证书,而证书是针对域名的。

2.收到消息

WebSocket通过 message 事件来接收消息。

socket.addEventListener('message', function (event) {
    console.log('Message from server', event.data);
});

WebSocket可以传递 String ArrayBuffer Blob 三种数据类型,因此在收到消息时可能是其中的任意一种。其中, String ArrayBuffer 使用的最多。

  • 如果是 String 类型,直接通过字符串处理函数即可进行相关转换,如JSON等格式。
  • 如果是二进制 Blob 类型,则需要使用ArrayBuffer和DataView来进行处理。

3.发送消息

WebSocket通过 send 方法来发送消息。


webSocket.send(data);

示例中的data字段,也有可能是收到消息所说的String、ArrayBuffer和Blob三种数据类型之一。

4.关闭连接

4.1 被动关闭

当服务端主动关闭WebSocket连接时,会通过WebSocket向客户端发送一个close数据包,WebSocket的 close 事件会触发。此时,客户端是被动关闭了连接。

webSocket.addEventListener('close', (closeEvent) => {
    
});

注:当网络断开时,WebSocket连接并不会被动关闭,因为没有收到关闭的数据包。

4.2 主动关闭

客户端可以通过WebSocket提供的 close 方法来主动关闭长连接。


webSocket.close();

目前该方法有两个参数:

  • 第一个参数表示关闭连接的状态号,默认为1000,表示正常关闭。
  • 第二个参数为关闭原因,是一个不长于123字节的UTF-8文本。

四、基础知识

1.后端基础知识

  1. 后端通过配置文件注册一个ServerEndpointExporter类型的bean,顾名思义,该类叫做服务端点导出器,该bean会自动扫描并组测用注解@ServerEndpoint标记的类。

  2. 使用@ServerEndpoint标注的类,会被ServerEndpointExporter扫描注册成一个服务端点,可以理解为一个webSocket的服务器,@ServerEndpoint具有一个value属性,该属性用来指定连接该服务端点的uri,该uri可以包含如/chatServer/{id}这样的uri模板,只要id不同则可进行多个webSocket连接,否则如value设置为"/chatServer"的服务端点将只会接受一个uri为"/chatServer"的连接。

  3. @ServerEndpoint标注的服务端点类,包含一下几个常用的注解

  • @OnOpen

用于监听建立连接,当有客户端与该服务端点建立连接时,将会自回调该注解标注的方法

  • @OnClose

用于监听连接关闭,当客户端与该服务端点断开连接时,将会回调该注解标注的方法

  • @OnError

用于监听该连接上的任何错误,当客户端与该服务端点的连接发生任何异常,都将回调该注解标注的方法

注意该方法的参数必选Throwable,可选Sessiion以及0-n个String参数,且String参数需要使用@PathParam注解标注

  • @OnMessage

用于监听客户端向服务端发送消息,当客户端与服务端发送消息时,将会回调该注解标注的方法

  • @OnPathParam

用以获取连接上的uri模块中的值

  1. session对象

一个session即一个webSocket连接,使用对应的session调用其getBasicRemote().sendText(“message”)即可向其发送消息

2.前端基础知识

  1. 构建一个连接服务端点的socketUrl,WebSocket使用的是ws协议,所以以ws开头,uri和后端服务端点定义的value保持一致,如@ServerEndpoint(value=“/chatServer/{username}”)

let socketUrl = "ws://localhost:8080/chatServer/" + username;

  1. 根据socketUrl创建一个socket对象

const socket = new WebSocket(socketUrl);

  1. 为socket对象的属性设置回调函数
//连接建立时触发
socket.opopen = () - > {}
//接收到来自服务器的消息时触发
socket.onmessage = () -> {}
//连接关闭时触发
socket.onclose= () -> {}
//连接发生异常时触发
socket.οnerrοr= ()-> {}
  1. 使用socket对象的方法发送消息

socket.send("message")
  1. 关闭socket的连接

socket.close();

五、总体实现思路

后端利用@ServerEndpointExporter和@ServerEndpoint注册一个WebSocket的服务端点,并通过注解监听相应的事件,前端创建一个WebSocket的对象,通过为WebSocket的属性设置回调函数监听以及send()方法向服务器发送消息

业务细节:

后端需要使用一个集合保存当前连接的用户的session,用于向这些session连接发送消息,最好为每个session使用一个key标记

比如使用hashMap,key为用户名,value为该用户的session,接收到消息时根据消息中的用户名去拿到对应的消息,然后向其发送消息。

六、总结

本文主要是介绍了一下WebSocket相关的基础知识。

通过WebSocket的长连接,客户端和服务端可以进行大量的数据传输而不会带来相关的性能问题,这给Web端带来了极大的功能增强。目前Web端可以使用WebSocket来进行IM相关功能开发,或者实时协作等需要与服务端进行大量数据交互的功能,并且不需要像之前一样使用长轮询的Hack方式来实现。文章来源地址https://www.toymoban.com/news/detail-521225.html

到了这里,关于WebSocket系列之基础知识以及设计思路的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数字电路基础知识系列(六)之LC滤波器的基础知识

    LC滤波器,是指将电感(L)与电容器 ©进行组合设计构成的滤波电路,可去除或通过特定频率的无源器件。电容器具有隔直流通交流,且交流频率越高越容易通过的特性。而电感则具有隔交流通直流,且交流频率越高越不易通过的特性。因此,电容器和电感是特性完全相反的被

    2024年02月03日
    浏览(89)
  • Elasticsearch系列-基础知识

    Elasticsearch是一个开源的分布式搜索和分析引擎,它能够快速地存储、搜索和分析大量的数据。 特点 分布式:Elasticsearch采用分布式架构,可以水平扩展,支持无缝添加节点,提高了系统的可用性和性能。 实时性:Elasticsearch能够实时地存储、搜索和分析数据,支持实时索引和

    2024年02月09日
    浏览(48)
  • Ribbon基础知识以及相关配置

    1、什么是Ribbon Ribbon 是 Netflix 发布的一个负载均衡器,有助于控制HTTP和TCP客户端行为在 SpringCloud 中,Nacos一般配合Ribbon进行使用,Ribbon提供了客户端负载均衡的功能,Ribbon利用从Nacos中读取到的服务信息,在调用服务节点提供的服务时,会合理的进行负载。 在SpringCloud中可以

    2024年02月10日
    浏览(48)
  • 2023美赛基础知识以及如何入门

    报名截止时间: 北京时间2023年2月17日00:00 比赛时间: (北京时间:2023年2月17日,早晨6:00点,星期五)至(北京时间:2023年2月21日,上午9:00,星期二) 提交截止日期: (北京时间:2023年2月21日,上午10:00,星期二) 比赛结果: 结果将于2023年5月20日或之前发布。 报名

    2024年02月01日
    浏览(45)
  • Spark避坑系列一(基础知识)

    大家想了解更多大数据相关内容请移驾我的课堂: 大数据相关课程 剖析及实践企业级大数据 数据架构规划设计 大厂架构师知识梳理:剖析及实践数据建模 剖析及实践数据资产运营平台 Spark作为大数据领域离线计算的王者,在分布式数据处理计算领域有着极高的处理效率,

    2024年02月02日
    浏览(48)
  • ChatGPT基础知识系列之Prompt

    在 ChatGPT 中,用户可以输入任何问题或者话题,如天气、体育、新闻等等。系统将这个输入作为一个“提示”(prompt)输入到 GPT 模型中进行处理。GPT 模型会基于其学习到的语言规律和上下文知识,生成一个自然语言回答,并返回给用户。 例如,当用户输入“明天天气怎么样

    2024年02月14日
    浏览(42)
  • WebGL系列教程:WebGL基础知识

    下面我们来正式学习WebGL开发中的一些基本的概念和知识。 为了在 Web 上创建图形应用程序,HTML5 提供了一组丰富的功能,例如 2D Canvas、WebGL、SVG、3D CSS 转换和 SMIL。要编写 WebGL 应用程序,就需要用到 HTML5 的画布元素。 HTML5 的标签提供了一个简单而强大的选项来实现 JavaSc

    2024年02月14日
    浏览(46)
  • ChatGPT基础知识系列之Embeddings模型

    OpenAI的Embeddings(文本嵌入)测量的是文本字符串的相关性。嵌入通常用于: 搜索(根据与查询字符串的相关性对结果进行排名) 聚类(其中文本字符串按相似性分组) 建议(推荐具有相关文本字符串的项目) 异常检测(识别出相关性很小的异常值) 多样性测量(分析相似性

    2024年02月06日
    浏览(38)
  • [FPGA] 7系列FPGA的基础知识

    Virtex-7 Family是Xilinx公司推出的一系列FPGA器件,采用了28纳米工艺制造。它是Xilinx公司的第一个采用28纳米工艺的FPGA系列,提供了高性能、低功耗和灵活性的特点。 Virtex-7 Family提供了不同规模的器件,包括Virtex-7 XT、Virtex-7 HT、Virtex-7 H580T、Virtex-7 VXT和Virtex-7 VX系列,每个系列都

    2024年02月09日
    浏览(45)
  • uniapp快速入门系列(1)- 概述与基础知识

    1.1.1 什么是uniapp? uniapp是一款基于Vue.js框架的跨平台应用开发框架,它可以让开发者使用一套代码,同时构建多个平台(包括但不限于微信小程序、支付宝小程序、抖音小程序等)的应用程序。 在过去,我们可能需要分别使用不同的技术和工具来开发不同平台的应用,但是

    2024年02月07日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包