Nodejs+Socket.io+Web端完成聊天

news2024/11/20 3:35:58

前言

源码获取:node+express+socket.io+web: 聊天demo (gitee.com)

目录结构

后端依赖

启动方式

前端是html正常启动

后端是node app.js

后端app.js核心代码

const express = require('express')
const app = express()
var http = require('http').Server(app)
var io = require('socket.io')(http, { cors: true })
var name = ""
var count = 0
app.all('*', function(req, res, next) {  
  res.header("Access-Control-Allow-Origin", "*");  
  res.header("Access-Control-Allow-Headers", "X-Requested-With");  
  res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");  
  res.header("X-Powered-By",' 3.2.1')  
  res.header("Content-Type", "application/json;charset=utf-8");  
  next();  
});   
app.get('/',(req,res)=>{
  // 保存用户的名称
  name = req.query.username
  // 返回状态码,通过状态码执行客户端页面跳转
  res.send({state:200})
  // res.sendFile(__dirname + '/index.html')
})
//入口函数,连接进程
io.on('connection', function (socket) {
  // 每建立连接一次,在线人数减一
  count++
  //这里是发送消息
  // on用来监听客户端message事件,回调函数处理。
  socket.on('message', function (msg) {
    // 如果在这里通过url解析的username来改变下面33行即将渲染的name,会出现异步问题。name还没有赋值就被传到客户端
    // 所以通过ajax请求,先让后端拿到username,然后再做提示信息的渲染
    console.log(msg.username+':'+ msg.inpval);
    // 将客户端发送来的消息中转给所有客户端
    io.emit('message', msg)
  });
  // loginin是自定义事件,第二个参数返回数据对象用于渲染,用于登陆后向客户端发送用户登录信息
  io.emit('loginin',{count,des:'温馨提示:'+name+'加入聊天室'})
  //登陆后向客户端发送用户退出信息
  socket.on('disconnect', function () {
    // loginout是自定义事件,第二个参数返回数据对象用于渲染
    count--
    io.emit('loginout',{count,des:'温馨提示:'+name+'用户退出聊天室'})
    // 连接每断开一次,在线人数减一
  })
});
http.listen(3000, function () {
  console.log('listening:3000')
})

html部分

<!doctype html>
<html>

<head>
  <title>Socket.IO chat</title>

  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .chat {
      width: 400px;
      margin: 0 auto;
      border: 1px solid #333;
    }

    .title {
      line-height: 30px;
      color: black;
      border-bottom: 1px solid #999;
      text-align: center;
    }

    .content {
      width: 100%;
      overflow: auto;
      height: 500px;
    }

    #messages li {
      list-style: none;
      padding: 5px;
    }

    #m {
      width: 80%;
      height: 30px;
      outline: none;
      color: #666
    }

    #btn {
      width: 20%;
      height: 30px;
      cursor: pointer;
    }

    .tips {
      width: 50%;
      margin: 4px auto;
      padding: 2px 5px;
      text-align: center;
      font-size: 8px;
      border-radius: 10px;
      background-color: #cfcfcf;
      color: #fff
    }

    .title #people {
      font-size: 8px;
      color: #999;
    }
  </style>
</head>

<body>
  <div class="chat">
    <div class="title">
      <h3>聊天室<span id="people">(0)</span></h3>
    </div>
    <div class="content">
      <ul id="messages">
      </ul>
    </div>
    <input id="m" autocomplete="off" /><button id="btn">Send</button>
  </div>
