在nodejs中实现实时通信的几种方式
在nodejs中实现实时通信的几种方式
在当今世界中,实时通信至关重要。无论是聊天应用程序还是实时体育更新,实时通信都是保持用户活跃度所必需的。Node.js 因其速度、可扩展性和可靠性而成为开发实时应用程序的流行工具。在本文中,我们将探讨为什么 Node.js 是实时通信的理想选择以及如何实现它。
为什么使用 Node.js 进行实时通信?
Node.js 构建在 Google 的 V8 JavaScript 引擎之上,该引擎以其高性能而闻名。这使得 Node.js 成为构建需要速度和可扩展性的实时通信应用程序的完美工具。Node.js 也是事件驱动的,这意味着它可以同时处理多个连接,非常适合构建实时应用程序。
协议和库的类型
Node.js 提供了多种方式来实现实时数据通信。Node.js 中实时数据通信的一些流行库是:
socket.io
socket.io是一个流行的实时通信库。它使用 WebSockets 作为传输层来提供客户端和服务器之间的实时通信。socket.io 提供了许多功能,例如自动重新连接、对二进制数据的支持以及不支持 WebSocket 的环境的回退选项。

示例代码
服务器端代码:
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);io.on('connection', (socket) => {console.log('User connected');socket.on('chat:message', (data) => {io.emit('chat:message', data);});socket.on('disconnect', () => {console.log('User disconnected');});
});const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {console.log(`Server listening on port ${PORT}`);
});
客户端代码:
<!DOCTYPE html>
<html>
<head><title>Socket.IO Chat</title>
</head>
<body><div id="messages"></div><form id="chat-form"><input type="text" id="message-input"><button type="submit">Send</button></form><script src="/socket.io/socket.io.js"></script><script>const socket = io();const messagesDiv = document.getElementById('messages');const chatForm = document.getElementById('chat-form');const messageInput = document.getElementById('message-input');chatForm.addEventListener('submit', (event) => {event.preventDefault();const message = messageInput.value.trim();if (message) {socket.emit('chat:message', message);messageInput.value = '';}});socket.on('chat:message', (data) => {const messageDiv = document.createElement('div');messageDiv.innerText = data;messagesDiv.appendChild(messageDiv);});</script>
</body>
</html>
WebSockets
WebSockets 是一种支持客户端和服务器之间实时通信的协议。它通过单个 TCP 连接提供全双工通信通道,允许客户端和服务器之间进行实时数据交换。ws模块可用于实现 WebSockets。

示例代码
服务器端代码:
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 3000 });server.on('connection', (socket) => {console.log('User connected');socket.on('message', (message) => {server.clients.forEach((client) => {if (client.readyState === WebSocket.OPEN) {client.send(message);}});});socket.on('close', () => {console.log('User disconnected');});
});
客户端代码:
<!DOCTYPE html>
<html>
<head><title>WebSockets Chat</title>
</head>
<body><div id="messages"></div><form id="chat-form"><input type="text" id="message-input"><button type="submit">Send</button></form>
<script>const socket = new WebSocket('ws://localhost:3000');const messagesDiv = document.getElementById('messages');const chatForm = document.getElementById('chat-form');const messageInput = document.getElementById('message-input');chatForm.addEventListener('submit', (event) => {event.preventDefault();const message = messageInput.value.trim();if (message) {socket.send(message);messageInput.value = '';}});socket.addEventListener('message', (event) => {const messageDiv = document.createElement('div');messageDiv.innerText = event.data;messagesDiv.appendChild(messageDiv);});</script>
</body>
</html>
服务器发送事件
服务器发送事件是一个简单的协议,允许服务器通过 HTTP 连接向客户端发送事件。它非常适合需要单向通信的应用程序,例如现场体育赛事比分或股票市场更新。该模块称为sse,可用于实现服务器发送事件。

