WebSocket

WebSocket的基本使用 WebSocket 是一种网络协议,用于在客户端和服务器之间进行双向通信。它允许在一个单独的 TCP 连接上进行全双工通信,因此比传统的 HTTP 请求-响应模型更高效。 阅读详情

是什么

由于TCP是服务器被动通信,无法主动向客户端发送信息,所以有了websocket
可以双向通信
服务端监听自身端口+客户端连接服务器地址和该端口,达成通信成功!(类似于Java的socket通信)

使用的是Http连接来建立:

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

在这里插入图片描述
参考:https://www.ruanyifeng.com/blog/2017/05/websocket.html

如何建立

必须由浏览器发起!因为是一个HTTP请求
请求头:

GET ws://localhost:3000/ws/chat HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Origin: http://localhost:3000
Sec-WebSocket-Key: client-random-string
Sec-WebSocket-Version: 13

注意点:

  • 地址以ws://目标地址:端口开始
  • connection指定连接升级
  • upgrade指定升级成websocket协议
  • 13是websocket协议版本号

返回值:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: server-random-string

注意:101标识HTTP协议将被替代成websocket协议!标识连接成功!

安全的WebSocket连接机制和HTTPS类似。首先,浏览器用wss://xxx创建WebSocket连接时,会先通过HTTPS创建安全的连接,然后,该HTTPS连接升级为WebSocket连接,底层通信走的仍然是安全的SSL/TLS协议

websocket 常用 api

// 构造函数
WebSocket WebSocket(url)

// 属性
// 用于指定连接关闭后的回调函数
webSocket.onclose
// 用于指定连接失败后的回调函数
webSocket.onerror
// 用于指定当从服务器接受到信息时的回调函数
webSocket.onmessage
// 用于指定连接成功后的回调函数
webSocket.onopen
// 查询当前连接状况:
// CONNECTING:值为0,表示正在连接。
// OPEN:值为1,表示连接成功,可以通信了。
// CLOSING:值为2,表示连接正在关闭。
// CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
webSocket.readyState

// 事件 使用 addEventListener() 或将一个事件监听器赋值给本接口的 oneventname 属性,来监听下面的事件
// 当一个 WebSocket 连接被关闭时触发。
// 也可以通过 onclose 属性来设置。
"close" 
// 当一个 WebSocket 连接因错误而关闭时触发,例如无法发送数据时。
// 也可以通过 onerror 属性来设置。
"error" 
//  当通过 WebSocket 收到数据时触发。
// 也可以通过 onmessage 属性来设置。
"message"
// 当一个 WebSocket 连接成功时触发。
// 也可以通过 onopen 属性来设置。
"open" 

// 方法 调用该方法执行一些功能
// 关闭当前链接。
WebSocket.close([code[, reason]])
// 对要传输的数据进行排队。
// data类型:utf-8字符串、arraybuffer、blob、arraybufferview
WebSocket.send(data)

向服务器发送数据

发送文本:ws.send('your message');
发送二进制:

var file = document
  .querySelector('input[type="file"]')
  .files[0];
ws.send(file);

发送arraybuffer:

var img = canvas_context.getImageData(0, 0, 400, 320);
var binary = new Uint8Array(img.data.length);
for (var i = 0; i < img.data.length; i++) {
  binary[i] = img.data[i];
}
ws.send(binary.buffer);

判断发送进度:实例对象的bufferedAmount属性,表示还有多少字节的二进制数据没有发送出去。它可以用来判断发送是否结束。

var data = new ArrayBuffer(10000000);
socket.send(data);

if (socket.bufferedAmount === 0) {
  // 发送完毕
} else {
  // 发送还没结束
}

处理服务器发过来的数据

发送过来的数据包裹在event.data中

ws.onmessage = function(event) {
  var data = event.data;
  // 处理数据
};

ws.addEventListener("message", function(event) {
  var data = event.data;
  // 处理数据
});

对于接受的数据,需要判断下是什么类型,然后做处理

ws.onmessage = function(event){
  if(typeof event.data === String) {
    console.log("Received data string");
  }

  if(event.data instanceof ArrayBuffer){
    var buffer = event.data;
    console.log("Received arraybuffer");
  }
}

可以显式指定二进制的数据类型

// 收到的是 blob 数据 // 收到的是 ArrayBuffer 数据
ws.binaryType = "blob";//ws.binaryType = "arraybuffer";
ws.onmessage = function(e) {
  console.log(e.data.size);
};