</body>
<script src="./static/dist/socket.io.js"></script>
<script>
  // 通过url获取username
  var test = window.location.href;
  var username = decodeURI(test.split("?username=")[1]);
  // 做个判断
  if (localStorage.getItem('username') != '') {
    var socket = io('http://localhost:3000/')
    var btn = document.getElementById('btn')
    var ul = document.getElementById('messages')
    let cxt = document.getElementById('m')
    let people = document.getElementById('people')
    // 点击send按钮,把消息发送给服务器
    btn.onclick = function () {
      // 把登录的用户名和输入框内容全部发送给服务器,让服务器做一次广播,才能同步用户信息。
      socket.emit('message', { username, inpval: cxt.value })
      return false
    }
    //监听服务器的广播消息,同步用户信息,msg就是点击发送按钮发送的用户信息
    socket.on('message', function (msg) {
      // 每个客户端将用户的消息渲染
      var newli = document.createElement("li")
      newli.innerHTML = msg.username + ':' + msg.inpval
      ul.appendChild(newli)
      cxt.value = ''
    })
    // 服务器端监听服务端建立连接发来的信息,用于渲染温馨提示信息,msg是服务器返回广播的用户对象数据
    socket.on("loginin", function (msg) {
      // 生成用户进入房间提示信息标签
      let tip = document.createElement("p")
      tip.innerHTML = msg.des
      // 设置样式
      tip.className = "tips"
      ul.appendChild(tip)
      // people是显示当前聊天室人数
      people.innerHTML = '(' + msg.count + ')'
    })
    //服务器端监听服务端建立连接发来的信息,msg是服务器返回广播的用户对象数据
    socket.on("loginout", function (msg) {
      // 生成用户退出提示信息
      let tip = document.createElement("p")
      tip.innerHTML = msg.des
      tip.className = "tips"
      ul.appendChild(tip)
      people.innerHTML = '(' + msg.count + ')'
    })
  } else {
    window.location.href = "/login.html"
  }

</script>

</html>

联系方式

v:13053025350,欢迎询问,也欢迎接单选手>>>>>

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

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

相关文章

Ping32和IPguard两款文件透明加密软件进行实测分享

透明加密软件在现代企业的数据安全保护中扮演着至关重要的角色。它们通过自动加密和解密文件&#xff0c;确保数据在存储、传输和使用过程中的安全性&#xff0c;从而防止敏感信息泄露。本文将介绍几种常见的透明加密软件&#xff0c;并对Ping32和IPguard两款加密软件进行实测分…

压铸模具适合采用3D打印随形水路吗

3D打印随形水路是一种基于3D打印技术的新型模具冷却水路设计。这种设计方式可以很好地贴合产品形状&#xff0c;有效提升产品良率和冷却效率&#xff0c;3D打印随形水路最初多应用在注塑模具上&#xff0c;而随着3D打印技术的发展和新材料的不断丰富&#xff0c;压铸模具在逐步…

DOS学习-目录与文件应用操作经典案例-more

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一.前言 二.使用 三.案例 一.前言 DOS系统的more命令是一个用于查看文本文件内容的工具。…

一个典型的分布式缓存系统是什么样的?no.32

分布式 Redis 服务 由于本课程聚焦于缓存&#xff0c;接下来&#xff0c;我将以微博内的 分布式 Redis 服务系统为例&#xff0c;介绍一个典型的分布式缓存系统的组成。 微博的 Redis 服务内部也称为 RedisService。RedisService 的整体架构如图所示。主要分为Proxy、存储、集…

日处理100吨污水处理设备安装需要多久

日处理100吨污水处理设备的安装时间取决于多种因素&#xff0c;包括设备的复杂性、安装地点的条件、所需的基础设施建设、以及安装团队的经验和效率等。以下是一个大致的安装时间框架和相关的考虑因素&#xff1a; 前期准备&#xff1a; 现场勘查和设计&#xff1a;1-2周&#…

【科研小小白】Faster R-CNN论文阅读笔记+与FAST RCNN区别对比+个人补充知识

论文阅读笔记 网络结构 整个Faster R-CNN可以分为三部分&#xff1a; **backbone&#xff1a;**共享基础卷积层&#xff0c;用于提取整张图片的特征。例如VGG16&#xff0c;或Resnet101&#xff0c;去除其中的全连接层&#xff0c;只留下卷基层&#xff0c;输出下采样后的特征…

SMERF,使用SD地图来增强模型的拓扑感知

论文链接 2311.04079v1 (arxiv.org)https://arxiv.org/pdf/2311.04079v1 研究背景 理解道路的拓扑关系是自动驾驶中很重要的一个环节&#xff0c;以往这个部分都是通过HD地图&#xff0c;及高精度地图的数据训练来实现的。高精度地图具备很多的标注信息和很明确的语义信息&a…

docker 指定jdk11镜像执行jar

dockerfile :下载jdk11 并将上传的jar 放入jdk11容器/root&#xff0c;改名为app.jar vi dockerfile 。。。。内容见下图 # 构建jdk11镜像 docker build -t demo . # 也可以通过jdk11镜像&#xff08;前提有jdk11镜像&#xff09;外挂载目录方式运行jar docker run --name d…

使用小技巧:PREEvision权限管理进阶篇

