认识并理解webSocket

今天逛牛客,看到有大佬分享说前端面试的时候遇到了关于webSocket的问题,一看自己都没见过这个知识点,赶紧学习一下,在此记录!

WebSocket 是一种网络通信协议,提供了全双工通信渠道,即客户端和服务器可以同时发送和接收数据。这与传统的HTTP请求不同,后者是单向的,客户端发起请求,服务器响应请求。WebSocket 允许服务器主动向客户端发送消息,这使得实时通信成为可能,例如在线聊天应用、实时游戏、股票行情更新等场景。

WebSocket 的基本概念

  1. 连接建立:客户端通过发送一个HTTP请求来发起WebSocket连接,这个请求中包含特定的头部,表明这是一个WebSocket握手请求。
  2. 握手:服务器接收到请求后,如果支持WebSocket,则响应一个HTTP响应,完成握手过程,建立WebSocket连接。
  3. 数据传输:一旦连接建立,客户端和服务器就可以通过这个连接发送数据。数据可以是文本或二进制格式。
  4. 连接关闭:任何一方都可以关闭WebSocket连接。

WebSocket 的使用步骤

  1. 创建WebSocket实例:在客户端,首先需要创建一个WebSocket实例,指定服务器的URL。

    const ws = new WebSocket('ws://example.com/socket');
    
  2. 处理连接事件:当WebSocket连接建立时,会触发open事件。

    ws.onopen = function(event) {
      console.log('WebSocket connection opened:', event);
    };
    
  3. 发送数据:使用send方法向服务器发送数据。

    ws.send('Hello Server!');
    
  4. 接收数据:服务器发送的数据可以通过message事件接收。

    ws.onmessage = function(event) {
      console.log('Message from server:', event.data);
    };
    
  5. 处理错误和关闭连接:WebSocket连接可能会遇到错误,或者需要主动关闭。

    ws.onerror = function(error) {
      console.error('WebSocket Error:', error);
    };
    
    ws.onclose = function(event) {
      console.log('WebSocket connection closed:', event);
    };
    
    // 可以主动关闭连接
    ws.close();
    

使用nodejs实现一个简单的在线聊天demo。

客户端代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
 <!-- 简单的HTML界面 -->
<textarea id="messageInput" placeholder="Type a message..."></textarea>
<button id="sendButton">Send</button>
<div id="messages"></div>

<script>
  // 绑定按钮点击事件
  document.getElementById('sendButton').addEventListener('click', sendMessage);

  // 创建WebSocket连接
  const ws = new WebSocket('ws://localhost:8080');
  const messageInput = document.getElementById('messageInput');
  const messagesDiv = document.getElementById('messages');
  const sendButton = document.getElementById('sendButton');

  // 连接打开时触发
  ws.onopen = function(event) {
    console.log('Connected to the server');

    // 可以在这里禁用或启用按钮等
    sendButton.disabled = false;
  };

  // 接收到消息时触发
  ws.onmessage = function(event) {
    // 将接收到的消息添加到消息显示区域
    const messageElement = document.createElement('div');
    messageElement.textContent = event.data;
    messagesDiv.appendChild(messageElement);
    // 滚动到消息区域底部
    messagesDiv.scrollTop = messagesDiv.scrollHeight;
  };

  // 发送消息的函数
  function sendMessage() {
    if (ws.readyState === WebSocket.OPEN) {
      const message = messageInput.value;
      if (message) { // 确保消息不为空
        ws.send(message);
        
        messageInput.value = ''; // 清空输入框
      }
    } else {
      console.error('WebSocket is not connected. Cannot send message.');
    }
  }

  // 客户端连接错误时触发
  ws.onerror = function(error) {
    console.error('WebSocket error observed:', error);
    // 可以在这里显示错误信息或禁用发送按钮
    sendButton.disabled = true;
  };

  // 客户端关闭连接时触发
  ws.onclose = function(event) {
    console.log('WebSocket connection closed:', event);
    // 可以在这里禁用发送按钮或显示断开连接的信息
    sendButton.disabled = true;
  };
</script>
</body>
</html>
服务端代码

(注意要先使用npm install ws命令安装需要的库)

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

// 存储所有客户端的集合
const clients = new Set();

