现代Web开发:WebSocket 实时通信详解
💓 博客主页:瑕疵的CSDN主页
📝 Gitee主页:瑕疵的gitee主页
⏩ 文章专栏:《热点资讯》
现代Web开发:WebSocket 实时通信详解
- 现代Web开发:WebSocket 实时通信详解
- 引言
- WebSocket 概述
- 什么是 WebSocket
- WebSocket 的特点
- WebSocket 工作原理
- 握手过程
- 客户端请求
- 服务器响应
- 数据帧
- WebSocket API
- 客户端 API
- 服务器端实现
- 实战案例分析
- 实时聊天应用
- 项目结构
- 安装依赖
- 创建 WebSocket 服务器
- 创建客户端页面
- 编写客户端脚本
- WebSocket 安全性
- 使用 WSS
- 防止跨站请求伪造(CSRF)
- WebSocket 与其他技术的比较
- 与 AJAX 的比较
- 与长轮询(Long Polling)的比较
- 总结
- 参考资料
在现代Web开发中,实现实时通信是一个常见的需求。无论是在线聊天、实时协作编辑还是实时数据更新,WebSocket 技术都提供了强大的支持。本文将详细介绍 WebSocket 的基本概念、工作原理、实现步骤以及实际应用,帮助读者更好地理解和使用 WebSocket。
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
- 全双工通信:WebSocket 提供了真正的双向通信,客户端和服务器可以同时发送数据。
- 低延迟:相比 HTTP 请求,WebSocket 的数据传输延迟更低。
- 轻量级:WebSocket 协议的头部信息非常小,减少了不必要的开销。
- 持久连接:一旦建立连接,除非客户端或服务器主动断开,否则连接会一直保持。
WebSocket 的握手过程是通过 HTTP 协议完成的。客户端发送一个特殊的 HTTP 请求,服务器响应一个特殊的 HTTP 状态码,从而完成握手。
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
握手完成后,客户端和服务器开始通过 WebSocket 进行数据传输。数据传输的基本单位是帧(frame),每个帧都有自己的格式。
在浏览器中,可以通过 WebSocket
对象来使用 WebSocket API。
const socket = new WebSocket('ws://example.com/socket');socket.onopen = function(event) {console.log('Connection opened:', event);
};socket.onmessage = function(event) {console.log('Message received:', event.data);
};socket.onclose = function(event) {console.log('Connection closed:', event);
};socket.onerror = function(error) {console.error('Error detected:', error);
};socket.send('Hello, server!');
在服务器端,可以使用多种语言和框架来实现 WebSocket 服务器。以下是使用 Node.js 和 ws
库的示例。
- 安装
ws
库
npm install ws
- 创建 WebSocket 服务器
const WebSocket = require('ws');const wss = new WebSocket.Server({ port: 8080 });wss.on('connection', function connection(ws) {ws.on('message', function incoming(message) {console.log('Received:', message);});ws.send('Hello, client!');
});
假设我们要构建一个简单的实时聊天应用,包含用户登录、发送消息和接收消息功能。
chat-app/
├── client/
│ ├── index.html
│ └── script.js
├── server/
│ └── server.js
└── package.json
npm install ws
在 server/server.js
中创建 WebSocket 服务器。
const WebSocket = require('ws');const wss = new WebSocket.Server({ port: 8080 });wss.on('connection', function connection(ws) {ws.on('message', function incoming(message) {console.log('Received:', message);wss.clients.forEach(function each(client) {if (client !== ws && client.readyState === WebSocket.OPEN) {client.send(message);}});});ws.send('Welcome to the chat!');
});console.log('WebSocket server is running on ws://localhost:8080');
在 client/index.html
中创建客户端页面。
<!DOCTYPE html>
<html lang='en'>
<head><meta charset='UTF-8'><title>Real-time Chat</title>
</head>
<body><div id='chat-container'><ul id='messages'></ul><input type='text' id='message-input' placeholder='Type a message...' /><button id='send-button'>Send</button></div><script src='./script.js'></script>
</body>
</html>
在 client/script.js
中编写客户端脚本。
const socket = new WebSocket('ws://localhost:8080');const messagesList = document.getElementById('messages');
const messageInput = document.getElementById('message-input');
const sendButton = document.getElementById('send-button');socket.onopen = function(event) {console.log('Connection opened:', event);
};socket.onmessage = function(event) {const messageItem = document.createElement('li');messageItem.textContent = event.data;messagesList.appendChild(messageItem);
};socket.onclose = function(event) {console.log('Connection closed:', event);
};socket.onerror = function(error) {console.error('Error detected:', error);
};sendButton.addEventListener('click', function() {const message = messageInput.value;socket.send(message);messageInput.value = '';
});
为了保证通信的安全性,可以使用 WSS(WebSocket Secure),即加密的 WebSocket 连接。WSS 使用 TLS/SSL 加密,确保数据传输的安全性。
const socket = new WebSocket('wss://example.com/socket');
在 WebSocket 服务器端,可以通过验证 Origin 头来防止 CSRF 攻击。
wss.on('connection', function connection(ws, req) {if (req.headers.origin !== 'http://example.com') {ws.close();return;}// 正常处理连接
});
- 数据传输方向:AJAX 只支持从客户端到服务器的单向数据传输,而 WebSocket 支持双向数据传输。
- 延迟:AJAX 的每次请求都需要建立新的连接,延迟较高;WebSocket 一旦建立连接,数据传输延迟较低。
- 资源消耗:AJAX 每次请求都会消耗一定的资源,而 WebSocket 在连接建立后,资源消耗较低。
- 数据传输方向:长轮询也只支持从客户端到服务器的单向数据传输,而 WebSocket 支持双向数据传输。
- 延迟:长轮询的延迟较高,因为每次请求都需要等待服务器响应;WebSocket 的延迟较低。
- 资源消耗:长轮询会频繁建立和关闭连接,资源消耗较高;WebSocket 一旦建立连接,资源消耗较低。
通过本文,我们深入了解了 WebSocket 的基本概念、工作原理、实现步骤以及实际应用。WebSocket 提供了一种高效、低延迟的实时通信方式,适用于多种应用场景。希望本文能帮助读者更好地理解和应用 WebSocket,提升Web开发能力。
- WebSocket 官方文档
- WebSocket API 参考
- WebSocket 教程
相关文章:

