转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。

原文出处:https://blog.bitsrc.io/deep-dive-into-websockets-e6c4c7622423

 

在Internet发展的早期,Web应用程序是围绕由用户交互触发的HTTP请求而构建的。随着技术的进步,对实时数据传输和双向通信的需求出现了。这是低延迟应用程序的要求,例如

  • 多人在线游戏
  • 聊天应用
  • 实时更新社交供稿
  • 实时体育记分牌,体育行情自动收录器等

解决以上应用场景的解决方案就是WebSockets,随着它在技术领域被广泛应用,出现了许多现成的库加入了应用程序中。因此,这导致了许多开发人员在不了解其内部原理的情况下开始使用这个技术,以至在某些情况下影响程序的执行效率。

所以为了尽可能使程序执行效率更高效,在这篇文章中,我将为您介绍WebSocket的基本属性及实现原理。

WebSockets架构

WebSockets的核心是定义了一个在客户端和服务器之间建立套接字连接的Web API。它允许自Web浏览器或服务器从任何方向上的数据通讯。此外,与HTTP相比,它还进行了多项优化,使其更适合实时通讯的场景。

实时通信

在HTTP请求中,浏览器发送Cookie和其他头信息需要使用几百个字节,由于这陡增的数据容量,从而增加了实时通信的额外开销。

不过,如果使用WebSockets,信息的尺寸很小,只有6个字节的开销(其中2个用于header报头,4个用于掩码值),因此,WebSockets更适合实时数据传输,尤其适合低延迟的应用场景。

WebSocket连接

打开WebSocket连接很简单。如果需要指定子协议,也可以使用第二个参数来完成。

// 创建一个Websocket连接
let socketConnection = new WebSocket('ws://websocket.mysite.com'); //创建一个使用子协议WebSocket连接
let socketConnection = new WebSocket('ws://websocket.mysite.com', ['soap', 'xmpp']);

创建Socket连接后,您可以向其附加事件处理程序,这样您就可以知道连接什么时候打开、什么时候接收消息以及什么时候出现错误。

// 当连接打开时,一些数据会被发送到服务器上。
socketConnection.onopen = function () {
connection.send('Hello, the socket connection is open!'); // Send a message to the server
}; // 记录错误日志
socketConnection.onerror = function (error) {
console.log('WebSocket Error ' + error);
}; // 记录来自服务器的消息
socketConnection.onmessage = function (e) {
console.log('Server: ' + e.data);
};

连接建立后,将在WebSocket实例上触发onopen事件。

这意味着握手的完成,从这个事件开始后,任何一方(服务器和客户端)都可以随时向对方发送数据。当WebSocket在客户端接收数据时,将触发OnMessage事件,OnError事件可用于错误处理。

这时候,你可能会有疑问,我们不是一直都在这样做吗,建立连接,监听消息。还有什么其他内容吗?

那么,我们下面就一起来看看,如何能更高效执行WebSocket。对于WebSockets,我们如何处理连接非常重要,同时我们如何处理连接和连接错误重试也将决定通信的总体容错能力。

容错连接重试

在使用WebSockets时,一个常见的问题就是连接中断。当客户端或服务器没有响应时,就会发生这种情况。为了避免由此产生的任何问题,您应该实现一种优雅地机制便于关闭套接字连接。特别在当 WebSocket 连接时间较长的情况下,需要实现不时刷新连接(关闭并再次打开连接)的方法,以实现流畅的通信系统。

扩展连接

由于WebSocket具有持久连接的特性,因此需要高可用性,所以服务器应该具有可伸缩性,以满足需要时的高需求。但是,在打开ws连接后,大部分时间它将处于空闲状态。

那么我们应该如何扩展WebSocket后端?

扩展WebSocket后端是一项复杂的任务,它需要持久存储任何服务器节点在出现故障时的连接和传递的消息。此外,考虑开放连接的数量,最好实施横向扩展策略。由于大多数用户可能不经常重新连接,因此基于开放式连接来提高可伸缩性更为有意义。

数据传输模式

