【Node.js】WebSockets

概述

WebSockets是一种在浏览器和服务器之间建立持久连接的协议,它允许服务器主动推送数据给客户端,并且在客户端和服务器之间实现双向通信。

  1. 建立连接:客户端通过在JavaScript代码中使用WebSocket对象来建立WebSockets连接。例如:var socket = new WebSocket('ws://example.com/socket');

  2. 协议:WebSockets使用标准的WebSocket协议来进行通信。相对于HTTP协议,WebSocket协议提供了更高效率和更低的延迟。ws和wss协议正对应了http和https。

  3. 服务器支持:为了使用WebSockets,服务器必须支持WebSocket协议。

  4. 事件:WebSocket对象提供了一些事件,用于处理连接的不同阶段和接收到的数据。常见的事件有onopen(连接建立)、onmessage(接收到消息)、onclose(连接关闭)等。

  5. 数据传输:WebSockets可以传输文本和二进制数据。文本数据是以UTF-8编码发送和接收的,而二进制数据使用ArrayBuffer对象。

  6. 安全性:与HTTP协议通过TLS/SSL协议进行加密一样,WebSockets也可以通过wss协议来提供安全的通信。wss://表示通过TLS/SSL加密的WebSockets连接。

  7. 跨域策略:WebSockets默认不受同源策略的限制,可以跨域使用,但仍然会受到服务器的安全策略限制。

可以在浏览器和服务器之间建立稳定的连接,实际应用如聊天应用、实时数据监控等。

基本使用

使用WebSockets进行连接和通信:

首先,在客户端使用WebSocket对象来建立连接:

var socket = new WebSocket('ws://example.com/socket');// 监听连接建立事件
socket.onopen = function() {console.log('WebSocket连接已建立');// 向服务器发送消息socket.send('Hello Server!');
};// 监听接收到消息事件
socket.onmessage = function(event) {var message = event.data;console.log('接收到服务器消息:' + message);
};// 监听连接关闭事件
socket.onclose = function() {console.log('WebSocket连接已关闭');
};

在上面的代码中,我们创建了一个WebSocket对象并指定连接的URL。然后我们监听了三个事件:onopen表示连接建立时触发的事件,onmessage表示接收到消息时触发的事件,onclose表示连接关闭时触发的事件。

在连接建立后,我们向服务器发送了一条消息Hello Server!。当服务器向客户端发送消息时,onmessage事件将被触发,并且我们可以在回调函数中处理接收到的消息。

接下来,让我们看一下服务器端的示例代码(以Node.js和Express框架为例):

const express = require('express');
const WebSocket = require('ws');const app = express();// 创建WebSocket服务器
const server = require('http').createServer(app);
const wss = new WebSocket.Server({ server });wss.on('connection', function(socket) {console.log('WebSocket连接已建立');// 监听客户端发送的消息socket.on('message', function(message) {console.log('接收到客户端消息:' + message);// 向客户端发送消息socket.send('Hello Client!');});// 监听连接关闭事件socket.on('close', function() {console.log('WebSocket连接已关闭');});
});server.listen(3000, function() {console.log('服务器已启动,监听端口3000');
});

在服务器端的代码中,我们使用了ws库创建了一个WebSocket服务器,并监听了connection事件。当有客户端连接到服务器时,connection事件将被触发,并在该回调函数中处理连接过程。

在服务器接收到客户端的消息时,我们输出消息到控制台,并向客户端发送一条回复消息。当连接关闭时,close事件将被触发。

最后,我们在Express应用中创建了一个HTTP服务器,将WebSocket服务器绑定到服务器上,然后启动服务器监听端口3000。

通信小实例

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<script>const ws = new WebSocket('ws://localhost:3000')ws.addEventListener('open',()=> {console.log('已连接服务器')ws.send('我是前端的数据')})ws.addEventListener('message', ({data})=> {console.log(data)})
</script>
</body>
</html>
const WebSocket = require('ws')
const socket = new WebSocket.Server({port: 3000});socket.on('connection',ws=> {console.log('我进来了')ws.on('message',(data)=> {console.log('前端数据:' + data + "。后端返回数据:"+ '我是后端的数据')})ws.on('close',()=> {console.log('溜了溜了')})
})