现代Web开发:WebSocket 实时通信详解
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 现代Web开发:WebSocket 实时通信详解 现代Web开发:WebSocket 实时通信详解 现代Web开发:WebS…...

《深度学习》——深度学习基础知识(全连接神经网络)
文章目录 1.神经网络简介2.什么是神经网络3.神经元是如何工作的3.1激活函数3.2参数的初始化3.2.1随机初始化3.2.2标准初始化3.2.3Xavier初始化(tf.keras中默认使用的)3.2.4He初始化 4.神经网络的搭建4.1通过Sequential构建神经网络4.2通过Functional API…...

nginx 部署2个相同的vue
起因: 最近遇到一个问题,在前端用nginx 部署 vue, 发现如果前端有改动,如果不适用热更新,而是直接复制项目过去,会404 因此想到用nginx 负载两套相同vue项目,然后一个个复制vue项目就可以了。…...

利用Java easyExcel库实现高效Excel数据处理
在Java应用程序中,处理Excel文件是一项常见任务,尤其是在需要读取、写入或分析大量数据时。easyExcel是一个基于Java的高性能Excel处理库,它提供了简洁的API和优化的性能,以简化Excel文件的处理。本文将指导您如何使用easyExcel库…...

Vulnhub靶场 Metasploitable: 1 练习(上)
目录 0x00 准备0x01 主机信息收集0x02 Samba服务(CVE-2007-2447)0x03 Distccd(CVE-2004-2687)0x04 Mysql弱口令0x05 Postgresql弱口令0x06 Telnet弱口令0x07 Tomcat 0x00 准备 下载链接:https://download.vulnhub.com/…...

