WS协议—介绍及原理

news2024/12/26 21:11:08

举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。

WebSocket 协议在2008年诞生,2011年成为国际标准。所有浏览器都已经支持了。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

一、传统的实现即时通信的方式

1、ajax轮询

ajax轮询的原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。

场景再现:

客户端:啦啦啦,有没有新信息(Request)
服务端:没有(Response)
客户端:啦啦啦,有没有新信息(Request)
服务端:没有。。(Response)
客户端:啦啦啦,有没有新信息(Request)
服务端:你好烦啊,没有啊。。(Response)
客户端:啦啦啦,有没有新消息(Request)
服务端:好啦好啦,有啦给你。(Response)
客户端:啦啦啦,有没有新消息(Request)
服务端:。。。。。没。。。。没。。。没有(Response) —- loop

2、long poll

long poll 其实原理跟 ajax轮询 差不多,都是采用轮询的方式,不过采取的是阻塞模型(一直打电话,没收到就不挂电话),也就是说,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。

场景再现:

客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request)
服务端:额。。 等待到有消息的时候。。来 给你(Response)
客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request) -loop

从上面可以看出其实这两种方式,都是在不断地建立HTTP连接,然后等待服务端处理,可以体现HTTP协议的另外一个特点,被动性。何为被动性呢,其实就是,服务端不能主动联系客户端,只能有客户端发起。

小结:ajax轮询 需要服务器有很快的处理速度和资源。(速度)
long poll 需要有很高的并发,也就是说同时接待客户的能力。(场地大小)

3、长连接

在页面里嵌入一个隐蔵iframe,将这个隐蔵iframe的src属性设为对一个长连接的请求或是采用xhr请求,服务器端就能源源不断地往客户端输入数据。

优点:消息即时到达,不发无用请求;管理起来也相对方便。

缺点:服务器维护一个长连接会增加开销,当客户端越来越多的时候,server压力大!

实例:Gmail聊天

(1)基于http协议的长连接

      在HTTP1.0和HTTP1.1协议中都有对长连接的支持。其中HTTP1.0需要在request中增加”Connection: keep-alive“ header才能够支持,而HTTP1.1默认支持.

     http1.0请求与服务端的交互过程:

  • a)客户端发出带有包含一个header:”Connection: keep-alive“的请求
  • b)服务端接收到这个请求后,根据http1.0和”Connection: keep-alive“判断出这是一个长连接,就会在response的header中也增加”Connection: keep-alive“,同是不会关闭已建立的tcp连接.
  • c)客户端收到服务端的response后,发现其中包含”Connection: keep-alive“,就认为是一个长连接,不关闭这个连接。并用该连接再发送request.转到a)

(2)http1.1请求与服务端的交互过程

  • a)客户端发出http1.1的请求
  • b)服务端收到http1.1后就认为这是一个长连接,会在返回的response设置Connection: keep-alive,同是不会关闭已建立的连接.
  • c)客户端收到服务端的response后,发现其中包含”Connection: keep-alive“,就认为是一个长连接,不关闭这个连接。并用该连接再发送request.转到a)

    基于http协议的长连接减少了请求,减少了建立连接的时间,但是每次交互都是由客户端发起的,客户端发送消息,服务端才能返回客户端消息.因为客户端也不知道服务端什么时候会把结果准备好,所以客户端的很多请求是多余的,仅是维持一个心跳,浪费了带宽.

4、Flash Socket

在页面中内嵌入一个使用了Socket类的 Flash 程序JavaScript通过调用此Flash程序提供的Socket接口与服务器端的Socket接口进行通信,JavaScript在收到服务器端传送的信息后控制页面的显示。

优点:实现真正的即时通信,而不是伪即时。

缺点:客户端必须安装Flash插件,移动端支持不好,IOS系统中没有flash的存在;非HTTP协议,无法自动穿越防火墙。

二、websocket的方式实现服务端消息推送

1、什么是socket?什么是websocket?两者有什么区别?websocket是仅仅将socket的概念移植到浏览器中的实现吗?

我们知道,在网络中的两个应用程序(进程)需要全双工相互通信(全双工即双方可同时向对方发送消息),需要用到的就是socket,它能够提供端对端通信,对于程序员来讲,他只需要在某个应用程序的一端(暂且称之为客户端)创建一个socket实例并且提供它所要连接一端(暂且称之为服务端)的IP地址和端口,而另外一端(服务端)创建另一个socket并绑定本地端口进行监听,然后客户端进行连接服务端,服务端接受连接之后双方建立了一个端对端的TCP连接,在该连接上就可以双向通讯了,而且一旦建立这个连接之后,通信双方就没有客户端服务端之分了,提供的就是端对端通信了。我们可以采取这种方式构建一个桌面版的im程序,让不同主机上的用户发送消息。从本质上来说,socket并不是一个新的协议,它只是为了便于程序员进行网络编程而对tcp/ip协议族通信机制的一种封装。

