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

原文出处: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. 如何快速搭建hadoop集群

    安装好虚拟机,重命名为master 配置网卡 命令:vi /etc/sysconfig/network-scripts/ifcfg-en(按tab键) 这里要配置ip,网关,域名解析 例如我的 IPA ...

  2. Label_strange_labels

    空格符号  特殊符号名 注释语句 , align = "left right center" 粗体 斜体 也可能是控制标签 上标 下标 大字号 小字号 下划线 删除线 等宽 键盘输 ...

  3. 用python+sklearn(机器学习)实现天气预报数据 数据

    用python+sklearn机器学习实现天气预报 数据 项目地址 系列教程 勘误表 0.前言 1.爬虫 a.确认要被爬取的网页网址 b.爬虫部分 c.网页内容匹配取出部分 d.写入csv文件格式化 ...

  4. Flutter 基础组件:按钮

    前言 Material组件库中提供了多种按钮组件如RaisedButton.FlatButton.OutlineButton等,它们都是直接或间接对RawMaterialButton组件的包装定制,所 ...

  5. Docker 镜像管理及基础命令(二)

    Docker 常用命令: ## Docker 登录下载镜像: docker login # 登录官方hub.docker.com docker pull nginx:alpine # 下载nginx的 ...

  6. 【JS学习】数组过滤方法的使用filter

    前言:本博客系列为学习后盾人js教程过程中的记录与产出,如果对你有帮助,欢迎关注,点赞,分享.不足之处也欢迎指正,作者会积极思考与改正. 使用效果: 可以返回参数函数为真的值 //情景:实现从stu数 ...

  7. 【Linux】make编译的小技巧

    ------------------------------------------------------------------------------------------------- | ...

  8. 【Linux】实现端口转发的rinetd

    Linux下端口转发一般都使用iptables来实现,使用iptables可以很容易将TCP和UDP端口从防火墙转发到内部主机上.但是如果需要将流量从专用地址转发到不在您当前网络上的机器上,可尝试另一 ...

  9. 【七天搞定Python】day01.Python环境配置、pip、IDE、注释、变量,数据类型、标识符/关键字、输出、输入

    什么是Python? 动态解释型语言,1982年由荷兰人Guido von Rossum发明. 更多细节可以google,这里不做展开. Python解释器: CPython(官方版本C语言实现) I ...

  10. const关键字:终于拥有真正的常量声明语句

    本文首发于个人网站:const关键字:终于拥有真正的常量声明语句 你好,今天大叔想和你唠扯唠扯 ES6 新增的关键字 -- const.在说 const 关键字之前,大叔先和你唠唠大叔自己对 cons ...