Review 在《浅谈PREEvision权限管理》一文中&#xff0c;我们介绍了如何在PREEvision中初始化一个权限模型&#xff0c;但只有模型还不够&#xff0c;我们需要对各个用户在不同Project中进行权限的配置&#xff0c;以及在EEA工程中对各个Package配置权限。 Roles and Right …

成都青年AI人才崭露头角,知了汇智科技助力孵化营大放异彩

5月18日-19日&#xff0c;为期两天的成都国际商贸城青年&#xff08;大学生&#xff09;AI应用孵化营活动在热烈的氛围中圆满落幕。本次活动由成都国际商贸城、成都成商数字科技有限公司、成都知了汇智科技有限公司及成都电商职教集团联合举办&#xff0c;旨在为青年&#xff0…

Project Reactor 响应式编程

Project Reactor 响应式编程 什么是响应式编程 响应式编程&#xff08;Reactive Programming&#xff09;是一种编程范式&#xff0c;致力于处理异步数据流和变化。它的核心思想是构建响应于变化的系统&#xff0c;即当数据流或事件发生变化时&#xff0c;系统能够自动地调整…

iOS单元测试覆盖率报告导出功能实现

一、插件安装 在Mac电脑上&#xff0c;安装slather插件。插件地址&#xff1a;https://github.com/SlatherOrg/slather 安装命令&#xff1a; gem install slather二、在Xcode上设置Code Coverage&#xff0c;Targets指定XXX 三、在终端切换到项目根目录下&#xff0c;执行单…

HTML静态网页成品作业(HTML+CSS)——魅族商城首页网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

Nginx - 常用的控制请求处理和响应生成的指令的高阶用法和最佳实践

文章目录 指令列表returnbreakrewriteifproxy_passtry_files 执行顺序基础用法高阶使用最佳实践 指令列表 return 作用&#xff1a;用于立即结束当前请求的处理并生成响应。用法&#xff1a;return code [text]; code 是 HTTP 状态码&#xff0c;如 200、301、404 等。text 是…

GitLab集成DingTalk(超级详细)

目录 参考文档1 简介2 集成方法2.1 钉钉测操作2.2 极狐GitLab侧操作2.3 钉钉群内操作 参考文档 钉钉集成 1 简介 极狐GitLab集成钉钉&#xff0c;可以在群组中机器人或者直接与机器人创建一对一的聊天框发送消息。当您未将钉钉账户和极狐GitLab 账户进行绑定时&#xff0c;机…

Blazor 下支持 Azure AD 的多套登录方案

比如上图配置了两套不同的登录方案&#xff0c;各有自己的 TenantId 和 ClientId &#xff0c;要同时支持他们的登录&#xff08;其实在同一套 TenantId 和 ClientId 里面配置多个登录账户不就好了&#xff0c;但是......那套登录的管理是在客户自己的Azure AD账户管理下的&…

C++BuilderXE 如何让listView按文件名数字排序而非字母排序

int m_nDataColSort0; bool IsAsctrue; void __fastcall TForm1::RzListView4Compare(TObject *Sender, TListItem *Item1, TListItem *Item2, int Data, int &Compare) { if(m_nDataColSort0) { //按列表第二列排序 //CompareCompareText(Item1->SubItems-…

新书发布——《机器学习大数据平台的构建、任务实现与数据治理——使用Azure、DevOps、MLOps》

内容简介 机器学习大数据平台的构建、任务实现与数据治理 你需要构建安全、稳定的数据平台&#xff0c;需要可以扩展到任何规模的工作负载。当项目从实验室进入生产环境时&#xff0c;你需要确信它可以应对现实工作中的挑战。本书能够帮助你实现这些需求&#xff0c;将讲述如…

ARM9驱动开发基础概念

2、arm9的通用寄存器有几个&#xff1f; 3、异常向量表中irq的异常向量是多少&#xff1f; 4、cpsr中的那几位是用来设置工作模式的&#xff1f; 5、r13,r14,15别名是什么&#xff1f;有什么作用&#xff1f; r13栈顶指针 &#xff1a;它用于实现堆栈指针操作&#xff0c;实…

安装测缝计安装事项详解

在建筑和工程领域&#xff0c;测量缝隙和裂缝的准确性对于工程质量和安全性至关重要。测缝计作为一种专业的测量工具&#xff0c;能够帮助工程师和施工人员准确测量和监测建筑结构的缝隙情况&#xff0c;进而采取合适的修复和加固措施&#xff0c;保证建筑物的稳定性和安全性。…