【Node.js从基础到高级运用】二十四、Node.js中实现全双工通信

引言

在本篇博客文章中,我们将详细介绍如何在Node.js环境下使用WebSocket来实现全双工通信。WebSocket协议允许在用户的浏览器和服务器之间建立一个持久的连接,通过这个连接可以实现实时、双向的数据传输。

什么是WebSocket?

WebSocket是一种网络通信协议,提供了一种在单个TCP连接上进行全双工通信的方式。与传统的HTTP请求不同,WebSocket在建立连接后可以保持连接状态,使得数据可以随时从客户端发送到服务器,或者从服务器发送到客户端。

开始之前

在开始之前,请确保你的电脑上已经安装了Node.js。你可以通过访问Node.js官网来下载并安装最新版本的Node.js。

步骤1:创建Node.js项目

首先,打开命令提示符或终端,然后执行以下命令来创建一个新的Node.js项目:

mkdir websocket-demo
cd websocket-demo
npm init -y

这些命令将创建一个新的文件夹websocket-demo,并初始化一个新的Node.js项目。

步骤2:安装WebSocket库

我们将使用ws库来实现WebSocket通信。在项目文件夹中执行以下命令来安装ws库:

npm install ws

步骤3:创建WebSocket服务器

创建一个名为server.js的新文件,并添加以下代码:

const WebSocket = require('ws'); // 引入WebSocket库// 创建WebSocket服务器,监听端口3000
const wss = new WebSocket.Server({ port: 3000 });// 当有客户端连接时触发
wss.on('connection', function connection(ws) {console.log('客户端已连接');// 当从客户端接收到消息时触发ws.on('message', function incoming(message) {console.log('收到消息:', message);// 将消息回传给客户端ws.send(`服务器收到消息:${message}`);});// 向客户端发送欢迎消息ws.send('欢迎连接到WebSocket服务器');
});console.log('WebSocket服务器正在监听端口3000...');

在这段代码中,我们创建了一个WebSocket服务器,监听3000端口。当有客户端连接时,我们会向客户端发送一条欢迎消息,并监听客户端发送的消息。当收到消息时,我们会将其打印出来,并发送一条回复消息。

步骤4:创建客户端HTML页面

创建一个名为index.html的新文件,并添加以下代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket客户端示例</title>
<script>// 当页面加载完成时执行window.onload = function() {// 创建WebSocket连接const socket = new WebSocket('ws://localhost:3000');// 当连接打开时触发socket.onopen = function() {console.log('WebSocket连接已打开');// 发送消息到服务器socket.send('你好,服务器!');};// 当收到服务器消息时触发socket.onmessage = function(event) {console.log('收到服务器消息:', event.data);};// 当连接关闭时触发socket.onclose = function() {console.log('WebSocket连接已关闭');};// 当发生错误时触发socket.onerror = function(error) {console.error('WebSocket发生错误:', error);};};
</script>
</head>
<body>
<h1>WebSocket客户端示例</h1>
</body>
</html>

在这个HTML页面中,我们创建了一个WebSocket客户端,它会尝试连接到我们之前创建的WebSocket服务器。一旦连接成功,它会发送一条消息到服务器,并监听从服务器接收到的消息。

步骤5:运行WebSocket服务器

返回命令提示符或终端,运行以下命令来启动WebSocket服务器:

node server.js

步骤6:打开客户端HTML页面

在浏览器中打开index.html文件,你应该能够看到控制台中打印出“WebSocket连接已打开”和“收到服务器消息”的信息。

至此,你已经成功创建了一个简单的全双工WebSocket通信示例。客户端和服务器可以实时地发送和接收消息。

进阶:多个客户端之间的通信和消息广播

为了实现多个客户端之间的通信和消息广播,我们需要对之前的服务器代码进行一些修改。以下是一个简单的示例,展示了如何在WebSocket服务器上实现消息广播,使得一个客户端发送的消息可以被所有连接的客户端接收。

首先,我们修改server.js文件,添加广播功能:

const WebSocket = require('ws'); // 引入WebSocket库// 创建WebSocket服务器,监听端口3000
const wss = new WebSocket.Server({ port: 3000 });// 广播给所有客户端的函数
function broadcast(message) {// 遍历所有客户端wss.clients.forEach(function each(client) {// 检查客户端是否处于打开状态if (client.readyState === WebSocket.OPEN) {// 向客户端发送消息client.send(message);}});
}// 当有客户端连接时触发
wss.on('connection', function connection(ws) {console.log('客户端已连接');// 当从客户端接收到消息时触发ws.on('message', function incoming(message) {console.log('收到消息:', message);// 广播消息给所有连接的客户端broadcast(`客户端说:${message}`);});// 向客户端发送欢迎消息ws.send('欢迎连接到WebSocket服务器');
});console.log('WebSocket服务器正在监听端口3000...');