一个完整示例

客户端:

;(function(){
  // 获取页面dom节点
  const domList = document.querySelector("#list");
  const domMsg = document.querySelector("#msg");
  const domSend = document.querySelector("#send");
  // 判断登陆状况
  const username = localStorage.getItem('username');
  if(username == null || username == ""){
    location.href = '/entry.html';
    return;
  }
  // 连接服务器
  const ws = new WebSocket("ws:localhost:8000");
  function init(){
    bindEvent();
  }
  // 绑定websocket事件
  function bindEvent(){
    domSend.addEventListener('click',handleSendMsg,false);
    ws.addEventListener('open',onOpen,false);
    ws.addEventListener('close',onClose,false);
    ws.addEventListener('error',onError,false);
    ws.addEventListener('message',onMessage,false); // 也可以: ws.onmessage = onMessage;
  }
  // 发送数据函数
  function handleSendMsg(){
    ws.send(JSON.stringify({
      "username":username,
      "msg":domMsg.value,
      "time":new Date()
    }))
    domMsg.value = "";
  }
  function onOpen(){
    console.log('open')
  }
  function onClose(){
    console.log('close')
  }
  function onError(){
    console.log('error')
  }
  // 接收数据并处理的函数,这里主要是将接收到的数据插入一个li标签到页面上
  function onMessage(e){
    console.log('message',e)
    domList.appendChild(createMsg(JSON.parse(e.data)))
  }
  function createMsg(data){
    const {username,msg,time} = data;
    const li = document.createElement('li');
    li.innerHTML = `
      <p><span>${username}</span>  <i>${time}</i></p>
      <p>${msg}</p>
    `
    return li;
  }

  init();
})();

服务器:这里使用ws包来监听

const WS = require("ws");
(function () {
  const server = new WS.Server({ port: 8000 });
  function init() {
    bindEvent();
  }
  function bindEvent() {
    server.on("open", onOpen);
    server.on("close", onClose);
    server.on("error", onError);
    server.on("connection", onConnection);
  }
  function onOpen() {
    console.log("open");
  }
  function onClose() {
    console.log("close");
  }
  function onError() {
    console.log("error");
  }
  function onMessage(msg) {
    console.log("message", JSON.parse(msg));
    server.clients.forEach((c) => c.send(msg, { binary: false }));
  }
  function onConnection(clinet) {
    console.log("connection");
    clinet.on("message", onMessage);
  }
  init();
})();

后端可以使用nodemon来监控这个index.js文件,并启动服务!
前端可以使用vite来启动服务!

// 后端
"scripts": {
    "dev": "nodemon index.js"
  },
// 前端
"scripts": {
    "dev":"vite"
  },
详细讲解node的ws中服务端的websocket.server的各种api WebSocket是一种在单个TCP连接上进行全双工通信的协议。Node.js中的ws模块提供了WebSocket的实现,使得Node.js可以轻松地创建WebSocket服务器和客户端。在ws模块中,WebSocket服务器由WebSocket.Server类实现。WebSocket.Server提供了一系列的API,用于管理WebSocket连接、发送消息等操作。本文将详细讲解WebSocket.Server的各种API。 阅读详情

相关推荐

手机变砖前兆?手把手教你从高通XBL阶段读取UFS健康报告(附源码)

本文深入解析高通XBL阶段如何读取UFS健康报告,帮助用户提前预警手机变砖风险。通过实战案例和源码示例,详细介绍了UFS健康监测的关键参数、诊断框架构建及预警策略,为硬件工程师提供了一套完整的早期故障定位方案。

weixin_30561425的博客 589

Web实时通信的学习之旅:WebSocket入门指南及示例演示

WebSocket 协议的底层协议也是TCP协议WebSocket 协议的标识符为ws,加密后为wssWebSocket 协议没有同源限制,即WebSocket 协议可以跨域通信WebSocket 协议是有状态的,是前后端交互的长连接,即建立连接后可以保持连接状态,通信时可以省略部分状态信息WebSocket 协议可以发送文本,同时也可以发送二进制数据WebSocket 是一种强大的网络通信协议,它允许服务器和客户端之间进行实时、双向通信。

在这里,我乐于倾囊相授,分享我的技术心得、项目实战经验、技术技巧。希望能够惠及更多的开发者,助力大家在技术的海洋中扬帆远航。 5145

