带你掌握webSocket 和 socket.io的基本用法

news2024/12/29 13:42:58

两者的作用和区别

作用:使得前后端可以随时地相互沟通。什么是互相沟通呢?像网络请求这种就是客户端向服务端的单向的沟通,当然,网络请求也可以实现双向的沟通,比如ajax 轮询,就是浏览器开个定时器不断的发送请求来了解后端数据库中数据是否变化,但是这个性能和方式好像不太好。
区别:看来自socket.io官网的一句话。
在这里插入图片描述简单理解就是,socket.io主要是基于webSocket实现的,然后做了一些封装和优化吧,嗯。下面直接用两个聊天的案例来带你掌握webSocket socketIo

webSocket的使用(html+nodeJs)

就我当前学到的,做聊天的话,webSocket主要做群聊吧,只要连接了就能接到消息。这个依赖于一个第三方包,所以需要先安装,yarn add ws,我安装的版本是8.12.1

服务端代码。这里采用nodeJS来编写一个webSocket服务,代码如下:

const websocket=require("ws")

const server=new websocket.Server({port:6688},()=>{
    console.log('websocketServer is running in ws://localhost:6688');
})

server.on("connection",(Ws)=>{  //用户连接时调用
    console.log('hello new user')
    
Ws.on("message",(data)=>{
    //   console.log(data),可以看到传输过来的数据转buffer了
    let msg
      try {
        const info=JSON.parse(data.toString())
        const words=info.msg
        const name=info.name
        msg=words&&name ?`${name}${words}`:"消息解析失败,请联系管理员!"
      } catch (err) {
        msg=data.toString()
      }
      server.clients.forEach((user)=>{  
        if(user.readyState===websocket.OPEN){    // websocket.OPEN值为1,表示用户已连接且可以正常通信
            user.send(msg)        // 把消息发送给连接本ws服务的代码端
            // user.timeout(500).send(msg)        // 500ms后发送
        }
    })
    // console.log(server.clients);
    })
})

编写完后,比如该文件名为 webSocketServer.js,我们就是在终端使用指令node webSocketServer启动该服务即可,这样客户端那边就能连接该服务了。

前端代码。api不多,可参考代码注释

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
    <style>
    #allmsg{
        width: 300px;
        height: 250px;
        border: 1px solid black;
        overflow: auto;
    }
    #txtinput{
        width: 150px;
        height: 40px;
    }
    </style>
</head>
<body>
<h2>聊天社区</h2>
请输入当前登录用户的昵称:<input type="text" id="userName">
<p style="font-size:22px;">消息框</p>
<div id="allmsg"></div><br/><br/><br/>
<input type="text" name="" id="txtinput" placeholder="按回车发送消息">

<script>
const ws=new WebSocket("ws://localhost:6688")
const txtinput=document.getElementById("txtinput")
const allmsg=document.getElementById("allmsg")
const userName=document.getElementById("userName")
let user=null

userName.onblur=(e)=>{
    if(e.target.value)
    user={id:Math.random()+Date.now(),name:e.target.value}
    else user=null
}

txtinput.onkeyup=(e)=>{
    if(e.keyCode===13)      // 通知socket切换房间
    {
     if(!user) {alert("请输入当前登录用户的昵称!");return}
     if(!txtinput.value) return
      ws.send(JSON.stringify({...user,msg:txtinput.value}))  // 向服务器发送消息 。ws.close() - 关闭连接
      txtinput.value=""
    }
}

ws.onopen=()=>{       //自己连接服务器成功时回调
    ws.send("新用户加入聊天室")
}

ws.onmessage=(msg)=>{  // 接到服务器的消息时回调
  allmsg.innerHTML+=`<p>${msg.data}</p>`
}
ws.onerror=(err)=>{     // 出错时回调
  console.log(err);
}
ws.onclose=()=>{       // 连接关闭时回调
    console.log('disconnection');
}
</script>
</body>
</html>

此时,我们就可以在该html页面open with live server3次或者更多来开多个页签,这样就可以开始测试聊天了。效果展示如下:

chat_webSocket

socket.io的使用(html+nodeJs)

由于socket.io丰富的api,可以用它来实现群聊或者私聊。这个依赖于两个第三方包,所以需要先安装
yarn add socket.io express,我安装的socket.io的版本是4.6.1

服务端代码。这里采用nodeJS来编写一个socketIO服务,代码如下,具体使用看注释

const server=require("http").createServer(require("express")())
const io=require("socket.io")(server,{cors:true})  //创建io并允许跨域