在这个修改后的版本中,我们添加了一个broadcast函数,它会遍历所有连接的客户端,并向它们发送消息。当服务器接收到一个客户端发送的消息时,它会调用broadcast函数,将这个消息发送给所有其他客户端。

客户端的代码可以保持不变,因为它们只需要处理从服务器接收到的消息。当你运行这个服务器并从一个客户端发送消息时,所有连接的客户端都会收到这条消息。

现在,你可以通过以下步骤来测试广播功能:

  1. 运行修改后的server.js文件来启动WebSocket服务器。
  2. 在浏览器中多次打开index.html文件以创建多个客户端。
  3. 从任何一个客户端发送消息,观察其他客户端是否也收到了相同的消息。

通过这种方式,你可以实现一个简单的聊天室功能,其中一个客户端的消息会被广播到所有其他客户端。这是实现多客户端通信的基础,并且可以根据具体需求进行扩展和优化。

总结

在本篇博客文章中,我们详细介绍了如何在Node.js环境下使用WebSocket实现全双工通信。我们首先了解了WebSocket协议的基本概念,然后逐步搭建了一个简单的WebSocket服务器和客户端。通过实际的代码示例,我们展示了如何在服务器端创建WebSocket服务,并在客户端页面中建立与服务器的连接以及进行消息的发送和接收。

通过以上步骤,我们可以总结出实现WebSocket通信的关键点:

  1. 使用ws库在Node.js中创建WebSocket服务器。
  2. 监听服务器端口,并为每个连接的客户端创建事件处理。
  3. 在客户端使用原生的WebSocket API与服务器建立连接,并处理打开、消息接收、关闭和错误事件。
  4. 实现了客户端和服务器之间的实时、双向通信。

WebSocket技术为实现实时Web应用提供了强大的支持,它可以用于聊天应用、在线游戏、实时数据推送等多种场景。通过本文的指南,你应该能够掌握基本的WebSocket通信流程,并能够在自己的项目中应用这一技术。

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

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

相关文章

ARM64架构栈帧回溯

文章目录 前言一、栈帧简介二、demo演示 前言 请参考&#xff1a;ARM64架构栈帧以及帧指针FP 一、栈帧简介 假设下列函数调用&#xff1a; funb() {func() }funa() {funb() }main() {funa() }main函数&#xff0c;funa函数&#xff0c;funb函数都不是叶子函数&#xff0c;其…

MySQL 的事务概念

事务概念 MySQL事务是一个或者多个的数据库操作&#xff0c;要么全部执行成功&#xff0c;要么全部失败回滚。 事务是通过事务日志来实现的&#xff0c;事务日志包括&#xff1a;redo log和undo log。 事务状态 事务有以下五种状态&#xff1a; 活动的部分提交的失败的中止的…

详解爬虫基本知识及入门案列(爬取豆瓣电影《热辣滚烫》的短评 详细讲解代码实现)

目录 前言什么是爬虫&#xff1f; 爬虫与反爬虫基础知识 一、网页基础知识 二、网络传输协议 HTTP&#xff08;HyperText Transfer Protocol&#xff09;和HTTPS&#xff08;HTTP Secure&#xff09;请求过程的原理&#xff1f; 三、Session和Cookies Session Cookies Session与…

Java:如何轻松获取当前执行的方法名

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 在编程的世界里&#xff0c;经常会遇到各种各样的问题。有时候&#xff0c;需要了解当前执行的方法名&#xff0c;以便更好地调试代码或者记录日志。那么&#xff0c;如何在Java中轻松获取当前执行的方法名呢&#x…

【linux备份文件】将文件夹copy到另一位置解决方案

要将文件夹压缩成zip文件&#xff0c;可以使用以下命令&#xff1a; zip -r <压缩文件名.zip> <文件夹路径> 复制代码 其中&#xff0c;<压缩文件名.zip>是你希望生成的zip文件的名称&#xff0c;<文件夹路径>是需要压缩的文件夹的路径。 例如&#xf…

Cesium简单案例

一、Cesium组件 1、HTML <template><div id"cesiumContainer"><!-- 地图工具栏 --><ul class"mapTools"><li v-for"item in toolsData" :key"item.id" click"toolsClick(item)"><!-- 显…

for in 遍历对象,顺序不对

第一次遍历对象会导致时间乱序&#xff0c;如下&#xff1a; var obj { "key1":{"tenantId":""}, "key2":{"tenantId":"1720336885402484738"}, "key16":{"areaId":"1772463994999468…

股权融资成本GLS模型计算

