每个开发人员都应该知道的WebSockets知识
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。
原文出处: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知识的更多相关文章
- PDB文件:每个开发人员都必须知道的 PDB Files
PDB文件:每个开发人员都必须知道的 PDB Files: What Every Developer Must Knowhttp://www.wintellect.com/CS/blogs/jro ...
- pdb文件 PDB文件:每个开发人员都必须知道的 .NET PDB文件到底是什么?
pdb文件包含了编译后程序指向源代码的位置信息,用于调试的时候定位到源代码,主要是用来方便调试的. 在程序发布为release模式时,建议将 pdb文件删除, 同时,对外发布的时候,也把 pdb删除, ...
- 每个Java开发人员都应该知道的10个基本工具
大家好,我们已经在2019年的第9个月,我相信你们所有人已经在2019年学到了什么,以及如何实现这些目标.我一直在写一系列文章,为你提供一些关于你可以学习和改进的想法,以便在2019年成为一个更好的. ...
- 每个Java开发人员都应该知道的4个Spring注解
这是每个Java开发人员都应该知道的最重要的Spring注解.感谢优锐课老师对本文提供的一些帮助. 随着越来越多的功能被打包到单个应用程序或一组应用程序中,现代应用程序的复杂性从未停止增长.尽管这种增 ...
- 每个开发人员都应该知道的11个Linux命令
本文主要挑选出读者有必要首先学习的 11 个 Linux 命令,如果不熟悉的读者可以在虚拟机或云服务器上实操下,对于开发人员来说,能熟练掌握 Linux 做一些基本的操作是必要的! 事不宜迟,这里有 ...
- 【vs调试】PDB 文件:每个开发人员都必须知道的
[vs调试]PDB文件:每个开发人员都必须知道的 GDB:The GNU Project Debugger, 将会包含代码中符号(自定义变量, 数据类型), 还有函数调用或类引用的关联性, 有了pdb ...
- PDB文件:每个开发人员都必须知道的
PDB Files: What Every Developer Must Knowhttp://www.wintellect.com/CS/blogs/jrobbins/archive/2009/05 ...
- 隔壁小孩都要知道的Drupal配置
i春秋作家:Arizona 原文来自:隔壁小孩都要知道的Drupal配置 隔壁小孩都要知道的Drupal配置 Drupal是一个开源的PHP内容管理系统,具有相当复杂的架构.它还具有强大的安全模型.感 ...
- 每个开发者都应该知道的SOLID原则
每个开发者都应该知道的SOLID原则 单一职责原则(SRP) 它为什么违反了 SRP? 这种设计将来会带来什么问题? 开闭原则(OCP) 如何使它(AnimalSound)符合 OCP? 里氏替换原则 ...
随机推荐
- Elasticsearch节点下线(退役)and unassigned shards
一.节点退役当集群中个别节点出现故障预警等情况,需要进行退役工作,即让所有位于该退役节点上的分片的数据分配到其他节点上后,再将此节点关闭并从集群中移除. 1.ES提供了让某个节点上所有数据都移走的功能 ...
- NAT模式/路由模式/全路由模式 (转)
route全路由NAT NAT模式.此模式下,由局域网向广域网发送的数据包默认经过NAT转换,但路由器对所有源地址与局域网接口不在同一网段的数据包均不进行处理.例如,路由器LAN口IP设置为192.1 ...
- 04--Docker数据卷和数据卷容器
.为什么要使用数据卷: Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了.为了能保存数据在docke ...
- Centos7 虚拟机优化
配置yum源 rm -f /etc/yum.repos.d/* curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/ ...
- 网络可视化工具netron详细安装流程
1.netron 简介 在实际的项目中,经过会遇到各种网络模型,需要我们快速去了解网络结构.如果单纯的去看模型文件,脑海中很难直观的浮现网络的架构. 这时,就可以使用netron可视化工具,可以清晰的 ...
- linux编译模块,包含了头文件却还是报undifind警告
在编写一个自己写的gadget驱动的时候遇到一个这样的问题,编译的时候报了个警告:WARNING: "usb_composite_register" [-/my_zero.ko] ...
- 如何应对C语言内存泄露! 华为开发者社区 2020-09-29
如何应对C语言内存泄露! 华为开发者社区 2020-09-29
- Linux下unix socket 读写 抓包
Linux下unix socket 读写 抓包-ubuntuer-ChinaUnix博客 http://blog.chinaunix.net/uid-9950859-id-247877.html
- git database 数据库 平面文件 Git 同其他系统的重要区别 Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异 Git 的设计哲学
小结: 1.如果要浏览项目的历史更新摘要,Git 不用跑到外面的服务器上去取数据回来 2.注意 git clone 应指定版本,它复制的这个版本的全部历史信息: 各个分支 git init 数据库 ...
- CF42A
题意 给定两个序列 a 和 b. 序列 a 中的各个数之间的比例可以得出一个 x . 当 b 中比例满足 a 中比例,即 \(b_1\):\(b_2\):\(b_3\)-- \(=\) \(a_1\) ...