wss.on('connection', function connection(ws) {
  console.log('Client connected');

  // 将新的客户端WebSocket对象添加到集合中
  clients.add(ws);

  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
  });

  ws.on('close', function() {
    console.log('Client disconnected');
    // 从集合中移除客户端
    clients.delete(ws);
  });

  // 可以在这里发送欢迎消息给新连接的客户端
  ws.send('Welcome to the chat!');
});

// 假设我们有一个函数,用来向所有客户端广播消息
function broadcastMessage(message) {
  clients.forEach(client => {
    if (client.readyState === WebSocket.OPEN) {
      client.send(message);
    }
  });
}

// 示例:每隔5秒向所有客户端发送当前时间
setInterval(() => {
  const currentTime = new Date().toLocaleTimeString();
  broadcastMessage(`Current time: ${currentTime}`);
}, 5000);
实现效果

客户端向服务端发送消息:

在这里插入图片描述
在这里插入图片描述
服务端向客户端发送消息:
每隔五秒发送当前的时间
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity3D游戏 RPG

丛林探险游戏 人物进行探险游戏 拥有登录&#xff0c;首页&#xff0c;3D物体旋转浏览的功能&#xff0c;还能进行种植树等功能

GD32 MCU ADC采样率如何计算?

大家在使用ADC采样的时候是否计算过ADC的采样率&#xff0c;这个问题非常关键&#xff01; 以下为GD32F303系列MCU中有关ADC的参数&#xff0c;其中ADC时钟最大值为40MHz&#xff0c;12位分辨率下最大采样率为2.86MSPS.如果ADC时钟超频的话&#xff0c;可能会造成ADC采样异常&…

【总线】AXI4第七课时:AXI的额外的控制信息(PROT和CACHE)

大家好,欢迎来到今天的总线学习时间!如果你对电子设计、特别是FPGA和SoC设计感兴趣&#xff0c;那你绝对不能错过我们今天的主角——AXI4总线。作为ARM公司AMBA总线家族中的佼佼者&#xff0c;AXI4以其高性能和高度可扩展性&#xff0c;成为了现代电子系统中不可或缺的通信桥梁…

Vue3.js“非原始值”响应式实现基本原理笔记(二)

如果您觉得这篇文章有帮助的话&#xff01;给个点赞和评论支持下吧&#xff0c;感谢~ 作者&#xff1a;前端小王hs 阿里云社区博客专家/清华大学出版社签约作者/csdn百万访问前端博主/B站千粉前端up主 此篇文章是博主于2022年学习《Vue.js设计与实现》时的笔记整理而来 书籍&a…

STM32F103C8T6核心板原理图和PCB分享

PCB图 原理图 资料下载地址&#xff1a; 原理图PCB库: https://545c.com/d/45573183-61875742-29897c?p7526 (访问密码: 7526)

第3章.中央服务器的物联网模式--企业系统集成

为了从物联网实施中获得最大价值&#xff0c;物联网系统需要与企业中的现有软件系统集成。事实上&#xff0c;与外部系统的集成允许网络世界和物理世界之间的交互——代表物理世界的物联网系统和驻留在网络/虚拟世界中的外部系统。用于此模式的符号如下图所示&#xff1a; 图3.…

mac怎么压缩pdf文件大小,mac压缩pdf文件大小不改变清晰度

在数字化时代&#xff0c;pdf格式因其良好的兼容性和稳定性&#xff0c;成为了文档分享和传输的首选。然而&#xff0c;随着文件内容的丰富&#xff0c;pdf文件的体积也越来越大&#xff0c;给存储和传输带来了不小的困扰。本文将揭秘几种简单有效的pdf文件压缩方法&#xff0c…

图神经网络实战(16)——经典图生成算法

图神经网络实战&#xff08;16&#xff09;——经典图生成算法 0. 前言1. 图生成技术2. Erdős–Rnyi模型3. 小世界模型小结系列链接 0. 前言 图生成算法是指用于创建模拟图或网络结构的算法&#xff0c;这些算法可以根据特定的规则和概率分布生成具有特定属性的图&#xff0c…

SCI一区级 | Matlab实现BO-Transformer-BiLSTM时间序列预测

