采用nodejs + socket.io实现简易聊天室功能(群聊 + 私聊)

项目演示

支持群聊以及私聊
在这里插入图片描述

项目代码

index.html

<!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>Document</title>
    <script src="/socket.io/socket.io.js"></script>
    <style>
        .box {
            display: flex;
            justify-content: space-between;
            width: 800px;
            margin: 50px auto;
            text-align: center;
        }

        .box>div {
            flex: 1;
        }

        .box .center {
            flex: 2;
        }

        .box .center input {
            width: 70%;
        }

        .list {
            list-style: none;
            text-align: left;
        }
    </style>
</head>

<body>
    <div class="box">
        <div class="left">
            <div class="num">在线人数:1</div>
        </div>

        <div class="center">
            <h1 style="margin-bottom: 20px;">简易聊天室</h1>

            <!-- 输入框 -->
            <input type="text" class="ipt">

            <!-- 发送 -->
            <button class="btn">发送消息</button>

            <!-- 输入框 -->
            <input type="text" class="joinNum">

            <!-- 加入房间 -->
            <button class="joinBtn">加入房间</button>

            <ul class="list" style="margin-top: 40px;">
                <!-- <li class="list-group-item">An item</li> -->
            </ul>
        </div>

        <div class="right">
            <!-- <div>xxx已进入</div> -->
        </div>
    </div>

    <script>
        let num = document.querySelector('.num')
        let ipt = document.querySelector('.ipt')
        let btn = document.querySelector('.btn')

        let joinNum = document.querySelector('.joinNum')
        let joinBtn = document.querySelector('.joinBtn')

        let list = document.querySelector('.list')

        let left = document.querySelector('.left')
        let center = document.querySelector('.center')
        let right = document.querySelector('.right')

        let socket = io()

        const name = prompt('请输入你的名称:')
        
        //把用户名称传递给服务端
        socket.emit('join', name)

        // 监听用户已进入 | 已退出
        socket.on('join', (obj) => {
            right.innerHTML += `<div>${obj.name} ${obj.status}</div>`
        })

        // 监听用户在线人数
        socket.on('userNum', (n) => {
            num.innerHTML = `在线人数:${n} 个人`
        })

        // 点击发送按钮 发送消息
        btn.addEventListener('click', function () {
            // 将数据传递给服务端
            socket.emit('value', ipt.value)
        })

        // 键盘按下回车 发送消息
        ipt.addEventListener('keydown', function (e) {
            if (e.key !== 'Enter') return

            // 将数据传递给服务端
            socket.emit('value', ipt.value)
        })

        // 加入房间
        joinBtn.addEventListener('click', function () {
            socket.emit("joinRoom", { room: joinNum.value, value: ipt.value })
        })

        // 服务端再把数据响应回来
        socket.on('value', (value) => {
            list.innerHTML += `<li>${value}</li>`
            ipt.value = ''
        })
    </script>
</body>

</html>

index.js

const app = require("express")();
const http = require("http").Server(app);
const io = require("socket.io")(http);

app.get("/", (req, res) => {
  res.sendFile(__dirname + "/index.html");
});

let userNum = 0; //当前在线人数

io.on("connection", (socket) => {
  // 访问聊天室用户在线输了加1
  ++userNum;
  // 将用户在线数量实时同步给客户端
  io.emit("userNum", userNum);

  // 相应客户端传递的数据
  socket.on("value", (value) => {
    io.emit("value", `${socket.username}${value}`);
  });

  // 监听用户进入聊天室
  socket.on("join", (name) => {
    socket.username = name;

    io.emit("join", {
      name: name,
      status: "已进入",
    });
  });

  // 离开聊天室用户在线数量减1
  socket.on("disconnect", () => {
    --userNum;
    io.emit("userNum", userNum);

    io.emit("join", {
      name: socket.username,
      status: "已退出",
    });
  });

  // 加入房间
  socket.on("joinRoom", ({ room, value }) => {
    // 加入指定的房间
    socket.join(room);

    // 在指定房间中发送消息
    io.to(room).emit("value", `${socket.username}${value}`);
  });
});

http.listen(1231, () => {
  console.log("服务器已启动:http://localhost:1231");
});

