举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。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传送门:http://blog.csdn.net/luokehua789789/article/details/54378264

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 对象:

属性 描述
Socket.readyState

只读属性 readyState 表示连接状态,可以是以下值:

  • 0 - 表示连接尚未建立。

  • 1 - 表示连接已建立,可以进行通信。

  • 2 - 表示连接正在进行关闭。

  • 3 - 表示连接已经关闭或者连接不能打开。

Socket.bufferedAmount

只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。

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 对象:

事件 事件处理程序 描述
open Socket.onopen 连接建立时触发
message Socket.onmessage 客户端接收服务端数据时触发
error Socket.onerror 通信发生错误时触发
close Socket.onclose 连接关闭时触发

WebSocket 方法

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

方法 描述
Socket.send()

使用连接发送数据

Socket.close()

关闭连接

<!DOCTYPE HTML>
<html><head><meta charset="utf-8"><title>菜鸟教程(runoob.com)</title><script type="text/javascript">function WebSocketTest(){if ("WebSocket" in window){alert("您的浏览器支持 WebSocket!");// 打开一个 web socketvar ws = new WebSocket("ws://localhost:9998/echo");ws.onopen = function(){// Web Socket 已连接上,使用 send() 方法发送数据ws.send("发送数据");alert("数据发送中...");};ws.onmessage = function (evt) { var received_msg = evt.data;alert("数据已接收...");};ws.onclose = function(){ // 关闭 websocketalert("连接已关闭..."); };}else{// 浏览器不支持 WebSocketalert("您的浏览器不支持 WebSocket!");}}</script></head><body><div id="sse"><a href="javascript:WebSocketTest()">运行 WebSocket</a></div></body>
</html>

用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 datavar typedArray = new Uint8Array(4);socket.send(typedArray.buffer);
});// Receive binary data
socket.addEventListener('message', function (event) {var arrayBuffer = event.data;// ···
});

目前websocket的缺点是不兼容低版本浏览器。

WebSocket 有没有可能取代 AJAX ?

三、WebSocket的使用场景

websocket在实时通信领域运用的比较多,比如社交聊天、弹幕、多玩家游戏、协同编辑、股票基金实时报价、体育实况更新、视频会议/聊天、基于位置的应用、在线教育、智能家居等需要高实时的场景

WS协议—介绍及原理相关推荐

  1. RPC——RPC协议介绍及原理详解

    common wx:CodingTechWork 介绍 RPC框架 概念 RPC(Remote Procedure Call Protocol) 远程过程调用协议. RPC是一种通过网络从远程计算机程 ...

  2. 下面哪个字段是http请求中必须具备的_HTTP协议及其工作原理介绍

    HTTP,全称 HyperText Transfer Protocol,即超文本传输协议.它是互联网应用最为广泛的一种网络协议,我们平时浏览网页的时候就是使用HTTP协议.比如当你在浏览器中输入www ...

  3. 2022-10-31 网工进阶(三十三) IP组播-流量模型、组播概念、组播报文结构、组播地址与MAC、组播网络架构、组播服务模型、组播数据转发原理(RPF检查、组播分发树、组播协议介绍)

    IP组播概念 流量模型 网络中存在各种各样的业务,从流量模型看一般可以将业务分为两类: 点到点业务:比如FTP,WEB业务,此类业务主要特点是不同的用户有不同的需求,比如用户A需要下载资料A,用户B需 ...

  4. 24.CAPWAP原理_CAPWAP协议介绍

    CAPWAP协议介绍 前言 一.CAPWAP协议简介 1.协议主要内容 2.数据转发类型 3.基本报文格式 二.CAPWAP状态机 1.引入库 三.CAPWAP隧道建立过程 1.DHCP过程 2.Di ...

  5. websocket ws 协议 简介

    一.内容概览 WebSocket的出现,使得浏览器具备了实时双向通信的能力.本文由浅入深,介绍了WebSocket如何建立连接.交换数据的细节,以及数据帧的格式.此外,还简要介绍了针对WebSocke ...

  6. SNMP协议介绍和操作截图

    第一章 SNMP协议介绍 SNMP协议 基于TCP/IP的网络管理包含3个组成部分: 1) 一个管理信息库MIB(Management Information Base).管理信息库包含所有代理进程的 ...

  7. AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  8. 【helpdesk】启明星helpdesk7.0版本里,实现邮件提交功能介绍和原理

    在启明星helpdesk7.0版本里,新增了一个功能:邮件提交.所谓邮件提交就是用户直接发送邮件到IT.当然IT通常会公开一个公共邮件,例如support@dotnetcms.org.下面介绍一下启明 ...

  9. TLS 协议-对称加密原理

    文章目录 TLS 协议-对称加密原理 1.TLS 设计的目的 2.TLS/SSL 发展历史及通用模型 3.TLS 协议 4.TLS 安全密码套件解读 5.对称加密示意图 6.基于 XOR 的对称加密原 ...

最新文章

  1. 谁说AI无用?疫情下,AI已经代替人类做了很多...
  2. flowJS源码个人分析
  3. 深入了解java虚拟机(JVM) 第六章 垃圾回收算法
  4. 会员按天统计、日分时统计
  5. 变参函数寻找最大整数值
  6. 如何修改WAMP中mysql默认空密码重新登录phpmyadmin
  7. UC 国际信息流推荐中的多语言内容理解
  8. 小白教程系列——XMind8 Pro下载安装
  9. OPC client安装教程
  10. sqlserver2005 安装图解教程以及SQL 2005 SP3补丁安装图文教程
  11. MERGE JOIN CARTESIAN
  12. [趣味文学]“帅气”的莎士比亚
  13. CSP 201809-3 元素选择器
  14. python做出来的东西怎么让别人看_有趣的Python图片制作之如何用QQ好友头像拼接出里昂...
  15. 怎么获取api key?
  16. SHT30 温湿度传感器 使用示例
  17. [源码和文档分享]基于Python实现的论坛帖子情感分析
  18. Java死锁产生的四个条件
  19. 书法练字帖纸——井字格是不一样的格
  20. 批量处理不同文件夹下同名图片到相同文件内,简单处理

热门文章

  1. 空间平滑可以解相干的原因
  2. vue3使用大屏dataV详细教程
  3. 北京房产泡沫何时开始破灭?破灭多少?
  4. 充电宝转换率排行,转化率最好的充电宝推荐
  5. JSTL和Ajax小计
  6. 应届大学生如何找工作,如何选择,如何投简历,如何面试
  7. KPI 考核没毛病,要搞清楚KPI背后的why!
  8. 简单的项目规模统计方法
  9. Windows 10 1809 MSDN 版本下载 ed2k 链接
  10. java 抓取新浪财经网上的股票数据(1)