示例代码
服务器端代码:
const express = require('express');
const app = express();app.get('/events', (req, res) => {res.writeHead(200, {'Content-Type': 'text/event-stream','Cache-Control': 'no-cache','Connection': 'keep-alive'});const interval = setInterval(() => {res.write(`data: ${new Date().toLocaleTimeString()}\n\n`);}, 1000);req.on('close', () => {clearInterval(interval);res.end();});
});const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {console.log(`Server listening on port ${PORT}`);
});
客户端代码:
<!DOCTYPE html>
<html>
<head><title>Server-Sent Events Clock</title>
</head>
<body><div id="clock"></div>
<script>const source = new EventSource('/events');const clockDiv = document.getElementById('clock');source.addEventListener('message', (event) => {clockDiv.innerText = event.data;});</script>
</body>
</html>
WebRTC
WebRTC 是一种实时通信协议,允许浏览器建立点对点连接。它在客户端之间提供低延迟的通信通道,而无需服务器。wrtc库可用于实现 WebRTC。

示例代码
服务器端代码:
const express = require('express');
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
const { RTCPeerConnection, RTCSessionDescription, RTCIceCandidate } = require('wrtc');
app.use(express.static('public'));io.on('connection', socket => {console.log('Client connected:', socket.id);let pc = new RTCPeerConnection();socket.on('offer', offer => {console.log('Received offer');pc.setRemoteDescription(new RTCSessionDescription(offer)).then(() => {return navigator.mediaDevices.getUserMedia({ audio: true, video: true });}).then(stream => {console.log('Got local stream');stream.getTracks().forEach(track => {pc.addTrack(track, stream);});pc.onicecandidate = event => {if (event.candidate) {socket.emit('candidate', event.candidate);}};pc.ontrack = event => {console.log('Received remote stream');socket.emit('answer', pc.localDescription);};pc.createAnswer().then(answer => {return pc.setLocalDescription(answer);}).catch(error => {console.log('Error creating answer:', error);});}).catch(error => {console.log('Error getting user media:', error);});});socket.on('disconnect', () => {console.log('Client disconnected:', socket.id);pc.close();});
});const PORT = process.env.PORT || 3000;
http.listen(PORT, () => {console.log(`Server listening on port ${PORT}`);
});
客户端代码:
<html><head><meta charset="UTF-8"><title>WebRTC Example</title></head><body><h1>WebRTC Example</h1><div><video id="localVideo" autoplay></video><video id="remoteVideo" autoplay></video></div><div><button id="callButton">Call</button><button id="hangupButton" disabled>Hang Up</button></div><script src="/socket.io/socket.io.js"></script><script>const socket = io.connect('http://localhost:3000');const localVideo = document.getElementById('localVideo');const remoteVideo = document.getElementById('remoteVideo');const callButton = document.getElementById('callButton');const hangupButton = document.getElementById('hangupButton');let pc = new RTCPeerConnection();hangupButton.disabled = true;callButton.onclick = () => {console.log('Calling');navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then(stream => {console.log('Got local stream');localVideo.srcObject = stream;stream.getTracks().forEach(track => {pc.addTrack(track, stream);});pc.onicecandidate = event => {if (event.candidate) {socket.emit('candidate', event.candidate);}};pc.ontrack = event => {console.log('Received remote stream');remoteVideo.srcObject = event.streams[0];};pc.createOffer().then(offer => {return pc.setLocalDescription(offer);}).then(() => {socket.emit('offer', pc.localDescription);}).catch(error => {console.log('Error creating offer:', error);});hangupButton.disabled = false;hangupButton.onclick = () => {console.log('Hanging up');pc.close();remoteVideo.srcObject = null;hangupButton.disabled = true;callButton.disabled = false;};}).catch(error => {console.log('Error getting user media:', error);});};socket.on('answer', answer => {console.log('Received answer');pc.setRemoteDescription(new RTCSessionDescription(answer)).catch(error => {console.log('Error setting remote description:', error);});});socket.on('candidate', candidate => {console.log('Received candidate');pc.addIceCandidate(new RTCIceCandidate(candidate)).catch(error => {console.log('Error adding ice candidate:', error);});});</script></body>
</html>
MQTT
mqtt 是一种轻量级消息传递协议,非常适合 IoT 应用程序。它为客户端和服务器之间的通信提供了发布/订阅模型。该模块称为mqtt,可用于实现 mqtt。