io.on("connection",(socket)=>{  //有用户连接时回调
io.emit("msg","有新用户加入群聊室")
// io.local.emit("hello", "world");  //只向连接到当前服务器的客户端发送

// 客户端 emit("msg")时回调
socket.on("msg",(data)=>{
      io.local.emit("msg",data)      // 把消息发送给所有订阅了msg的用户
      //socket.emit("msg",data)          // 把消息发送给订阅了msg的自己
      //socket.broadcast.emit("msg",data)   // 把消息发给除自己外的其他订阅了msg的所有用户
})

// 利用房间发送私人消息
socket.on("privateChart",(room,data)=>{
       //socket.to("房间号").emit("msg",data)    // 把消息发送给已拥有房间中的指定房间内订阅了msg的除自己外的所有用户
      //socket.to("房间号1").to("房间号2").emit("msg",data)        // 也可以给多个房间发送
      socket.emit("privateChart",data)  
      socket.to(room).emit("privateChart",data);
})

// 用来切换房间
socket.on("changeRoom",(room)=>{
      //console.log(room)
      if(room=="room1") {
            socket.join("room1")        // 添加指定房间
            socket.leave("room2")        // 删除指定房间
      }
      else{
            socket.join("room2")
            socket.leave("room1")
      }
      //console.log(socket.rooms)      // 拥有的房间列表
})

socket.on("disconnect", (reason) => {
      // 此事件由 Socket 实例在断开连接时触发
});

})

server.listen(8866,()=>{
console.log('socketioServer is running in http://127.0.0.1:8866')
})

编写完后,比如该文件名为 socketIoServer.js,我们就是在终端使用指令node socketIoServer启动该服务即可,这样客户端那边就能连接该服务了。

前端代码如下,用到的api也不多,后端那边可能会多一点,具体使用看注释

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title></title>
		<style>
			#groupMsg,#privateMsg {
				width: 300px;
				height: 250px;
				border: 1px solid black;
				overflow: auto;
			}
			#groupInput,#privateInput {
				width: 150px;
				height: 40px;
			}
		</style>
	</head>
	<body>
		<h2>聊天社区</h2>
		<h3>群聊房间</h3>
		<div id="groupMsg"></div>
		<br />
		<input type="text" name="groupInput" id="groupInput" placeholder="按回车发送群消息" />
		<h3>私聊房间</h3>
		<div id="privateMsg"></div>
		<br />
		<span>请选择您的聊天房间(相同房间的人才可聊天):</span>
		<input type="radio" name="room" id="room1"  value="room1"  /> 房间1
		<input type="radio" name="room" id="room2"  value="room2" /> 房间2<br/><br/><br/>
		<input type="text" name="privateInput" id="privateInput" placeholder="按回车发送私人消息" />
		

		<script src="/socket.io.js">
			// 该文件在服务端安装的 socket.io 包 的 client-dist 目录下,复制过来引入
		</script>

		<script>
			//与服务器建立连接
			// const socket = io('http://localhost:8866/')
			const socket=io.connect("http://localhost:8866/")
			const groupInput = document.getElementById('groupInput')
			const groupMsg = document.getElementById('groupMsg')
			const privateInput = document.getElementById('privateInput')
			const privateMsg = document.getElementById('privateMsg')
			const room1 = document.getElementById('room1')
			const room2 = document.getElementById('room2')
			groupInput.onkeyup = (e) => {
				if (e.keyCode === 13) {
				   if(!groupInput.value) return
					 socket.emit('msg', groupInput.value)
					 groupInput.value = ''
				}
			}
			
			privateInput.onkeyup = (e) => {
				if (e.keyCode === 13) {   // 按回车发送消息
				 if(!room1.checked && !room2.checked) {alert("请选择私聊的房间");return}
				 if(!privateInput.value) return
					// 发送私人消息,第二个参数与后端约定传递房间号,之后的参数就都是数据了
					socket.emit('privateChart', room1.checked?"room1":"room2", privateInput.value)
					//groupMsg.innerHTML+=`<p>${ groupInput.value}</p>`
					privateInput.value = ''
				}
			}
      
			room1.onchange=(e)=>{    // 通知socket切换房间
				socket.emit("changeRoom","room1")
			}
			room2.onchange=(e)=>{  // 通知socket切换房间
				socket.emit("changeRoom","room2")
			}

			socket.on('msg', (data) => {
				// 订阅服务器发送到'msg'处的消息
				groupMsg.innerHTML += `<p>${data}</p>`
			})
     
			
			socket.on('privateChart', (data) => {
				privateMsg.innerHTML += `<p>${data}</p>`
			})

			socket.on('connect', () => {  // 连接成功后回调
			})

			socket.on('disconnect', (reason) => {   // 连接断开时回调
			})
      
		</script>
	</body>