package.json

{
  "name": "WebSocket",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "license": "MIT",
  "dependencies": {
    "express": "^4.18.2",
    "socket.io": "^4.5.4"
  }
}

通过 npm run start 运行项目

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

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

相关文章

Android12-RK3588_s-开机动画

目录 一、实现自定义开机动画 步骤一&#xff1a;准备 bootanimation.zip 步骤二&#xff1a;将 bootanimation.zip 放到 /system/media/bootanimation.zip下 步骤三&#xff1a;重启即可 二、注意事项 2.1 bootanimation.zip 压缩 2.2 bootanimation.zip 存放 2.3 boo…

RabbitMQ插件详解:rabbitmq_web_stomp【RabbitMQ 六】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 《RabbitMQ Web STOMP&#xff1a;打破界限的消息传递之舞》 前言STOMP协议简介STOMP&#xff08;Simple Text Oriented Messaging Protocol&#xff09;协议简介STOMP与WebSocket的关系 WebSocket和R…

Certbot实现 HTTPS 免费证书(Let‘s Encrypt)自动续期

Certbot实现 HTTPS 自动续期 以前阿里云支持申请一年的免费https证书&#xff0c;那每年我们手动更新证书并没什么大问题&#xff0c;但现在阿里云的免费证书仅支持3个月&#xff0c;这意味着每三个月都要要申请一下证书显得非常麻烦。 下面我们使用Certbot实现ssl证书的自动…

[Linux] LVS负载均衡群集+NAT部署

一、LVS负载均衡群集知识 1.1 群集的的定义及意义 Cluster&#xff0c;集群&#xff08;也称群集&#xff09;由多台主机构成&#xff0c;但对外只表现为一一个整体&#xff0c;只提供一-个访问入口(域名或IP地址)&#xff0c; 相当于一台大型计算机。 群集的作用&#xff1…

常用函数之js复制图片至剪切板

背景 最近在工作中遇到了一个需求&#xff0c;点击按钮将Echart图复制到剪切板&#xff0c;然后按Ctrl&#xff08;command&#xff09;V可以直接复制到聊天软件&文档编辑器中。本以为这是一个比较简单的需求&#xff0c;好像找了一圈资料&#xff0c;发现事情并不简单&am…

java线程的几种状态

一、线程的状态 Java中的线程有以下几种状态&#xff1a; 1. 新建状态&#xff08;New&#xff09;&#xff1a;当线程对象被创建但还没有被调用start()方法时&#xff0c;线程处于新建状态。 2. 运行状态&#xff08;Runnable&#xff09;&#xff1a;当线程启动后&#xff0c…

西瓜视频RenderThread引起的闪退问题攻坚历程

背景 影响 西瓜之前存在过一类RenderThread闪退&#xff0c;从堆栈上看&#xff0c;全部都是系统so调用&#xff0c;给人的第一印象像是一个系统bug&#xff0c;无从下手。闪退集中在Android 5~6上&#xff0c;表现为打开直播间立即闪退。该问题在2022年占据Native Crash Top5&…

C++异步网络库workflow系列教程(3)Series串联任务流

往期教程 如果觉得写的可以,请给一个点赞关注支持一下 观看之前请先看,往期的两篇博客教程,否则这篇博客没办法看懂 workFlow c异步网络库编译教程与简介 C异步网络库workflow入门教程(1)HTTP任务 C异步网络库workflow系列教程(2)redis任务 简介 首先,workflow是任务流的意…

『番外篇二』Swift “黑魔法”之动态获取类实例隐藏属性的值

概览 在 Swift 代码的调试中,我们时常惊叹调试器的无所不能:对于大部分“黑盒”类实例的内容,调试器也都能探查的一清二楚。 想要自己在运行时也能轻松找到 Thread 实例“私有”属性的值吗(比如 seqNum)? 在本篇博文中您将学到如下内容: 概览1. 借我,借我,一双慧眼吧…

Dockerfile创建镜像LNMP+WordPress

目录 实验部署 nginx 配置mysql 配置php 实验部署 INMPwordpress nginx 172.111.0.10 docker-nginx mysql 172.111.0.20 docker-mysql php 172.111.0.30 docker-php nginx 关闭防火墙和安全机制在opt目录创建nginx MySQL php目录 cd nginx mysql php vim Dockerfile#声…