socket传送门: socket-CRMEB社区

websocket是html5规范中的一个部分,它借鉴了socket这种思想,为web应用程序客户端和服务端之间(注意是客户端服务端)提供了一种全双工通信机制。同时,它又是一种新的应用层协议,websocket协议是为了提供web应用程序和服务端全双工通信而专门制定的一种应用层协议,通常它表示为:ws://echo.websocket.org/?encoding=text HTTP/1.1,可以看到除了前面的协议名和http不同之外,它的表示地址就是传统的url地址。

Websocket其实是一个新协议,跟HTTP协议基本没有关系,只是为了兼容现有浏览器的握手规范而已,也就是说它是HTTP协议上的一种补充可以通过这样一张图理解

websocket具有以下几个方面的优势:

  • (1)建立在 TCP 协议之上,服务器端的实现比较容易。
  • (2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
  • (3)数据格式比较轻量,性能开销小,通信高效。
  • (4)可以发送文本,也可以发送二进制数据。
  • (5)没有同源限制,客户端可以与任意服务器通信。
  • (6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

2、websocket的通信原理和机制

websocket传输使用的协议如下图:

Websocket是一个应用层协议,它必须依赖 HTTP 协议进行一次握手 ,握手成功后,数据就直接从 TCP 通道传输,与 HTTP 无关了。即:websocket分为握手和数据传输阶段,即进行了HTTP握手 + 双工的TCP连接。既然是基于浏览器端的web技术,那么它的通信肯定少不了http,websocket本身虽然也是一种新的应用层协议,但是它也不能够脱离http而单独存在。具体来讲,我们在客户端构建一个websocket实例,并且为它绑定一个需要连接到的服务器地址,当客户端连接服务端的时候,会向服务端发送一个类似下面的http报文

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Version: 13

客户端发起的WebSocket连接报文类似传统HTTP报文,其中:

  • Upgrade: websocket
    Connection: Upgrade
    这个是WebSocket的核心,告诉服务器,客户端发起的是WebSocket类型请求。Sec-WebSocket-Key是WebSocket客户端发送的一个 base64编码的密文,浏览器随机生成,要求服务端必须返回一个对应加密的Sec-WebSocket-Accept应答,否则客户端会抛出Error during WebSocket handshake错误,并关闭连接。
  • Sec-WebSocket-Version 是告诉服务器所使用的 Websocket 协议版本

服务端收到报文后会返回下列东西,表示已经接收到请求,WebSocket建立成功,来自服务器的握手如下:

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

  • Upgrade: websocket
  • Connection: Upgrade(告诉客户端即将升级的是WebSocket协议)
  • Sec-WebSocket-Accept的值是服务端采用与客户端一致的密钥计算出来后返回客户端的

至此,HTTP已经完成它所有工作,接下来就是完全按照Websocket协议进行了。

这里值得注意的是Sec-WebSocket-Accept的计算方法:

base64(hsa1(sec-websocket-key + 258EAFA5-E914-47DA-95CA-C5AB0DC85B11))

如果这个Sec-WebSocket-Accept计算错误浏览器会提示:Sec-WebSocket-Accept dismatch

如果返回成功,Websocket就会回调onopen事件。

通过查看WebSocket的原理,与HTTP对比,得出结论:

HTTP长连接中,每次数据交换除了真正的数据部分外,服务器和客户端还要大量交换HTTP header,信息交换效率很低。Websocket协议通过第一个请求建立了TCP连接之后,之后交换的数据都不需要发送 HTTP header就能交换数据,这显然和原有的HTTP协议有区别,所以它需要对服务器和客户端都进行升级才能实现(主流浏览器都已支持HTML5)。

此外还有 multiplexing、不同的URL可以复用同一个WebSocket连接等功能。这些都是HTTP长连接不能做到的。

基于以上分析,我们可以看到,websocket能够提供低延迟,高性能的客户端与服务端的双向数据通信。它颠覆了之前web开发的请求处理响应模式,并且提供了一种真正意义上的客户端请求,服务器推送数据的模式,特别适合实时数据交互应用开发。

对比前面的http的客户端服务器的交互图可以发现WebSocket方式减少了很多TCP打开和关闭连接的操作,WebSocket的资源利用率高。

3、websocket的创建和常用的属性方法

以下 API 用于创建 WebSocket 对象。

var Socket = new WebSocket(url, [protocol] );

以上代码中的第一个参数 url, 指定连接的 URL。第二个参数 protocol 是可选的,指定了可接受的子协议。

WebSocket 属性

以下是 WebSocket 对象的属性。假定我们使用了以上代码创建了 Socket 对象:

CONNECTING:值为0,表示正在连接。

OPEN:值为1,表示连接成功,可以通信了。

CLOSING:值为2,表示连接正在关闭。

CLOSED:值为3,表示连接已经关闭,或者打开连接失败。

 var webSocket = new WebSocket(url);
  if(webSocket.readyState == webSocket.CONNECTING){
    console.log('连接正在打开');
  }
 
  webSocket.onopen = function () {
    webSocket.send(consumerId);
    //可以看到 "连接正在打开"并没有被打印,说明open对应的就是OPEN状态;
    if(webSocket.readyState == webSocket.CONNECTING){
      console.log('连接正在打开1');
    }
    if(webSocket.readyState == webSocket.OPEN){
      console.log('连接已打开');
    }
    sendMsg();
    window.weui.alert('已经建立连接');
  };
 
//连接关闭时触发
  webSocket.onclose = function () {
    if(webSocket.readyState == webSocket.CLOSED){
      console.log('连接已关闭')
    }
      window.weui.alert('连接已断开');
  };
 
  //连接
  webSocket.onerror = function () {
    window.weui.alert('连接错误,请稍后再试');
  };

可以看到,当onopen触发时,对应的就是readyState的OPEN状态,不包含OPENING;onclose触发时,对应的就是CLOSED状态,不包含CLOSING状态。

WebSocket 事件

以下是 WebSocket 对象的相关事件。假定我们使用了以上代码创建了 Socket 对象:

WebSocket 方法

以下是 WebSocket 对象的相关方法。假定我们使用了以上代码创建了 Socket 对象:

用websocket发送接受二进制数据

WebSocket可以通过ArrayBuffer,发送或接收二进制数据。

var socket = new WebSocket('ws://127.0.0.1:8081');
socket.binaryType = 'arraybuffer';
 
// Wait until socket is open
socket.addEventListener('open', function (event) {
  // Send binary data
  var typedArray = new Uint8Array(4);
  socket.send(typedArray.buffer);
});
 
// Receive binary data
socket.addEventListener('message', function (event) {
  var arrayBuffer = event.data;
  // ···
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/682919.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ms17_010(永恒之蓝)漏洞复现详细教程

如题,这是个漏洞复现的详细教程,本教程针对的系统是Windows7操作系统,其他系统请自行测试。 备注:教程会很详细,讲解会很明白,一文可以解决你的常见困难。 测试环境 kalilinux 192.168.1.109 (…

Java设计模式之结构型-装饰器模式(UML类图+案例分析)

目录 一、基本概念 二、角色设计 三、代码实现 案例一 案例二 四、总结 一、基本概念 装饰器模式是指不必在改变原有的类和不使用继承的情况下,动态扩展一个对象的功能。 二、角色设计 角色描述抽象构件是一个接口或者抽象类,定义我们最核心的…

科技云报道:边缘计算步入“黄金年代”

科技云报道原创。 当前时点,AI大模型已经站在了从“玩具”向“工具”快速演化的关键迭代期。如何让大模型渗透进入各类垂直场景,如何更低成本的使用大模型,如何让更多场景与用户接触AI,成为了发展的下一个重点。 在AI向实际场景…

大数据应用——总结与反思

1.谈谈你对大数据行业的认识,目前对应的大数据岗位有哪些?每种岗位需要掌握哪些技能水平?目前自己的差距在哪里? (1)概述 对于大数据行业的认识,我的理解是,大数据是指海量数据&…

8种常见的SQL错误用法

前言:MySQL在2016年仍然保持强劲的数据库流行度增长趋势。越来越多的客户将自己的应用建立在MySQL数据库之上,甚至是从Oracle迁移到MySQL上来。但也存在部分客户在使用MySQL数据库的过程中遇到一些比如响应时间慢,CPU打满等情况。现将《Apsar…

Dumuz同步微信通讯录及常见问题

在Dumuz工具中,【微信通讯录同步】主要功能是从当前登录的微信上下载通讯录相关成员数据。 第1步: 打开应用【微信-消息批量发送】,在工具栏中点击【微信通讯录】如下图所示: 第2步: 进入【微信通讯录】 对话框&#…

【AUTOSAR】AUTOSAR开发工具链(九)----基于BTC的MIL/SIL测试操作说明(1)

一、BTC使用注意事项 1、安装成功后,在Edit->Preference->General->Compiler可以找到编辑器MSVC140 启动BTC:插入电子狗、选择与电子狗相匹配的License、选择相应的工具包 B2B就是MIL V SIL 适用于MBD开发的测试,单独SIL适用于手写…

【Jmeter教程】__将提取的参数并设置成全局变量(常用于提取token)

目录 一、提取参数 1、使用正则表达式提取器提取token 2、使用json提取器提取token 二、将提取参数设置成全局变量 三、常见问题 一、提取参数 1、使用正则表达式提取器提取token 查看登录响应参数找出token。图中token为 "ticketString": "ccf26b17-a96f…

深入理解MySQL主从配置原理

目录 1. MySQL主从复制原理工作原理 2. 主从配置步骤1: 配置主节点2: 备份主节点数据3: 配置从节点4: 启动主从复制 3.常见问题4. 需要考虑的一些因素 MySQL主从复制是一种数据库复制技术,通过将一个MySQL服务器(主节点)上的数据同步到其他My…

IP地点定位为什么有误差?

随着互联网的不断普及,人们对IP地点定位需求越来越多。然而,即便是在现代技术的支持下IP地点定位仍然存在误差。那么,IP地点定位为什么会出现误差呢? IP(Internet Protocol)地址是指互联网协议(…

SpringCloudSpringcloudAlibaba

SpringCloud 一:微服务架构1.1 ESB1.2 微服务与微服务 二 :编写SpringCloud代码2.1 父模块SpringCloudDemo项目2.2 公共类模块SpringCloud-api项目2.3 消费模块SpringCloud-user-8001项目2.4 RestTemplate 三:注册中心:Eureka3.1 …

机器学习——Kmeans算法

一、实验目的 学习sklearn模块中的KMeans算法 二、实验内容 学习KMeans算法,了解模型创建、使用模型及模型评价等操作 三、实验原理或流程 实验原理: K-means算法是将样本聚类成k个簇(cluster),具体算法描述如下: 1、随机选取k个聚类质…

春招上岸阿里,好多问题当场尬住!

一个粉丝,23年应届毕业生, 双非本科。最近他校招上岸了,拿到了阿里软件测试岗位的Offer。 他总结了一下面试题,感觉很多内容还是有难度的,尤其是对于应届生来说。下面是他整理的面试题,看看这种校招面试难…

sonarqube本地安装使用

sonarqube本地安装使用 sonarqube本地安装使用配置 官网网址:https://www.sonarqube.org/ 注意:sonarqube版本需要与jdk和数据库版本相对应,以及sonarqube对应电脑的位数 本案例中:JDK8、sonarqube7.6版本 在说明文档中可以…

svg图版绘制

推荐工具:Inkscape 绘制带折线的图版,使用左侧工具栏(绘制贝塞尔曲线和直线) 选中顶部(创建一个直线段构成的折线) 直接使用鼠标左键点对点进行绘制,停顿一次为一个坐标,鼠标右击…

软件测试技能,JMeter压力测试教程,setUp线程组实现用户先登录(八)

前言 在接口测试的时候,很多接口都需要用户先登录,才有访问接口的权限。在测试的时候,我们的关注点其实是当前测试的接口,登录只是一个前置操作 像 python 的 unittest 和 pytest 框架都有 setUp 的概念,前置操作用来…

探究物流机器人产业新发展

原创 | 文 BFT机器人 01 我国物流机器人发展现状 机器人人工智能加速了物流行业的发展,优化和提高了物流资源、物流流程和物流效率。 近年来,机器人相关产品和服务得到了快速推广,并经常应用于不同的存储和物流场景,如电子商务存储…

InternalAuthenticationServiceException: Invalid bound statement (not found):

InternalAuthenticationServiceException: Invalid bound statement (not found): 在项目中,我们会遇到如下问题,但是这个问题是一种常见的典型问题 org.springframework.security.authentication.InternalAuthenticationServiceException: Invalid boun…

SciencePub学术 | 纳米技术类重点SCIEEI征稿中

SciencePub学术 刊源推荐: 纳米技术类重点SCI&EI征稿中!1区正刊,进展顺利、录用快。信息如下,录满为止: 一、期刊概况: 纳米技术类重点SCI&EI 📌【期刊简介】IF:6.0-6.5,…

亚马逊云科技数据库市场份额提升迅速,合作伙伴和开发者生态系统为其赋能

对比常规的基础设施上云和应用上云,企业对于数据上云一直保持最为慎重的态度。不过也不是一成不变的,Gartner前不久公布的一组数据显示,在2022年全球数据库管理系统的市场份额排名中,作为纯云厂商的亚马逊云科技,超越了老牌传统数据库厂商甲骨文和微软,首次位居第一。 降低企业…