websocket深入浅出-程序员宅基地

技术标签: websocket  JavaScript  ES6  

websocket简介

websocket是什么

答: 它是一种网络通信协议,是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

为什么需要websocket? 疑问? 我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?

答:

  • 因为 HTTP 协议有一个缺陷:通信只能由客户端发起
  • 我们都知道轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开), 因此websocket应运而生。

简介

WebSocket用于在Web浏览器和服务器之间进行任意的双向数据传输的一种技术。WebSocket协议基于TCP协议实现,包含初始的握手过程,以及后续的多次数据帧双向传输过程。其目的是在WebSocket应用和WebSocket服务器进行频繁双向通信时,可以使服务器避免打开多个HTTP连接进行工作来节约资源,提高了工作效率和资源利用率。

WebSocket目前支持两种统一资源标志符wswss,类似于HTTP和HTTPS。

实现原理

浏览器发出webSocket的连线请求,服务器发出响应,这个过程称为握手,握手的过程只需要一次,就可以实现持久连接。

握手与连接

浏览器发出连线请求,此时的request如下:

request

通过get可以表明此次连接的建立是以HTTP协议为基础的,返回101状态码。

如果不是101状态码,表示握手升级的过程失败了

101是Switching Protocols,表示服务器已经理解了客户端的请求,并将通过Upgrade 消息头通知客户端采用不同的协议来完成这个请求。在发送这个响应后的空档,将http升级到webSocket

其中UpgradeConnection字段告诉服务端,发起的是webSocket协议

Sec-WebSocket-Key是浏览器经过Base64加密后的密钥,用来和response里面的Sec-WebSocket-Accept进行比对验证

Sec-WebSocket-Version是当前的协议版本

Sec-WebSocket-Extensions是对WebSocket的协议扩展

服务器接到浏览器的连线请求返回结果如下:

response

UpgradeConnection来告诉浏览器,服务已经是基于webSocket协议的了,让浏览器也遵循这个协议

Sec-WebSocket-Accept是服务端确认后并加密后的Sec-WebSocket-Accept

至此,webSocket连接成功,接下来就是webSocket的协议了。

客户端的简单示例

var ws = new WebSocket("wss://echo.websocket.org");

ws.onopen = function(evt) { 
  console.log("Connection open ..."); 
  ws.send("Hello WebSockets!");
};

ws.onmessage = function(evt) {
  console.log( "Received Message: " + evt.data);
  ws.close();
};

ws.onclose = function(evt) {
  console.log("Connection closed.");
}; 

ws.onerror = function(evt) {
  console.log("error!!!"); 
}; 

客户端的 API

  • 以下 API 用于创建 WebSocket 对象
var ws = new WebSocket('ws://echo.websocket.org');
  • websocket 属性
ws.readyState
CONNECTING:值为0,表示正在连接。
OPEN:值为1,表示连接成功,可以通信了。
CLOSING:值为2,表示连接正在关闭。
CLOSED:值为3,表示连接已经关闭,或者打开连接失败。

ws.bufferedAmount
只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。
  • WebSocket 事件
事件       事件处理程      描述
open     ws.onopen      连接建立时触发
message  ws.onmessage   客户端接收服务端数据时触发
error    ws.onerror     通信发生错误时触发
close    ws.onclose     连接关闭时触发

如果要指定多个回调函数,可以使用addEventListener方法

ws.addEventListener('open', function (event) {
   
    
  ws.send('Hello Server!');
});
ws.addEventListener("close", function(event) {
   
    
  ...
  // handle close event
});
ws.addEventListener("message", function(event) {
   
    
  var data = event.data;
  ...
  // 处理数据
});
  • websocket 方法
方法                  描述
ws.send()            使用连接发送数据
ws.close()           关闭链接

node 搭建服务器

ws模块

ws是一个websocket库,可以用了创建服务器。

新建server.js 输入以下代码

const WebSocket = require('ws');
 
const wss = new WebSocket.Server({
   
     port: 8181 });
 
wss.on('connection', function connection(ws) {
   
    
  ws.on('message', function(message){
   
    
    wss.clients.forEach(function(ws){
   
     // 看这里看这里  wss.clients 拿到所有的连接
          ws.send(message) // 发送消息
      })
  })
});

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sinat_36422236/article/details/85051547

智能推荐

Android应用层View绘制流程与源码分析-程序员宅基地

文章浏览阅读269次。【工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处,尊重分享成果】1 背景还记得前面《Android应用setContentView与LayoutInflater加载解析机制源码分析》这篇文章吗?我们有分析到Activity中界面加载显示的基本流程原理,记不记得最终分析结果就是下面的关系:看见没有,如上图中id为content的内容就是整个View树的结构,所

【CAD开发】gltf文件格式的转换工具汇总(js、python、c++)_gltf文件用什么软件-程序员宅基地

文章浏览阅读4.5k次。文章目录1、简介2、3dsMax/maya导出插件(Babylon.js)1、简介2、3dsMax/maya导出插件(Babylon.js)Exporters for Babylon.js and gltf file formatshttps://github.com/BabylonJS/Exporters/releases_gltf文件用什么软件