SCI一区级 | Matlab实现BO-Transformer-BiLSTM时间序列预测 目录 SCI一区级 | Matlab实现BO-Transformer-BiLSTM时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.【SCI一区级】Matlab实现BO-Transformer-BiLSTM时间序列预测&#xff0c;贝叶斯优化Transfor…

C++_STL---list

list的相关介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 list的底层是带头双向循环链表结构&#xff0c;链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后一个元素。…

WAIC | 上海人形机器人创新中心 | 最新演讲 | 详细整理

前言 笔者看了7月4号的人形机器人与具身智能发展论坛的直播&#xff0c;并在7月5日到了上海WAIC展会现场参观。这次大会的举办很有意义&#xff0c;听并看了各家的最新成果&#xff0c;拍了很多照片视频&#xff0c;部分演讲也录屏了在重复观看学习 稍后会相继整理创立穹彻智…

[c++] 可变参数模版

前言 可变参数模板是C11及之后才开始使用,学校的老古董编译器不一定能用 相信大家在刚入门c/c时都接触过printf函数 int printf ( const char * format, ... ); printf用于将数据格式化输出到屏幕上,它的参数非常有意思,可以支持任意数量,任意类型的多参数.而如果我们想实现类…

【Java探索之旅】继承概念_语法_父类的成员访问

文章目录 &#x1f4d1;前言一、继承1.1 继承的概念1.2 继承语法1.3 继承发生后 二、父类的访问2.1 父类成员变量访问2.2 父类成员方法访问 &#x1f324;️全篇总结 &#x1f4d1;前言 在面向对象编程中&#xff0c;继承是一种重要的概念&#xff0c;它允许我们创建一个类&…

[go-zero] 简单微服务调用

文章目录 1.注意事项2.服务划分及创建2.1 用户微服务2.2 订单微服务 3.启动服务3.1 etcd 服务启动3.2 微服务启动3.3 测试访问 1.注意事项 go-zero微服务的注册中心默认使用的是Etcd。 本小节将以一个订单服务调用用户服务来简单演示一下&#xff0c;其实订单服务是api服务&a…

VSCode设置好看清晰的字体!中文用鸿蒙,英文用Jetbrains Mono

一、中文字体——HarmonyOS Sans SC 1、下载字体 官网地址&#xff1a;https://developer.huawei.com/consumer/cn/design/resource/ 直接下载&#xff1a;https://communityfile-drcn.op.dbankcloud.cn/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20230517…

昇思25天学习打卡营第18天 | K近邻算法实现红酒聚类

1、实验目的 了解KNN的基本概念&#xff1b;了解如何使用MindSpore进行KNN实验。 2、K近邻算法原理介绍 K近邻算法&#xff08;K-Nearest-Neighbor, KNN&#xff09;是一种用于分类和回归的非参数统计方法&#xff0c;最初由 Cover和Hart于1968年提出(Cover等人,1967)&#…

Golang | Leetcode Golang题解之第220题存在重复元素III

题目&#xff1a; 题解&#xff1a; func getID(x, w int) int {if x > 0 {return x / w}return (x1)/w - 1 }func containsNearbyAlmostDuplicate(nums []int, k, t int) bool {mp : map[int]int{}for i, x : range nums {id : getID(x, t1)if _, has : mp[id]; has {retu…

ctfshow web sql注入 web242--web249

web242 into outfile 的使用 SELECT ... INTO OUTFILE file_name[CHARACTER SET charset_name][export_options]export_options:[{FIELDS | COLUMNS}[TERMINATED BY string]//分隔符[[OPTIONALLY] ENCLOSED BY char][ESCAPED BY char]][LINES[STARTING BY string][TERMINATED…

【三级等保】等保整体建设方案(Word原件)

建设要点目录&#xff1a; 1、系统定级与安全域 2、实施方案设计 3、安全防护体系建设规划 软件全文档&#xff0c;全方案获取方式&#xff1a;本文末个人名片直接获取。

数据结构——二叉树相关题目

1.寻找二叉树中数值为x的节点 //寻找二叉树中数值为x的节点 BTNode* TreeFind(BTNode* root, BTDataType x)//传过来二叉树的地址和根的地址&#xff0c;以及需要查找的数据 {if (root Null){return Null;}//首先需要先判断这个树是否为空&#xff0c;如果为空直接返回空if (…