</html>

此时,我们就可以在该html页面open with live server3次或者更多来开多个页签,这样就可以开始测试聊天了。然后要注意的是私人房间那里不要都选同一个房间。效果展示如下:

chat_socketIo

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

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

相关文章

Python虚拟环境(pipenv、venv、conda一网打尽)[通俗易懂]

一、什么是虚拟环境 1. 什么是Python环境 要搞清楚什么是虚拟环境&#xff0c;首先要清楚Python的环境指的是什么。当我们在执行python test.py时&#xff0c;思考如下问题&#xff1a; python哪里来&#xff1f;这个主要归功于配置的系统环境变量PATH&#xff0c;当我们在命…

山地车和公路车怎么选

公路车&#xff1a; 只能适应平坦的路面&#xff0c;骑行阻力小&#xff0c;速度快比较适合新手 山地车&#xff1a; 能适应所有路面&#xff0c;更注重操控性和舒适性 怎么选&#xff1f; 1、先决定用途 旅游&#xff1a;旅行车、山地车、 通勤&#xff1a;公路车 2、预…

如何使用BeaconEye监控CobaltStrike的Beacon

关于BeaconEye BeaconEye是一款针对CobaltStrike的安全工具&#xff0c;该工具可以扫描正在运行的主动CobaltStrike Beacon。当BeaconEye扫描到了正在运行Beacon的进程之后&#xff0c;BeaconEye将会监控每一个进程以查看C2活动。 工作机制 BeaconEye将会扫描活动进程或Mini…

G公司对接伍尔特wurth EDI项目案例

项目背景 对伍尔特wurth 而言&#xff0c;与其供应商开展成功的数字化项目通常是以自动连接开始的。通过这种方式&#xff0c;标准化的信息可以在彼此之间进行简单而自动的交换。这个流程被称为电子数据交换&#xff08;EDI&#xff09;。 EDI使得诸如订单、送货单、发票、订单…

Jmeter常用断言之JSON断言简介

JSON断言可以对服务器返回的JSON文档进行验证。 JSON断言有两种使用模式&#xff1a; 1.根据JSONPath能否在JSON文档中找到路径&#xff1b; 2.根据JSONPath提取值并对值进行验证。 结果判定&#xff1a;若文档格式为非JSON则断言失败&#xff1b;找不到路径断言失败&#xff1…

深度学习 | BN层原理浅谈

深度学习 | BN层原理浅谈 文章目录深度学习 | BN层原理浅谈一. 背景二. BN层作用三. 计算原理四. 注意事项为什么BN层一般用在线性层和卷积层的后面&#xff0c;而不是放在激活函数后为什么BN能抑制过拟合(有争议)一. 背景 神经网络在训练时&#xff0c;由于内存限制&#xff0…

Swagger2实现配置Header请求头

效果 实现 大家使用swagger肯定知道在代码中会写一个 SwaggerConfig 配置类&#xff0c;如果没有这个类swagger指定也用不起来&#xff0c;所以在swagger中配置请求头也是在这个 SwaggerConfig 中操作。 1、要实现配置请求头在配置swagger的Docket的bean实例中添加一个 globa…

用Python做了一个法律查询小工具,非常好用

用Python做了一个法律查询小工具&#xff0c;非常好用效果展示准备工作不会的话可以点我直达代码和视频讲解&#xff0c;我都准备好了主要代码哈喽兄弟&#xff0c;今天给大家分享一个Python tkinter制作法律查询小工具。 光爬虫大家也只能自己用用&#xff0c;就算打包了exe&…

安全狗受聘成为福州网信办网络安全技术支撑单位

近日&#xff0c;福州市委网信办召开了2022年度网络安全技术支撑单位总结表彰大会。 作为国内云原生安全领导厂商&#xff0c;安全狗也出席了此次活动。 据悉&#xff0c;会议主要对2022年度优秀支撑单位进行表彰&#xff0c;并为2023年度支撑单位举行授牌仪式。 本次遴选工…

2.1 黑群晖驱动:10代u核显硬解驱动(解决掉IP、重启无法连接问题)