《Python编程实训快速上手》第二天--列表与元组
一、列表 1、理解 列表是一个值,包含由多个值构成的序列 2、元素查找 1)索引--取列表中的单个值 正数索引:同c语言中的数组 spam [[1,2,3,4],["cat","dog"]] print(spam[0][1]) #结果:2 负数索引&…...

jangow靶机
先改jangow的ip设置,无ip地址,重启jangow虚拟机时候快速按E这个键盘,进入到编辑模式,找到ro这个位置,写入ro rw signin init/bin/bash ,ctrlx保存 下一步需要更改网卡名字为ens33,可以直接…...

使用UDP协议传输视频流!(分片、缓存)
背景 最近在开发工作中遇到需要两台本地设备之间进行视频流的传输的情况。但是团队一来没有这方面的专业人才,二来视频流的传续数据量很大,针对TCP和UDP的具体选择也不明确。 本文是在上诉背景之下进行的研究和开发工作。 目录 背景 UDP和TCP协议的…...

Pinia小菠萝(状态管理器)
Pinia 是一个专为 Vue 3 设计的状态管理库,它借鉴了 Vuex 的一些概念,但更加轻量灵活。下面将详细介绍如何使用 Pinia 状态管理库: 安装 Pinia 使用 npm:在项目目录下运行npm install pinia。使用 yarn:在项目目录下运…...

Python知识点:基于Python工具,如何使用Web3.py进行以太坊智能合约开发
开篇,先说一个好消息,截止到2025年1月1日前,翻到文末找到我,赠送定制版的开题报告和任务书,先到先得!过期不候! 基于Python工具Web3.py进行以太坊智能合约开发 简介 智能合约是区块链技术的核…...

【简信CRM-注册安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…...

ssm+vue694基于Java的药店药品信息管理系统的设计与实现
博主介绍:专注于Java(springboot ssm 等开发框架) vue .net php phython node.js uniapp 微信小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设,从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不…...

Sentinel微服务保护
目录 雪崩问题 解决雪崩问题的方法: 我们使用sentinel组件实现微服务的保护 一:下载sentinel 二.启动sentinel 三.访问:localhost:8080 默认的账号和密码都是sentinel 微服务整合sentinel 一.导入sentinel依赖 二.在application.yml配置…...

喜讯!实在Agent智能体入选《2024年度最佳企业服务AI产品榜》
10 月 30 日,硅星人主办的首届 AI 创造者大会(ACC)于北京中关村盛大举行。此次大会旨在为 AI 产业生态的共建者构筑一个多元化的交流平台。大会邀请了硅星人创始人兼 CEO 骆轶航、国家地方共建具身智能机器人创新中心 CTO 唐剑、百度智能云应…...

Aop+自定义注解实现数据字典映射
数据字典 Web项目开发中,字典表的一般都会存在,主要用来给整个系统提供基础服务。 比如男女性别的类型可以使用0和1来进行表示,在存储数据和查询数据的时候,就可以使用字典表中的数据进行翻译处理。 再比如之前做的一个项目中宠物…...

大语言模型(LLM)入门级选手初学教程 III
指令微调 一、指令数据的构建 包括任务描述(也称为指令)、任务输入-任务输出以及可选的示例。 Self-Instruct 指令数据生成:从任务池中随机选取少量指令数据作为示例,并针对Chat-GPT 设计精细指令来提示模型生成新的微调数据…...

STM32G0xx使用LL库将Flash页分块方式存储数据实现一次擦除可多次写入
STM32G0xx使用LL库将Flash页分块方式存储数据实现一次擦除可多次写入 参考例程例程说明一、存储到Flash中的数据二、Flash最底层操作(解锁,加锁,擦除,读写)三、从Flash块中读取数据五、测试验证 参考例程 STM32G0xx HAL和LL库Flash读写擦除操…...

SAP B1 认证考试习题 - 解析版(三)
前一篇:《SAP B1 认证考试习题 - 解析版(二)》 题目纯享版合集:《SAP B1 认证考试习题 - 纯享版》 五、运费(附加费用) 57. 以下哪个选项能够影响库存商品的价格 A. 仅为总量级别的附加费用 B. 只为行级…...