在通过WebSocket传输数据时,您可以考虑不同的模式。您可以直接通过WebSockets传输消息,也可以向客户端发送通知,告知消息的可用性。

用于发送Web应用通知的WebSockets

发送应用内通知是WebSockets的常见用例。WebSocket连接仅用于提醒浏览器有新消息可用。

一旦用户收到通知并访问通知页面,应用程序就可以发送HTTP请求来检索消息内容。

所以在这种方法中,WebSocket并不发送实际的消息内容,而是作为一种信令机制来通知前端的通知可用性。

使用WebSocket进行实时数据传输

对于在实时多人游戏或聊天应用程序,需要无延迟地发送数据,因为总是有用户盯着屏幕等待数据。

在此场景中,我们可以通过WebSocket连接直接发送消息数据,以便更快地传递消息。

数据压缩

对于WebSockets,压缩不是经常讨论的话题。但是,如果需要实时发送大量数据,则使用压缩方法是有用的。

但是,要使用WebSockets实现数据压缩,客户端和服务器都需要在这一点上达成一致。

您知道WebSockets提供了数据压缩扩展吗?

当客户端通过在SEC-WebSocket-Extensions头中通告permessage-deflate扩展来发起协商时,服务器必须通过在其响应中回显来确认通告的扩展。

客户端启动:

GET /socket HTTP/1.1
Host: thirdparty.com
Origin: http://example.com
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Extensions: permessage-deflate
 
服务端响应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Access-Control-Allow-Origin: http://example.com
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Extensions: permessage-deflate

WebSockets安全

WebSocket允许无限数量的消息到达服务器。这很容易让攻击者有权执行DoS攻击。

因此,必须使用身份验证机制来加强安全性。常见的用法之一是使用JWT令牌,这样可以更快地验证请求的签名。

此外,使用wss而不是ws是至关重要的,这将保护通信隧道,类似于HTTPS。

浏览器兼容性

WebSocket与几乎所有浏览器都具有良好的浏览器兼容性。

此外,WebSocket还内置了跨域通信。它允许与任何域上的任何方进行通信。这可以通过定义服务器可以与之通信的域进行控制,从而提高安全性。

此外,流行的WebSockets实现(如Socket.IO(NodeJS)或SignalR(.NET))在较旧的浏览器中支持后退到HTTP。

结论

每当您需要客户端和服务器之间更好的低延迟连接时,WebSockets都是您的最佳选择。

然而,WebSockets集成到您现有的Web基础设施中可能会令人沮丧,因为它需要更改架构。此外,您还可以查看Event Sourcing模式,该模式有效地使用WebSocket进行通信。

请在下面的评论中告诉我您想知道的关于WebSockets的更多详细信息。您可以点击这里查看WebSocket连接演示。