rabbitmq-windows安装使用-简易后台界面-修改密码

文章目录 1.下载2.安装3.安装 RabbitMQ4.后台访问5.修改密码 1.下载 将erlang运行时和rabbitmq-windows版本&#xff0c;上传在csdn&#xff0c;下载链接。https://download.csdn.net/download/m0_67316550/88633443 2.安装 右键&#xff0c;以管理员身份运行rabbitmq。启动…

mysql:修改整数字段的显式长度不生效

例如&#xff0c;我使用mysql 8.2.0版本&#xff0c;想修改整数字段的显式长度&#xff0c;不会生效&#xff0c;提醒整数的显示长度已经废弃&#xff0c;会在将来某个版本去掉&#xff1a; mysql官网中也有说明&#xff1a; https://dev.mysql.com/doc/refman/8.2/en/numeric…

【JetBrains】将Gateway中的GoLand回滚到无bug旧版本

问题背景 2023-12-15 我把 Gateway 中使用的 GoLand 从 2023.2.x 升级到了 2023.3 &#xff0c;然后编辑文件过程中输入时时不时会显示错误信息&#xff0c;然后就会进入无法输入&#xff08;键入也不会看到增加字符&#xff09;但能粘贴的奇怪状态。 问题解决 升级到 2023.…

canvas基本绘制对象

目录 绘制画布 设置画布 绘制圆形 绘制矩形填充渐变色 绘制文字及文字样式 绘制画布 <canvas id"canvas" width"800" height"600"></canvas> 设置画布 //获得画布元素var canvasdocument.getElementById(canvas);var ctxca…

Android BluetoothAdapter 使用(二)

Android BluetoothAdapter 使用(二) 本篇文章主要讲下蓝牙设备的配对. 1: 蓝牙设备列表展示 下 面是蓝牙设备adapter的代码: package com.test.bluetooth;import android.bluetooth.BluetoothDevice; import android.content.Context; import android.view.LayoutInflater;…

人工智能多模态:看、听、说,智能感知的全方位融合

导言 人工智能多模态技术是指通过整合视觉、听觉、语言等多个感知模态的信息&#xff0c;实现对丰富、多样化数据的理解与处理。本文将深入研究人工智能多模态的技术原理、应用场景以及对未来感知智能的影响。 1. 简介 人工智能多模态技术通过整合多个感知模态的信息&#xff…

医学检验系统LIS源码,C# +.Net+Oracle

LIS是HIS的一个组成部分&#xff0c;通过与HIS的无缝连接可以共享HIS中的信息资源&#xff0c;使检验科能与门诊部、住院部、财务科和临床科室等全院各部门之间协同工作。  体系结构&#xff1a;Client/Server架构 客户端&#xff1a;WPFWindows Forms 服务端&#xff1a;C…

stm32项目(12)——基于stm32f407zgt6的频率计设计

1.项目功能 配置stm32自带的定时器&#xff0c;以一定的周期产生中断&#xff0c;在中断服务函数里面&#xff0c;对某个IO口进行取反&#xff0c;这样就在该管脚上产生了一定频率的方波&#xff08;频率可以用按键调节&#xff09;。然后再使用stm32的捕获功能&#xff0c;对产…

解决nuxt3环境中css样式失效的问题

现象: 底部播放器进度条拖动按钮没有了&#xff01; 然后通过chrome开发工具检查html元素的结构&#xff1a; 发现progressbar这个元素是存在的&#xff0c;但是为什么没有显示呢&#xff0c;然后回到代码中&#xff1a; 发现原来是组件的名字写错了&#xff0c;多写了一个字母…

安恒明御安全网关 aaa_local_web_preview文件上传漏洞复现

0x01 产品简介 明御安全网关秉持安全可视、简单有效的理念,以资产为视角,构建全流程防御的下一代安全防护体系,并融合传统防火墙、入侵检测、入侵防御系统、防病毒网关、上网行为管控、VPN网关、威胁情报等安全模块于一体的智慧化安全网关。 0x02 漏洞概述 明御安全网关在…