数据库开发规范
一、概述 本规范规定了,软件项目团队开发数据库的全流程规范。规范覆盖了数据库设计、管理及配套文件等。 二、项目阶段 项目阶段包括需求评审(需求分析阶段)、技术评审(方案阶段)、数据库开发…...

使用python向钉钉群聊发送消息
使用python向钉钉群聊发送消息 一、在钉钉群中新建机器人二、使用代码发送消息 一、在钉钉群中新建机器人 在群设置中添加机器人 选择自定义 勾选对应的安全设置 完成后会展示webhook,将地址复制出来,并记录,后面会用到 二、使用代码发送消…...

YOLOv11改进:SE注意力机制【注意力系列篇】(附详细的修改步骤,以及代码,与其他一些注意力机制相比,不仅准确度更高,而且模型更加轻量化。)
如果实验环境尚未搭建成功,可以参考这篇文章 ->【YOLOv11超详细环境搭建以及模型训练(GPU版本)】 文章链接为:YOLOv11超详细环境搭建以及模型训练(GPU版本)-CSDN博客 -------------------------------…...

STM32 基于HAL库和STM32cubeIDE的应用教程 (二)--GPIO的使用
如果有什么不懂的地方欢迎私聊博主,欢迎小白,博主必一一解答。 在 STM32 中,GPIO(通用输入输出)是与外部硬件接口进行交互的主要方式之一。STM32 HAL 库提供了简洁的接口来配置和控制 GPIO 引脚。下面是使用 STM32 HA…...

【毫米波雷达(七)】自动驾驶汽车中的精准定位——RTK定位技术
一、什么是RTK? RTK,英文全名叫做Real-time kinematic,也就是实时动态。这是一个简称,全称其实应该是RTK(Real-time kinematic,实时动态)载波相位差分技术。 二、RTK的组装 如上图所示&#x…...

Transformer和BERT的区别
Transformer和BERT的区别比较表: 两者的位置编码: 为什么要对位置进行编码? Attention提取特征的时候,可以获取全局每个词对之间的关系,但是并没有显式保留时序信息,或者说位置信息。就算打乱序列中token…...

linux 加载uPD720201固件
硬件 jetson orin nano jetpack 35.5.0 uPD720201是瑞萨推出的怕pcie扩展usb3.0芯片,支持flash主动加载与在系统被动加载 本文介绍如何做到没接flash情况下由系统加载固件 在uPD720201没接spi flash时候nano启动会报XhciDxe错误而自动重启,首先需要在ue…...

C语言中的信号量semaphore详解
在C语言中,**信号量(Semaphore)**是一种常用的同步机制,用于控制多个线程或进程对共享资源的访问。信号量可以实现类似于锁的效果,但更为灵活,适用于并发编程场景。 1. 什么是信号量 信号量可以看作是一个…...

0087__DirectX11 With Windows SDK--02 顶点/像素着色器的创建、顶点缓冲区
DirectX11 With Windows SDK--02 顶点/像素着色器的创建、顶点缓冲区-CSDN博客...

Windows换机华为擎云(银河麒麟V10+麒麟9000C CPU)后,使用selenium的程序怎么办(20241030)
原本的 seleniumChrome 已无法正常工作。chromedriver 报错:不支持 Linux/aarch64。 1、尝试Firefox、edge驱动。Firefox有一个geckodriver版本与Firefox版本的对照表,我看了一下,感觉他们是始终跟进新技术的。银河麒麟的很多库都是几年前的…...

linux 下 signal() 函数的用法,信号类型在哪里定义的?
--------------------------------------------------- author: hjjdebug date: 2024年 11月 07日 星期四 14:47:33 CST description: linux 下 signal() 函数的用法 --------------------------------------------------- signal 是linux 下最基础的进程通讯机制…...

享元模式及其运用场景:结合工厂模式和单例模式优化内存使用
介绍 享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享对象来减少内存使用,尤其是对于大量相似对象的场景。享元模式通常与工厂模式和单例模式结合使用,从而有效地控制和复用对象的创建。在享元模式中&am…...