一、模型公式 式中&#xff1a; r 为股权融资成本 P为股价 B为每股净资产 FROE为预测每股净资产收益率 目标&#xff1a;求解股权融资成本r 二、模型口径参考来源 PS&#xff1a;实际以代码为准 ①FROE&#xff08;预测每股净资产收益率&#xff09;: 资本市场开放与…

“R+遥感”的水环境综合评价方法实践技术应用

张博士&#xff0c;来自重点高校及科研院所一线科研人员&#xff0c;长期从事机器学习、遥感技术与应用研究&#xff0c;主持多项国家级科研项目&#xff0c;编写著作3部&#xff0c;第一作者发表科研论文20余篇。对国内外遥感技术的多平台、多传感器应用现状&#xff0c;以及涉…

基于python的pdf2word(可以批量转换)

介绍 pdf2word是一个基于Python的命令行工具,可以将PDF文件批量转换为Word文档。该项目利用了Python的强大功能和多个第三方库,如pdfminer和python-docx,以实现高效、准确的转换。 项目功能: 批量转换:用户可以指定一个文件夹,pdf2word会自动查找该文件夹中的所有PDF文…

【leetcode面试经典150题】59. 合并两个有序链表(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

Elasticsearch:简化 KNN 搜索

作者&#xff1a;来自 Elastic Panagiotis Bailis 在这篇博客文章中&#xff0c;我们将深入探讨我们为了使 KNN 搜索的入门体验变得更加简单而做出的努力&#xff01; 向量搜索 向量搜索通过在 Elasticsearch 中引入一种新的专有的 KNN 搜索类型&#xff0c;已经可以使用一段…

题解:P9426 [蓝桥杯 2023 国 B] 抓娃娃

思路 1.其实题目保证了 max ⁡ r i − l i ≤ min ⁡ R i − L i \max{r_i − l_i} \le \min{R_i − L_i} maxri​−li​≤minRi​−Li​&#xff0c;那么如果占了一半的话&#xff0c;那么肯定包含了中点&#xff0c;做一个前缀和就好了。 2.因为涉及了小数&#xff0c;给每…

【粉丝福利 | 第5期】教你快速入门三大层次学习企业架构框架TOGAF

⛳️ 写在前面参与规则&#xff01;&#xff01;&#xff01; ✅参与方式&#xff1a;关注博主、点赞、收藏、评论&#xff0c;任意评论&#xff08;每人最多评论三次&#xff09; ⛳️本次送书1~4本【取决于阅读量&#xff0c;阅读量越多&#xff0c;送的越多】 三大层次学习…

如何取消电脑屏幕保护?学会这3招,操作无难度!

“我之前在电脑上设置了电脑屏幕保护&#xff0c;现在想将它取消掉&#xff0c;大家有什么比较好的方法可以分享一下吗&#xff1f;” 在日常使用电脑的过程中&#xff0c;屏幕保护程序是一个常见的功能。它可以在电脑空闲一段时间后自动启动&#xff0c;以动画或图片的形式展示…

玄子Share-网络布线与数制转换

玄子Share-网络布线与数制转换 网络传输介质 信号概述 什么是信号 信息数据信号 信号的分类 模拟信号数字信号 信号在传输过程中产生的失真 噪声距离速度 数字信号的优势 抗干扰能力强传输距离远并能保证质量 双绞线 双绞线 总共8根双绞线&#xff0c;两两绞合在一起常用…

C语言—常用字符串函数剖析

字符串函数 cplusplus.com/reference/cstring/ 更多没有总结到的函数大家可以自行查阅 这篇文章只是把最需要知道的函数做一个总结 strlen size_t strlen ( const char * str );字符串已经 ‘\0’ 作为结束标志&#xff0c;strlen函数返回的是在字符串中 ‘\0’ 前面出现的…

软考 - 系统架构设计师 - 架构风格例题

问题一&#xff1a; 什么是软件架构风格&#xff1f; 软件架构风格指特定软件系统组织方式的惯用模式。组织方式描述了系统的组成构件和这些构件的组织方式。惯用模式反映了众多系统所共有的结构和语义。 集成开发环境与用户的交互方式 &#xff08;实际上询问在交互方面&am…

聚观早报 | 华为Pura70系列先锋计划;月之暗面升级Kimi

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 4月19日消息 华为Pura70系列先锋计划 月之暗面升级Kimi OPPO Find X7将推白色版本 波士顿动力推出人形机器人 v…

Tomcat漏洞利用工具-TomcatVuln

检测漏洞清单 CVE-2017-12615 PUT文件上传漏洞 tomcat-pass-getshell 弱认证部署war包 弱口令爆破 CVE-2020-1938 Tomcat 文件读取/包含项目地址 https://github.com/errors11/TomcatVuln TomcatVuln put文件上传 ajp协议漏洞 默认读取web.xml文件&#xff0c;漏洞利用…