SpringBoot整合WebSocket服务 springboot整合websocket springboot使用websocket springboot使用websocket

仅使用 SpringBoot封装好的服务,并不是使用第三方Netty或者: 底层使用实现: 底层使用Netty实现(没有使用过,不知道具体)官方文档1官方文档2。

web17886480312的博客 6767

WebSocket:server/client

server 开启node服务,实现ws服务端: const WebSocketServer = require('ws').Server; // 创建websocket服务器 const wss = new WebSocketServer({ port: 8888 }); // 注册连接开启事件,同时其他事件的初始化 wss.on('connection', function (ws) { console.log('ws client connected'); //接收客户端发送的报文事件

@tangguo123 博客 1031

ESP32入门基础之ESP WebSocket Client

ESP WebSocket Client

while(1) 5037

websocket

​ 我们在上网时经常会遇到一些情况,就是页面没有刷新,但是一些数据会发生了改变,比如:在邮箱页面当收到新邮件时,我们并没有刷新页面,但是却会主动提示有新邮件达到,并会将未读邮件的数量+1。或者是在一些购物网站,当有新消息时并没有刷新页面,却提示了我们有新消息未读。​ 那像这样的业务场景是怎么实现的呢?为什么页面没有刷新,浏览器却提醒我们有新消息呢?​ 解决方案:1、采用轮询的方式。即:通过js不断的请求服务器,查看是否有新数据,如果有,就获取到新数据。这种解决方法是否存在问题呢?

Casual_Lei的博客 1478

React中使用websocket连接

React WebSocket

小蜜蜂的博客 4万+

Django 实现Websocket

django实现websocket大致上有两种方式,一种channels,一种是dwebsocket。channels依赖于redis,twisted等,相比之下使用dwebsocket要更为方便一些。 安装:  pip install dwebsocket 配置: # setting.py INSTALLED_APPS = [ ..... ..... 'dw...

FanMLei的博客 8295

WebSocket原理及技术简介

WebSocket原理及技术简介 目录 1    引言    1 2    WebSocket技术及协议    2 2.1    WebSocket API    2 2.1.1    示例    3 2.2    WebSocket协议    4 2.2.1    握手阶段    4 2.2.2    数据通信    5 2.2.3    连接关闭

当年老王的专栏 4万+

websocket / 使用 wireshark 分析 websocket 连接过程

一、连接过程时序图 二、wireshark 分析 上图是一个完整的进行 websocket 连接时产生的数据包。 根据时序图可知,前 3 行是 tcp/ip 握手过程,因为可以通过标志来看到,前 3 个标志(Flags)分别为 SYN、SYN ACK、ACK。这是建立 http 请求的需要,和 websocket 没有关系。 第 4 条就是 client 主动发给 server 的握手协议了,如下图所示: 细心的小伙伴可以发现,这套代码是基于 C++ 版的 websocketpp 实现

布袋和尚 3631

超详细 Git创建仓库及上传项目至Github操作(Windows系统)