本文提供了两种10代核显驱动方式&#xff1a;1&#xff09;第一种(本文&#xff1a;二、仅修改i915.ko驱动10代u核显方法)为网上流传最多但是对主板兼容性要求很高&#xff0c;网上评论常会出现操作后无法识别IP&#xff08;掉IP&#xff09;的问题。因此&#xff0c;采用第一种…

vue-cli升级vue-cli5(webpack5引入)

一. 升级目标 vue-cli从v4版本升级到v5版本&#xff08;同时升级到webpack5&#xff09; node-sass不再支持&#xff0c;需要删除依赖&#xff0c;并将/deep/ 替换为v::deep方式 二. vue-cli4升级为vue-cli5 1.全局安装vue-cli npm install -g vue/cli// 检查是否更新成功 …

教你安装 Altium Designer23详细图文教程

Altium Designer (AD) 最新安装教程 ,ltium designer 显著地提高了用户体验和效率,利用时尚界面使设计流程流线化,同时实现了前所未有的性能优化。使用64位体系结构和多线程的结合实现了在PCB设计中更大的稳定性、更快的速度和更强的功能。Altium Designer 使您能够创建互联…

【项目精选】进销存管理系统的设计与实现(视频+源码+论文)

点击下载源码 1.1研究背景和意义 目前&#xff0c;许多的中小企业普遍存在一个问题&#xff1a;企业的决策者看到的进销存资料及相关报表都是比较繁杂&#xff0c;让本应该一目了然的结果因信息的分散使得产生的结果无法保持一致和完整&#xff0c;造成企业在进销存管理上问题很…

【C++】哈希

哈希一、unordered系列关联式容器二、哈希原理2.1 哈希映射2.2 哈希冲突2.2.1 闭散列—开放地址法2.2.2 代码实现2.2.3 开散列—拉链法2.2.4 代码实现三、哈希封装unordered_map/unordered_set3.1 基本框架3.2 迭代器实现3.2.3 operator*和operator->和operator!3.2.4 opera…

【微服务】Ribbon实现负载均衡

目录 1.什么是负载均衡 2.自定义负载均衡 3.基于Ribbon实现负载均衡 Ribbon⽀持的负载均衡策略 4.负载均衡原理 源码跟踪 LoadBalancerIntercepor LoadBalancerClient 5.负载均衡策略IRule 总结 1.什么是负载均衡 通俗的讲&#xff0c; 负载均衡就是将负载&#xff…

环境搭建04-Ubuntu16.04更改conda,pip的镜像源

我常用的pipy国内镜像源&#xff1a; https://pypi.tuna.tsinghua.edu.cn/simple # 清华 http://mirrors.aliyun.com/pypi/simple/ # 阿里云 https://pypi.mirrors.ustc.edu.cn/simple/ #中国科技大学1、将conda的镜像源修改为国内的镜像源 先查看conda安装的信息…

【shell 编程大全】sed详解

sed详解1. 概述 今天单独拉出一章来讲述下sed命令。因为sed命令确实内容太多&#xff0c;不过也是比较灵活的&#xff0c;好了不废话了。我们开始吧 1.2 原理解析 shell脚本虽然功能很多&#xff0c;但是它最常用的功能还是处理文本文件&#xff0c;尤其是在正常的业务操作流程…

4.3 where关键字过滤查询数据

文章目录1.使用WHERE子句2.WHERE子句操作符2.1 使用单个值2.2 不匹配检查2.3 范围值查询2.4 空值检查3.组合WHERE子句3.1 AND操作符3.2 OR操作符3.3 计算次序4.IN操作符5.NOt关键字&#xff15;.注意事项&#xff15;.1 NULL与不匹配&#xff15;.2 SQL过滤与应用过滤&#xff…

【RSA】HTTPS中SSL/TLS握手时RSA前后端加密流程

SSL/TLS层的位置 SSL/TLS层在网络模型的位置&#xff0c;它属于应用层协议。接管应用层的数据加解密&#xff0c;并通过网络层发送给对方。 SSL/TLS协议分握手协议和记录协议&#xff0c;握手协议用来协商会话参数&#xff08;比如会话密钥、应用层协议等等&#xff09;&…

QT中级(6)基于QT的文件传输工具(2)

QT中级&#xff08;6&#xff09;基于QT的文件传输工具&#xff08;2&#xff09;本文实现第一步1 新增功能2 运行效果3 实现思路4 源代码实现这个文件传输工具大概需要那几步&#xff1f;实现多线程对文件的读写实现TCP客户端和服务端实现网络传输 书接上回&#xff1a;QT中级…