【腾讯Bugly干货分享】WebSocket 浅析

2024-03-23 18:48

本文主要是介绍【腾讯Bugly干货分享】WebSocket 浅析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/7aXMdnajINt0C5dcJy2USg

前言

在WebSocket API尚未被众多浏览器实现和发布的时期,开发者在开发需要接收来自服务器的实时通知应用程序时,不得不求助于一些“hacks”来模拟实时连接以实现实时通信,最流行的一种方式是长轮询 。 长轮询主要是发出一个HTTP请求到服务器,然后保持连接打开以允许服务器在稍后的时间响应(由服务器确定)。为了这个连接有效地工作,许多技术需要被用于确保消息不错过,如需要在服务器端缓存和记录多个的连接信息(每个客户)。虽然长轮询是可以解决这一问题的,但它会耗费更多的资源,如CPU、内存和带宽等,要想很好的解决实时通信问题就需要设计和发布一种新的协议。

WebSocket 是伴随HTML5发布的一种新协议。它实现了浏览器与服务器全双工通信(full-duplex),可以传输基于消息的文本和二进制数据。WebSocket 是浏览器中最靠近套接字的API,除最初建立连接时需要借助于现有的HTTP协议,其他时候直接基于TCP完成通信。它是浏览器中最通用、最灵活的一个传输机制,其极简的API 可以让我们在客户端和服务器之间以数据流的形式实现各种应用数据交换(包括JSON 及自定义的二进制消息格式),而且两端都可以随时向另一端发送数据。在这个简单的API 之后隐藏了很多的复杂性,而且还提供了更多服务,如:

  • 连接协商和同源策略;
  • 与既有 HTTP 基础设施的互操作;
  • 基于消息的通信和高效消息分帧;
  • 子协议协商及可扩展能力。

所幸,浏览器替我们完成了上述工作,我们只需要简单的调用即可。任何事物都不是完美的,设计限制和性能权衡始终会有,利用WebSocket 也不例外,在提供自定义数据交换协议同时,也不再享有在一些本由浏览器提供的服务和优化,如状态管理、压缩、缓存等。

随着HTML5的发布,越来越多的浏览器开始支持WebSocket,如果你的应用还在使用长轮询,那就可以考虑切换了。下面的图表显示了在一种常见的使用案例下,WebSocket和长轮询之间的带宽消耗差异:

1.WebSocket API

WebSocket 对象提供了一组 API,用于创建和管理 WebSocket 连接,以及通过连接发送和接收数据。浏览器提供的WebSocket API很简洁,调用示例如下:

var ws = new WebSocket('wss://example.com/socket'); // 创建安全WebSocket 连接(wss)ws.onerror = function (error) { ... } // 错误处理
ws.onclose = function () { ... } // 关闭时调用ws.onopen = function () { // 连接建立时调用ws.send("Connection established. Hello server!"); // 向服务端发送消息
}ws.onmessage = function(msg) { // 接收服务端发送的消息if(msg.data instanceof Blob) { // 处理二进制信息processBlob(msg.data);} else {processText(msg.data); // 处理文本信息}
}

1.1.接收和发送数据

WebSocket提供了极简的API,开发者可以轻松的调用,浏览器会为我们完成缓冲、解析、重建接收到的数据等工作。应用只需监听onmessage事件,用回调处理返回数据即可。 WebSocket支持文本和二进制数据传输,浏览器如果接收到文本数据,会将其转换为DOMString 对象,如果是二进制数据或Blob 对象,可直接将其转交给应用或将其转化为ArrayBuffer,由应用对其进行进一步处理。从内部看,协议只关注消息的两个信息:净荷长度和类型(前者是一个可变长度字段),据以区别UTF-8 数据和二进制数据。示例如下:

var wss = new WebSocket('wss://example.com/socket');
ws.binaryType = "arraybuffer"; // 接收数据
wss.onmessage = function(msg) {if(msg.data instanceof ArrayBuffer) {processArrayBuffer(msg.data);} else {processText(msg.data);}
}// 发送数据
ws.onopen = function () {socket.send("Hello server!"); socket.send(JSON.stringify({'msg': 'payload'}));var buffer = new ArrayBuffer(128);socket.send(buffer);var intview = new Uint32Array(buffer);socket.send(intview);var blob = new Blob([buffer]);socket.send(blob); 
}

Blob 对象是包含有只读原始数据的类文件对象,可存储二进制数据,它会被写入磁盘;ArrayBuffer (缓冲数组)是一种用于呈现通用、固定长度的二进制数据的类型,作为内存区域可以存放多种类型的数据。