示例代码
发布者端代码:
const mqtt = require('mqtt');
const client = mqtt.connect('mqtt://test.mosquitto.org');client.on('connect', () => {console.log('connected to MQTT broker');setInterval(() => {client.publish('test', 'Hello MQTT');}, 1000);
});client.on('error', (error) => {console.log(error);
});
订阅者端代码:
const mqtt = require('mqtt');
const client = mqtt.connect('mqtt://test.mosquitto.org');client.on('connect', () => {console.log('connected to MQTT broker');client.subscribe('test', (error) => {if (error) {console.log(error);}});
});client.on('message', (topic, message) => {console.log(`${topic}: ${message}`);
});client.on('error', (error) => {console.log(error);
});
如何确保这种通信的安全
安全性对于任何实时通信应用程序都是至关重要的。可以使用crypto模块,用于保护客户端和服务器之间的通信。该模块提供加密和解密功能,使得在客户端和服务器之间发送加密消息成为可能。
此外,每种类型都有模块,例如,在 WebSocket 中,有ws模块,安全的方法是用https而不是http包装它。
结论
Node.js 因其速度、可扩展性和可靠性而成为构建实时通信应用程序的绝佳选择。其事件驱动架构使得同时处理多个连接成为可能,并且V8 JavaScript引擎的使用确保了高性能能力。在 socket.io 等库的帮助下,使用 Node.js 构建实时通信应用程序非常简单。
然而,在处理实时通信应用程序时,安全性至关重要,并且必须使用加密来保护客户端和服务器之间的通信。
还提供了实现实时数据通信的各种方法,每种方法都有自己的一组功能和优点。选择正确的方法取决于您的应用程序的具体要求。socket.io 和 WebSockets 是最流行的实时通信方法,而服务器发送事件、WebRTC 和 MQTT 适用于特定用例。
总体而言,Node.js 是构建实时通信应用程序的强大工具,对于任何需要实时通信的项目都值得考虑。
相关文章:
在nodejs中实现实时通信的几种方式
在nodejs中实现实时通信的几种方式 在当今世界中,实时通信至关重要。无论是聊天应用程序还是实时体育更新,实时通信都是保持用户活跃度所必需的。Node.js 因其速度、可扩展性和可靠性而成为开发实时应用程序的流行工具。在本文中,我们将探讨…...
【tg】 7 GroupInstanceCustomImpl
group GroupInstanceCustomImpl 核心GroupInstanceCustomInternal G:\CDN\P2P-DEV\tdesktop-offical\Telegram\ThirdParty\tgcalls\tgcalls\group\GroupInstanceCustomImpl.h 最核心是是GroupInstanceCustomInternal: private:std::shared_ptr<Threads> _threads;std::u…...
kubernates 集群实战-安装K3s集群
安装K3s集群 安装K3s集群环境准备安装 docker主节点安装work 节点验证环境 安装K3s集群 K3S是一种轻量级的Kubernetes发行版,安装和运行只需要一个二进制文件。相比之下,K8S需要更多的步骤和资源来安装和部署,例如设置etcd集群、安装控制平面…...
通俗介绍:什么是 Redis ?
刚接触 Redis 的伙伴们可能会因为不熟悉而感到困惑。本文简述 Redis 是什么、有哪些作用的问题,是一篇短浅而入门级别的文章。 Redis官网:Redis 打开 Redis 官网可以看到,官方对 Redis 的介绍是这样的:The open source, in-memo…...
蓝桥算法赛(摆玩具)
问题描述 小蓝是一个热爱收集玩具的小伙子,他拥有 n 个不同的玩具。 这天,他把 n 个玩具按照高度顺序从矮到高摆放在了窗台上,然后,他希望将这些玩具分成 k 个段,使得所有分段的极差之和尽可能小。 具体来说&…...
vueDay04——v-if else show
一、v-if的使用 我们可以像c语言一样去使用v-if结构 比如单用v-if,连用v-if v-else,或者是v-if v-else-if v-else 注意: 1.v-if v-else-if需要绑定值,而v-else不需要绑定值 2.if结构可以用在不同的标签类型之间 <div v-if"fir…...
大数据技术学习笔记(二)—— Hadoop 运行环境的搭建
目录 1 准备模版虚拟机hadoop1001.1 修改主机名1.2 修改hosts文件1.3 修改IP地址1.3.1 查看网络IP和网关1.3.2 修改IP地址 1.4 关闭防火墙1.5 创建普通用户1.6 创建所需目录1.7 卸载虚拟机自带的open JDK1.8 重启虚拟机 2 克隆虚拟机3 在hadoop101上安装JDK3.1 传输安装包并解压…...
leetcode系列(双语)002——GO两数相加
文章目录 两数相加 | Add Two Numbers示例个人解答官方解答扩展Algorithm 两数相加 | Add Two Numbers You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a sing…...
废柴勇士(据说没有人能坚持37秒)
欢迎来到程序小院 废柴勇士 玩法:点击屏幕下方左右按键击杀怪物,怪物会在左右方向同时来袭,快速点击按钮进行击杀怪物,看您能够坚持多少秒, 据说还没有能够坚持37秒,快去击杀怪物挑战吧^^。开始游戏https:…...
buuctf_练[羊城杯2020]easyphp
[羊城杯2020]easyphp 文章目录 [羊城杯2020]easyphp掌握知识解题思路关键paylaod 掌握知识 .htaccess文件的利用,把自己指定当做 php文件处理;preg_match正则匹配的了解,stristr函数的绕过;file_put_contents文件写入操作的了…...
【Linux】安装配置虚拟机及虚拟机操作系统的安装
目录 一、操作系统 1. 介绍 2. 功能 3. 有哪些 4. 个人版本和服务器版本的区别 二、VMWare虚拟机 1. 安装 2. 配置 三、安装配置Windows Server 1. 配置 2. 安装 四、虚拟机的环境配置及连接 1. 主机连接虚拟机 2. 虚拟机环境配置及共享 3. 环境配置 一、操作系…...
hugo-stack for github
静态博客框架jekyll、hexo和hugo三者之间的区别与差异 博客生成器? 全名为静态网站生成器, 可在任意拥有主机功能的环境下寄存(托管)可直接配合域名进行全球访问 劣势: 每次更新网页必须重新生成整个网站编译速度(单位:秒) Jek…...
【uniapp】proxy 代理切换至线上测试地址调试接口
本地测试地址形如:http://192.168.124.x:xxxx 线上测试地址形如:https://xxxx.xxxx.com 使用线上地址之后需要修改配置项 secure 为 true const constant require(./src/utils/constant) module.exports {devServer: {proxy: {/api: {target: constan…...
对比Vue2和Vue3的自定义指令
一、自定义指令简介 自定义指令是Vue提供的能力,用于注册自定义的指令,从而实现一些自定义的DOM操作。 二、Vue2中自定义指令 在Vue2中,自定义指令通过全局方法Vue.directive()进行注册: // 注册全局指令v-focus Vue.directive(focus, {inserted: function(el) {el.focus()…...
Python:实现日历到excel文档
背景 日历是一种常见的工具,用于记录事件和显示日期。在编程中,可以使用Python编码来制作日历。 Python提供了一些内置的模块和函数,使得制作日历变得更加简单。 在本文,我们将探讨如何使用Python制作日历,并将日历输出到excel文档中。 效果展示 实现 在代码中会用到cale…...
C++ 异常和错误处理机制:如何使您的程序更加稳定和可靠
在C编程中,异常处理和错误处理机制是非常重要的。它们可以帮助程序员有效地处理运行时错误和异常情况。本文将介绍C中的异常处理和错误处理机制。 什么是异常处理? 异常处理是指在程序执行过程中发生异常或错误时,程序能够捕获并处理这些异常…...
第1章 Java、IDEA环境部署与配置
JavaEE简介与IDE环境部署 课程目录 JavaEE简介JDK环境部署IntelliJ IDEA环境部署 JavaEE简介 1. JavaEE是什么? Java EE(Java Platform,Enterprise Edition)是sun公司(2009年4月20日甲骨文将其收购)推…...
如何进行二进制文件的读写操作?
在C语言中,进行二进制文件的读写操作是非常常见的任务,尤其在处理文件、图像、音频和视频等二进制数据时。本文将详细介绍如何进行二进制文件的读写操作,包括如何打开文件、读取文件、写入文件以及关闭文件。我们将使用标准C库中的函数来执行…...
python实现PDF表格与文本分别导出EXCEL
现需将pdf 转换至Excel , 目前实现方式:将PDF的TABLE部分与 非 TABLE部分分别导出至Excel两个sheet中 1)、识别PDF中的表格块 2)、将PDF转换为Word格式 3)、提取Word中非表格的文本数据 4)、对文本与表格重…...
Java开发-WebSocket
WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信-浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并实现 双向数据传输。 使用 导入maven坐标 <dependency><groupId>org.springframework.bo…...
Qwen3-ASR-0.6B与Java集成:企业级语音处理方案
Qwen3-ASR-0.6B与Java集成:企业级语音处理方案 1. 引言 想象一下这样的场景:你的客服中心每天要处理成千上万的电话录音,传统的人工转录不仅成本高昂,还容易出错。或者你的移动应用需要实时语音转文字功能,但现有的云…...
Aurix/Tricore实验解析:从链接脚本到汇编指令的Trap向量表构建
1. 理解Trap机制与向量表基础 在Aurix/Tricore架构中,Trap(陷阱)是处理器响应异常事件的硬件机制,相当于汽车的安全气囊——平时看不见,但遇到碰撞时会立即触发保护。与中断不同,Trap是同步触发的ÿ…...
Wan2.2-I2V-A14B实战案例:地方政府生成‘乡村振兴’政策解读动画短视频系列
Wan2.2-I2V-A14B实战案例:地方政府生成乡村振兴政策解读动画短视频系列 1. 项目背景与需求分析 近年来,随着数字政务的快速发展,各级地方政府越来越重视利用新媒体技术进行政策宣传。某地方政府计划开展"乡村振兴"系列政策解读工…...
智能猫砂盆:除臭静音,养猫更省心!
行业痛点分析当前智能猫砂盆领域面临两大核心挑战:清洁残留与安全防护。传统自动铲屎机型在完成集便动作后,猫砂盆底部仍会残留约15%-20%的沾尿结团猫砂(数据表明:第三方实验室对6款主流机型测试结果),用户…...
CTF逆向实战:从RC4到Base64,手把手拆解CTFshow赛题
1. RC4加密实战:从文件分析到密钥破解 第一次接触CTF逆向题时,看到RC4加密可能会觉得无从下手。但实际拆解后你会发现,这类题目往往藏着明显的突破口。就拿CTFshow这道re2赛题来说,整个解题过程就像在玩解谜游戏。 用IDA打开题目…...
Z-Image-Turbo-辉夜巫女数据预处理实战:模拟VLOOKUP实现提示词与风格模板匹配
Z-Image-Turbo-辉夜巫女数据预处理实战:模拟VLOOKUP实现提示词与风格模板匹配 你有没有遇到过这样的烦恼?每次用AI画图,想生成一个“赛博朋克”风格的图片,都得重新回忆或者翻找之前写好的那一长串复杂的提示词。或者团队里每个人…...
OBS Advanced Timer:全场景直播计时神器,让你的直播节奏掌控自如
OBS Advanced Timer:全场景直播计时神器,让你的直播节奏掌控自如 【免费下载链接】obs-advanced-timer 项目地址: https://gitcode.com/gh_mirrors/ob/obs-advanced-timer 作为主播,你是否曾因手动计时失误导致直播环节超时ÿ…...
终极指南:如何用Vortex模组管理器轻松管理250+游戏模组
终极指南:如何用Vortex模组管理器轻松管理250游戏模组 【免费下载链接】Vortex Vortex: Nexus-Mods开发的游戏模组管理器,用于简化模组的安装和管理过程。 项目地址: https://gitcode.com/gh_mirrors/vor/Vortex 还在为游戏模组安装繁琐、冲突不断…...
从MATLAB验证到FPGA上板:双频信号叠加的完整开发闭环实战
从MATLAB验证到FPGA上板:双频信号叠加的完整开发闭环实战 在数字信号处理领域,实现双频信号的精确叠加是一个常见但极具挑战性的任务。无论是通信系统中的载波调制,还是音频处理中的音效合成,都需要工程师能够准确地在硬件层面实现…...
实战指南:基于快马平台,快速构建可部署的unet卫星图像分割系统
今天想和大家分享一个实战项目:基于UNet的卫星图像建筑物分割系统。这个项目特别适合在InsCode(快马)平台上快速搭建,因为它涉及从数据处理到模型部署的完整流程,而平台的一键部署功能正好能省去繁琐的环境配置工作。 项目背景与需求分析 卫星…...