image.png

Socket.io

Socket.io 具有跨平台,实时性,WebSocket 不可连接时自动降级到其他传播机制(如 http 长轮询)等优点。

官方文档:(服务器初始化 | Socket.IO)

npm install socket.io 安装。

聊天室案例

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>* {padding: 0;margin: 0;}html,body,.room {height: 100%;width: 100%;}.room {display: flex;}.left {width: 300px;border-right: 0.5px solid #2b2d30;background: #333;}.right {background: #1c1c1c;flex: 1;display: flex;flex-direction: column;}.header {background: rgb(60, 63, 65);color: white;padding: 10px;box-sizing: border-box;font-size: 20px;}.main {flex: 1;padding: 10px;box-sizing: border-box;font-size: 20px;overflow: auto;}.main-chat {color: #bcbec4;}.footer {min-height: 200px;border-top: 1px solid #4e5157;}.footer .ipt {width: 100%;height: 100%;color: #bcbec4;outline: none;font-size: 20px;padding: 10px;box-sizing: border-box;}.groupList {height: 100%;overflow: auto;}.groupList-items {height: 50px;width: 100%;background: rgb(67, 69, 74);border-bottom: 1px solid #2b2d30;display: flex;align-items: center;justify-content: center;color: white;}</style>
</head>
<div class="room"><div class="left"><div class="groupList"></div></div><div class="right"><header class="header">聊天室</header><main class="main"></main><footer class="footer"><div class="ipt" contenteditable></div></footer></div>
</div><body>
<script type="module">import {io} from "https://cdn.socket.io/4.7.4/socket.io.esm.min.js";let name = prompt('请输入你的名字')let room = prompt('请输入你要进入的房间')const sendMessage = (message) => {const div = document.createElement('div');div.className = 'main-chat';div.innerText = `${message.user}:${message.text}`;main.appendChild(div)}const group = document.querySelector('.groupList');  // 左侧列表的父级const main = document.querySelector('.main');  // 消息内容的父级const ipt = document.querySelector('.footer .ipt')// 希望自己也能收到信息const addChart = (msg)=> {let item = document.createElement('div')item.className = 'main-chat'item.innerHTML = `${msg.name}: ${msg.message}`main.appendChild(item)}const socket = io('ws://localhost:3000')  // ws 的地址socket.on('connect', () => {// 监听回车事件document.addEventListener('keydown',e=> {if (e.key === 'Enter') {const message = ipt.innerTextsocket.emit('message', {name, message, room})addChart({name, message})ipt.innerText = ''}})// 加入房间socket.emit('join', {name, room})//监听左侧列表socket.on('groupMap', (data) => {group.innerHTML = ``Object.keys(data).forEach(key=> {const item = document.createElement('div')item.className = 'groupList-items'item.innerHTML = `房间号:${key} 房间人数:${data[key].length}`group.appendChild(item)})})//监听发送的消息socket.on('message', (data) => {addChart(data)})})
</script>
</body></html>
import {createServer} from "http";
import {Server} from "socket.io";const server = createServer();
const io = new Server(server, {cors: true // 允许跨域
});
/*** [{name, room, id}, {name, room, id}]* @type {{}}*/
const groupMap = {}io.on("connection", (socket) => {// 前端传过来 name 和 roomsocket.on('join', ({name, room}) => {socket.join(room) // 创建一个房间if (groupMap[room]) {groupMap[room].push({name, room, id: socket.id}) // 已有就 push} else {groupMap[room] = [{name, room, id: socket.id}]  // 没有就创建}socket.emit('groupMap', groupMap)// 所有人都可以看到socket.broadcast.emit('groupMap', groupMap)// 管理员发送信息socket.broadcast.to(room).emit('message', {name: '管理员',message: `欢迎${name}进入聊天室`})})// 向前端发消息socket.on('message', ({name, message, room}) => {// 虽然给别人发送了消息,但是自己收不到socket.broadcast.to(room).emit('message', {name, message})})
});server.listen(3000);

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

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

相关文章

如何定位预防死锁

如何定位&预防死锁 什么是死锁&#xff1f; 简单来说就是并发环境下&#xff0c;两个或两个以上的线程互相等待资源&#xff0c;导致“永久阻塞”的现象 代码示例&#xff1a; public class Main {private static Object resource1 new Object();private static Objec…

达梦数据库自动备份(全库)+还原(全库) 控制台

一 前提 1.安装达梦数据库DB8(请参照以前文章) 我的数据库安装目录是 /app/dmDB8 2.已创建实例 (请参照上一篇文章) 二 准备测试数据 三 自动备份步骤 1.开启归档模式 开启DM管理工具管理控制台 弹不出来工具的 输入命令 xhost 第一步 将服务器转换为配置状态 右键-&g…

Kibana的安装(Linux版)

Kibana是一个针对Elasticsearch的开源分析及可视化平台&#xff0c;用来搜索、查看交互存储在Elasticsearch索引中的数据。使用Kibana&#xff0c;可以通过各种图表进行高级数据分析及展示。 Kibana让海量数据更容易理解。它操作简单&#xff0c;基于浏览器的用户界面可以快速创…

汽车电子行业知识:智能汽车电子架构

文章目录 3.智能汽车电子架构3.1.汽车电子概念及发展3.2.汽车电子架构类型3.2.1.博世汽车电子架构3.2.2.联合电子未来汽车电子架构3.2.3.安波福汽车电子架构3.2.4.丰田汽车电子架构3.2.5.华为汽车电子架构 3.智能汽车电子架构 3.1.汽车电子概念及发展 汽车电子是车体汽车电子…

阿里云对象存储OSS入门

阅读目录 一、阿里云OSS的使用 1、OSS是什么&#xff1f;2、OSS的使用 二、阿里云OSS的使用三、图床的搭建四&#xff1a;图床绑定阿里云OSS 编写不易&#xff0c;如果我的文章对你有帮助的话&#xff0c;麻烦小伙伴还帮忙点个赞再走&#xff01; 如果有小伙伴觉得写的啰嗦&am…

基于SIR模型的疫情发展趋势预测算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于SIR模型的疫情发展趋势预测算法.对病例增长进行SIR模型拟合分析&#xff0c;并采用模型参数拟合结果对疫情防控力度进行比较。整体思路为采用SIR微分方程模型…

PC电脑技巧[笔记本通过网线访问设备CMW500]

笔记本局域网访问设备 现在我有一台CMW500,我要用笔记本去访问它,但是我发现没有路由器就是不能够访问,通过网线连接设备就是ping不通: 这里设置TCP/IPv4的IP地址如下,这时候就可以pin通了:

Aspose.PDF功能演示:在 JavaScript 中合并两个 PDF 文件

在 Web 应用程序的世界中&#xff0c;处理和操作文档是一项常见的要求。当谈到 PDF 文件时&#xff0c;开发人员经常发现自己需要将 PDF 合并为单个 PDF 文件。因此&#xff0c;在这篇博文中&#xff0c;我们将探索如何使用强大的 PDF 库在 JavaScript 中轻松合并两个 PDF 文件…

【学习】软件测试行业 ,有哪些以就业为主的学习侧重点

今天给所有入行软测的同学们&#xff0c;帮大家梳理下以就业为主的学习侧重点&#xff0c;简单来说就是【这些都是重点&#xff0c;圈起来&#xff0c;要考的】&#xff0c;有需要的小伙伴可以往下看。 建议一&#xff1a;一定要学习一门编程语言&#xff0c;再开始使用自动化测…

Qt Design Studio 软件怎么用(详细+通俗+有趣)

建议&#xff1a;本文长期更新&#xff0c;建议点赞/收藏&#xff01; 1. 啥是Qt Design Studio&#xff1f; Qt Design Studio 是一个用于设计和开发用户界面的工具&#xff0c;特别适合开发跨平台应用程序。它结合了UI设计和开发的工作流程&#xff0c;使得设计师和开发者可…

[WTL/Win32]_[初级]_[如何设置ListView的列宽不出现水平滚动条]

场景 开发WTL/Win32的程序时&#xff0c;经常会用到表格控件CListViewCtrl。这个控件需要设置列的宽度&#xff0c;当用完100%的宽度来平均分配给列宽时&#xff0c;一加载数据多&#xff0c;就会出现垂直滚动条后&#xff0c;水平滚动条也会同时出现的问题。怎么设置才能让水…

搭建 Apple Mac M1 stm32 开发环境

近期想学习 stm32 开发,看了些书和视频,买了开发板。开发板到了后就迫不及待的的进行尝试。由于我目前使用的电脑是 Apple M1 Pro,目前用的比较多的是 windows + keil。我先是在 mac 使用虚拟机,安装 win 环境来使用,但是我分别使用了 VMware 和 parallels desktop ,keil…

vue3:通过【自定义指令】实现自定义的不同样式的tooltip

一、效果展示 vue3自定义不同样式的tooltip 二、实现思路 1.ts文件 在ts文件中创建一个全局容器 import一个容器组件&#xff0c;用于存放自定义的各式组件 创建一个指令并获取到指令传递的数据&#xff0c;并为容器组件传值 2.容器组件 用于存放自定义Tooltip样式的组件…

VGG16神经网络搭建

一、定义提取特征网络结构 将要实现的神经网络参数存放在列表中&#xff0c;方便使用。 数字代表卷积核的个数&#xff0c;字符代表池化层的结构 cfgs {"vgg11": [64, M, 128, M, 256, 256, M, 512, 512, M, 512, 512, M],VGG13: [64, 64, M, 128, 128, M, 256, …

【JS】深度学习JavaScript

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【JS】深度学习JavaScript &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 一:JavaScript1.1 JavaScript是什么1.2 JS的引入方式1.3 JS变量1.4 数据类型1.5 …

电脑桌面记事本便签软件,电脑记事本app

在快节奏的生活和工作中&#xff0c;我们时常需要记录一些待办事项、重要信息或是灵光一现的创意。这时&#xff0c;一款好用的电脑桌面记事本便签软件显得尤为重要。今天&#xff0c;我要为大家推荐的这款电脑桌面记事本便签软件&#xff0c;就是集齐简单、实用、高效于一身的…

MySQL高阶语句(一)

一、常用查询 &#xff08;增、删、改、查&#xff09; 对 MySQL 数据库的查询&#xff0c;除了基本的查询外&#xff0c;有时候需要对查询的结果集进行处理。 例如只取 10 条数据、对查询结果进行排序或分组等等 1、按关键字排序 PS:类比于windows 任务管理器 使用 SELECT 语…

STM32之HAL开发——DMA转运串口数据

DMA功能框图&#xff08;F1系列&#xff09; 如果外设要想通过 DMA 来传输数据&#xff0c;必须先给 DMA 控制器发送 DMA 请求&#xff0c; DMA 收到请求信号之后&#xff0c;控制器会给外设一个应答信号&#xff0c;当外设应答后且 DMA 控制器收到应答信号之后&#xff0c;就会…

动听的洗牌游戏(Java篇ArrayList实操)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

鸿蒙OS开发实例:【demo选择列表限定数量】

效果图&#xff1a; 示例代码 // 使用 DevEco Studio 3.1.1 Release 及以上版本&#xff0c;API 版本为 api 9 及以上。 // 主要功能及注意事项&#xff1a; // 该组件展示了一个乘客选择列表。列表中的每个项目包含一个复选框和对应的乘客姓名&#xff0c; // 用户点击任意一…