对于将要传输的二进制数据,开发者可以决定以何种方式处理,可以更好的处理数据流,Blob 对象一般用来表示一个不可变文件对象或原始数据,如果你不需要修改它或者不需要把它切分成更小的块,那这种格式是理想的;如果你还需要再处理接收到的二进制数据,那么选择ArrayBuffer 应该更合适。

WebSocket 提供的信道是全双工的,在同一个TCP 连接上,可以双向传输文本信息和二进制数据,通过数据帧中的一位(bit)来区分二进制或者文本。WebSocket 只提供了最基础的文本和二进制数据传输功能,如果需要传输其他类型的数据,就需要通过额外的机制进行协商。WebSocket 中的send( ) 方法是异步的:提供的数据会在客户端排队,而函数则立即返回。在传输大文件时,不要因为回调已经执行,就错误地以为数据已经发送出去了,数据很可能还在排队。要监控在浏览器中排队的数据量,可以查询套接字的bufferedAmount 属性:

var ws = new WebSocket('wss://example.com/socket');ws.onopen = function () {subscribeToApplicationUpdates(function(evt) { if (ws.bufferedAmount == 0) ws.send(evt.data); });
};

前面的例子是向服务器发送应用数据,所有WebSocket 消息都会按照它们在客户端排队的次序逐个发送。因此,大量排队的消息,甚至一个大

这篇关于【腾讯Bugly干货分享】WebSocket 浅析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/839201

相关文章

浅析CSS 中z - index属性的作用及在什么情况下会失效

《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

Python解析器安装指南分享(Mac/Windows/Linux)

《Python解析器安装指南分享(Mac/Windows/Linux)》:本文主要介绍Python解析器安装指南(Mac/Windows/Linux),具有很好的参考价值,希望对大家有所帮助,如有... 目NMNkN录1js. 安装包下载1.1 python 下载官网2.核心安装方式3. MACOS 系统安

Java springBoot初步使用websocket的代码示例

《JavaspringBoot初步使用websocket的代码示例》:本文主要介绍JavaspringBoot初步使用websocket的相关资料,WebSocket是一种实现实时双向通信的协... 目录一、什么是websocket二、依赖坐标地址1.springBoot父级依赖2.springBoot依赖

Java嵌套for循环优化方案分享

《Java嵌套for循环优化方案分享》介绍了Java中嵌套for循环的优化方法,包括减少循环次数、合并循环、使用更高效的数据结构、并行处理、预处理和缓存、算法优化、尽量减少对象创建以及本地变量优化,通... 目录Java 嵌套 for 循环优化方案1. 减少循环次数2. 合并循环3. 使用更高效的数据结构4

浅析Python中的绝对导入与相对导入

《浅析Python中的绝对导入与相对导入》这篇文章主要为大家详细介绍了Python中的绝对导入与相对导入的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1 Imports快速介绍2 import语句的语法2.1 基本使用2.2 导入声明的样式3 绝对import和相对i

Python中常用的四种取整方式分享

《Python中常用的四种取整方式分享》在数据处理和数值计算中,取整操作是非常常见的需求,Python提供了多种取整方式,本文为大家整理了四种常用的方法,希望对大家有所帮助... 目录引言向零取整(Truncate)向下取整(Floor)向上取整(Ceil)四舍五入(Round)四种取整方式的对比综合示例应

浅析如何使用Swagger生成带权限控制的API文档

《浅析如何使用Swagger生成带权限控制的API文档》当涉及到权限控制时,如何生成既安全又详细的API文档就成了一个关键问题,所以这篇文章小编就来和大家好好聊聊如何用Swagger来生成带有... 目录准备工作配置 Swagger权限控制给 API 加上权限注解查看文档注意事项在咱们的开发工作里,API

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

JavaWeb-WebSocket浏览器服务器双向通信方式

《JavaWeb-WebSocket浏览器服务器双向通信方式》文章介绍了WebSocket协议的工作原理和应用场景,包括与HTTP的对比,接着,详细介绍了如何在Java中使用WebSocket,包括配... 目录一、概述二、入门2.1 POM依赖2.2 编写配置类2.3 编写WebSocket服务2.4 浏

MySQL8.2.0安装教程分享

《MySQL8.2.0安装教程分享》这篇文章详细介绍了如何在Windows系统上安装MySQL数据库软件,包括下载、安装、配置和设置环境变量的步骤... 目录mysql的安装图文1.python访问网址2javascript.点击3.进入Downloads向下滑动4.选择Community Server5.