每个开发人员都应该知道的WebSockets知识的更多相关文章

  1. PDB文件:每个开发人员都必须知道的 PDB Files

    PDB文件:每个开发人员都必须知道的   PDB Files: What Every Developer Must Knowhttp://www.wintellect.com/CS/blogs/jro ...

  2. pdb文件 PDB文件:每个开发人员都必须知道的 .NET PDB文件到底是什么?

    pdb文件包含了编译后程序指向源代码的位置信息,用于调试的时候定位到源代码,主要是用来方便调试的. 在程序发布为release模式时,建议将 pdb文件删除, 同时,对外发布的时候,也把 pdb删除, ...

  3. 每个Java开发人员都应该知道的10个基本工具

    大家好,我们已经在2019年的第9个月,我相信你们所有人已经在2019年学到了什么,以及如何实现这些目标.我一直在写一系列文章,为你提供一些关于你可以学习和改进的想法,以便在2019年成为一个更好的. ...

  4. 每个Java开发人员都应该知道的4个Spring注解

    这是每个Java开发人员都应该知道的最重要的Spring注解.感谢优锐课老师对本文提供的一些帮助. 随着越来越多的功能被打包到单个应用程序或一组应用程序中,现代应用程序的复杂性从未停止增长.尽管这种增 ...

  5. 每个开发人员都应该知道的11个Linux命令

    本文主要挑选出读者有必要首先学习的 11 个 Linux 命令,如果不熟悉的读者可以在虚拟机或云服务器上实操下,对于开发人员来说,能熟练掌握 Linux 做一些基本的操作是必要的! 事不宜迟,这里有 ...

  6. 【vs调试】PDB 文件:每个开发人员都必须知道的

    [vs调试]PDB文件:每个开发人员都必须知道的 GDB:The GNU Project Debugger, 将会包含代码中符号(自定义变量, 数据类型), 还有函数调用或类引用的关联性, 有了pdb ...

  7. PDB文件:每个开发人员都必须知道的

    PDB Files: What Every Developer Must Knowhttp://www.wintellect.com/CS/blogs/jrobbins/archive/2009/05 ...

  8. 隔壁小孩都要知道的Drupal配置

    i春秋作家:Arizona 原文来自:隔壁小孩都要知道的Drupal配置 隔壁小孩都要知道的Drupal配置 Drupal是一个开源的PHP内容管理系统,具有相当复杂的架构.它还具有强大的安全模型.感 ...

  9. 每个开发者都应该知道的SOLID原则

    每个开发者都应该知道的SOLID原则 单一职责原则(SRP) 它为什么违反了 SRP? 这种设计将来会带来什么问题? 开闭原则(OCP) 如何使它(AnimalSound)符合 OCP? 里氏替换原则 ...

随机推荐

  1. [ABP教程]第一章 创建服务端

    Web应用程序开发教程 - 第一章: 创建服务端 关于本教程 在本系列教程中, 你将构建一个名为 Acme.BookStore 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开发 ...

  2. 不吹不黑,jupyter lab 3.0客观使用体验

    1 简介 jupyter lab于近期发布了其具有里程碑意义的3.0版本,随之带来的一些重要新特性,想必广大读者朋友已在各大公众号所翻译转载的jupyter lab团队官方介绍文章中知晓了很多. 图1 ...

  3. i5 11300H 怎么样 相当于什么水平

    i5-11300H 为 4 核 8 线程,主频 3.1GHz,睿频 4.4GHz,三级缓存 8MBi5-11300H 怎么样看完你就知道了 https://list.jd.com/list.html?

  4. Command2

    Ctrl^c 强制终止当前命令执行 chmod {ugoa(user/group/other/all)}{+-=(wrx权限增删改)} 文件或目录 权限 对文件 对目录 r 可查看文件内容 可以列出目 ...

  5. 【JavaWeb】XML 文件

    XML 文件 简介 XML 是可拓展的标记性语言. XML 的主要作用: 用来保存数据,且这些数据具有自我描述性: 作为项目或模块的配置文件: 作为网络数据传输的格式,但是现在以 JSON 格式为主. ...

  6. 机器学习算法·KNN

    机器学习算法应用·KNN算法 一.问题描述 验证码目前在互联网上非常常见,从学校的教务系统到12306购票系统,充当着防火墙的功能.但是随着OCR技术的发展,验证码暴露出的安全问题越来越严峻.目前对验 ...

  7. MySQL select if 查询最后一个主键 id

    查询最后一个主键id SELECT IF(MAX(id) IS NULL, 0, MAX(id)) AS maxid FROM users; 查询最小的主键id SELECT IF(MIN(id) I ...

  8. python sqlite3增加表字段

    给sqlite3表格增加新字段,要注意大小写,要不然不成功. 一开始这样写,不成功! 后面规范写,按大小写严格规范写! 成功了!现在查看新增加的字段commit: 仔细看,这下全部小写,括表名称.co ...

  9. poj-DNA排序

    描述 现在有一些长度相等的DNA串(只由ACGT四个字母组成),请将它们按照逆序对的数量多少排序. 逆序对指的是字符串A中的两个字符A[i].A[j],具有i < j 且 A[i] > A ...

  10. [Usaco2016 Dec]Counting Haybales

    原题链接https://www.lydsy.com/JudgeOnline/problem.php?id=4747 先将原数组排序,然后二分查找即可.时间复杂度\(O((N+Q)logN)\). #i ...