Pycharm常用的小技巧汇总,Python新手上路必备,快上车!_pycharm 一些使用技巧-程序员宅基地

文章浏览阅读4.3w次,点赞561次,收藏2.4k次。这不是去幼儿园的车!_pycharm 一些使用技巧

【Python】str.isdigit() 和 float.is_integer()的用法和区别,判断数据是否是数字_float' object has no attribute 'isdigit-程序员宅基地

文章浏览阅读3.3k次。str.isdigit() 和 float.is_integer()都可以判断数据是否是数字,但是二者是有一定区别的,具体见代码。# str.isdigit(),用来判断1个字符串str是否全部都是数字,如果是,返回Truea = 5; print(a.isdigit()) # AttributeError: 'int' object has no attribut..._float' object has no attribute 'isdigit

Java中double类型四舍五入的方法总结_double的四舍五入方法-程序员宅基地

文章浏览阅读1w次。代码:double a = 13.245; //方法一:BigDecimal bd= new BigDecimal(a);Double b = bd.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();System.out.println("方法一: "+b);//方法二:Double myValue = new BigD..._double的四舍五入方法

linux 离线安装rabbitmq 3.7.13_linux rabbit 离线安装-程序员宅基地

文章浏览阅读479次。在线安装及详细说明请参考Linux安装rabbitmq详细教程离线安装包https://download.csdn.net/download/qq_36249132/123622801.创建文件夹放置离线安装包2.安装erlang,socat,rabbitmq依次执行以下命令rpm -ivh erlang-21.2.6-1.el7.x86_64.rpm --force --node..._linux rabbit 离线安装

随便推点

opencv 字符图象 开运算 闭运算_OpenCV图像处理-平滑处理、形态学操作-程序员宅基地

文章浏览阅读192次。图像平滑️ 模糊/平滑图片来消除图片噪声️ OpenCV函数:cv2.blur(), cv2.GaussianBlur(), cv2.medianBlur(), cv2.bilateralFilter() 2D 卷积️ OpenCV中用cv2.filter2D()实现卷积操作,比如我们的核是下面这样(3×3区域像素的和除以10): img = cv2.imread('lena.jpg')#..._字符进行开闭运算

简单DHCP下放IP_dhcp下放系统-程序员宅基地

文章浏览阅读129次。拓扑图配置R1接口地址[R1]interface g0/0/0 [R1-GigabitEthernet0/0/0]ip address 192.168.1.1 24[R1-GigabitEthernet0/0/0]quit [R1]interface g0/0/1[R1-GigabitEthernet0/0/1]ip address 172.16.1.1 24启用DHCP服务器[R1]dhcp enable //打开dhcp服务Info: The operation may tak_dhcp下放系统

react替换元素节点_从0实现React 系列(一):React的架构设计-程序员宅基地

文章浏览阅读89次。编者按:本文作者苏畅,奇舞团前端开发工程师。为什么要写这个系列?2020年初给自己定下目标,今年要读懂React源码,最好能成为React Contributor(没想到很快就实现了,虽然提交的commit很微小)。为什么要读React源码呢,因为如果单纯开发日常业务的话,前端的边界其实很窄。回想一下,你今年做的业务,换作是去年的你,前年的你,换作是应届生甲乙丙,他们能替换你的位置么?我..._react 两个元素替换效果实现

华为交换机查看端口相关信息常用命令,排查故障法宝,转发收藏_华为交换机查看端口状态命令-程序员宅基地

文章浏览阅读6.1w次,点赞55次,收藏803次。一、查看接口状态1、显示接口的运行状态和相关信息display interface Ethernet brief查看以太网端口的简要信息,物理端口是否连通,端口是否是全双工,带宽是多少,端口的流入流出的流量百分比。可以排查端口的基本信息,比如有的端口用户网速慢,可以查看该端口的接口速率,是否是全双工状态,是否是网卡速率,比如本来是1000M的网卡,但是速率显示的是10M,那么该条链路一定是有问题的。2、查看接口的描述信息display interface descript._华为交换机查看端口状态命令

sql server的元素类型int identity(1,1)是什么意思?-程序员宅基地

文章浏览阅读7k次,点赞5次,收藏10次。该列自动增长,由1开始每次增加是1。标识列, identity(a,b),ab均为正整数,a表示开始数,b表示增幅。扩展资料:结构化查询语言(Structured Query Language)简称SQL(发音:/ˈes kjuː ˈel/ “S-Q-L”),是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;同时也是数据库脚本文件的扩..._int identity(1,1)

Android系统制作自定义签名_development/tools/make_key 指令的参数说明和示例-程序员宅基地

文章浏览阅读5.6k次。1、简介应客户要求为了是特殊定制的系统更具安全,系统ROM需要使用自己定义的签名,还有一些特殊的场景也会更改系统的签名比如在过cts认证测试的时候也会修改平台签名才能测试通过关于签名的问题。这是因为平台默认的是test签名.网上大多说签名的都是app签名而非平台签名。test签名这种类型的key只适用于开发阶段,而且这种秘钥是公开的,谁都可以使用。当发布一款android产品,就需要另外给整个..._development/tools/make_key 指令的参数说明和示例

推荐文章

热门文章

相关标签