文章目录前言一、Git下载及安装二、创建代码仓库1.配置身份2.创建本地仓库3.提交本地代码三、使用Git上传代码至Github1.创建ssh keys2.在Github中新建仓库3.关联本地仓库与Github仓库4.推送代码至Github仓库总结 前言 本文对于Windows系统上git的安装及基本使用方法进行简单介绍,并介绍如何使用git将仓库中的项目上传至个人的Github中去。内容参考《第一行代码》以及一些博客。 本文适合新手阅读哦~ 一、Git下载及安装 打开网站 git下载 下载安装包(直接

lijianyi0219的博客 2万+

springboot集成websocket

​ 这里我们使用springboot搭建一个轻量级的websocket服务,同时提供4个入参。使用websocket服务可以轻松和微信小程序、支付宝小程序、网页就行双向通讯,非常实用方便。wss地址这里是我们自己搭建的中转服务websocket地址。参数说明。

大爱仙尊 3万+

手把手教你用scRNA-seq和scTCR-seq分析CD8⁺ T细胞在免疫治疗中的动态变化

本文详细介绍了如何整合单细胞RNA测序(scRNA-seq)与单细胞TCR测序(scTCR-seq)技术,深入解析CD8⁺ T细胞在癌症免疫治疗中的动态变化。通过从数据预处理、细胞亚群鉴定到TCR克隆追踪的完整分析流程,揭示了T细胞的功能状态转变与克隆演化规律,为理解免疫应答机制和开发精准治疗策略提供了关键方法学指导。

p8q9r0的博客 566

websocket入门及应用

**WebSocket** 是基于TCP/IP协议,独立于HTTP协议的通信协议。WebSocket 是双向通讯,有状态,客户端一(多)个与服务端一(多)双向实时响应(客户端 ⇄ 服务端)。WebSocket 是应用在浏览器的 Socket (是 Socket 模型接口的实现),Socket 是一个网络通信接口 (通信规范)。

qq_36115196的博客 1387

张量/数组存储方式与向量化展开/展平、view、reshape、permute对比

对于一个Tensor来说,我们可以认为它有两种存储方式。

欢迎关注,共同进步! 3434

手把手教你用STM32+LAN8720搭建以太网通信模块(含原理图)

本文详细介绍了如何使用STM32微控制器与LAN8720物理层芯片搭建以太网通信模块,涵盖硬件设计、软件配置及常见问题排查。重点讲解了LAN8720的低功耗设计、RMII接口简化布线等特性,以及STM32CubeMX配置和LwIP协议栈移植技巧,助力开发者快速实现稳定可靠的嵌入式网络通信。

CAT789的专栏 413

Django通过dwebsocket实现websocket

与django推荐的channel不同,dwebsocket使用更加方便简单 使用方法1: 只需views.py文件中,将对应的视图函数添加装饰器 accept_websocket-—可以接受websocket请求和普通http请求 require_websocket----只接受websocket请求,拒绝普通http请求 from dwebsocket.decorators import ...

毛毛腿的博客 1万+

C# 的 Dapper 库高级进阶:刨根问底的深度解析

通过今天的探索,我们了解了 Dapper 的一些高级功能,包括如何处理复杂的查询、执行批量操作以及如何优化性能。希望这篇深入浅出的文章能帮助你在实际项目中更好地运用 Dapper!🎈好了,小伙伴们,今天的分享就到这里啦!如果你有任何疑问或者想要分享自己的经验,请在评论区留言。我们下次再见!👋上述示例代码仅供参考,实际使用时请根据项目需求进行适当调整。✨Dapper 官方文档Dapper 性能优化指南Dapper 动态参数使用来同时执行多个查询。利用Execute和Query方法来简化 SQL 调用。

java专栏 813

websocket封装

websocket封装

weixin_43422861的博客 6188

通信算法之264: DJI O2 协议物理层逆向工程解析

对于 DroneID,标志之间的间隙由循环前缀 (CP) 填充:每个标志末尾的副本附加在相应标志的开头。有了关于确切标志开始的信息,可以使用 FFT 将标志转移到频域 - 来自时域的 1024 个样本导致频域中的 1024 个子载波。使用比特流的解扰和涡轮解码,并将生成的数据映射到如上的DroneID 结构,通过逆向工程在无人机的固件中找到了它。注意到一些无人机(Mavic 2 和更早的 OcuSync 无人机)不发送第一个标志(标志 1),这导致更短的帧持续时间为 576 µs。//产品型号数字代号。

leegang12的专栏 3942

【WRF数据准备】气象驱动数据-ERA5再分析数据(Copernicus)

【WRF数据准备】气象驱动数据-ERA5再分析数据

WW、forever的博客 5528

Spring Boot整合websocket遇到的小问题

在项目根目录下创建一个endpoint包,在endpoint包下创建一个WebSocket类,在类上添加@Component和@ServerEndpoint注解,并通过@ServerEndpoint的value属性指定请求路径,用法类似于@RequestMapping。意思是onOpen()方法上的一个String类型的参数上没有用@PathParam注解,检查了一下,确实没有用这个注解,用的是@PathVariable,这两个注解的作用是类似的,都是获取rest风格请求的参数。修改之后能正常启动了。

沐雨橙风ιε的博客 3773

【系统移植】 移植主线U-Boot(v2024.01-rc3)到RK3399

[系统移植] 移植主线U-Boot(v2024.01-rc3)到RK3399

Systemcall名屋 1003

WebSocket之Sec-WebSocket-Protocol

后端通过继承ServerEndpointConfig.Configurator类来完成握手。前端创建的websocket对象。后面的数组可以传多个。

weixin_44142871的博客 2586

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

上一篇: 利用Suspense组件来包装请求
下一篇: es6和commonjs对导入导出的值修改是否影响原模块
天落枫
博客等级 码龄10年 91粉丝 92原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值