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

前言

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

目录结构

后端依赖

启动方式

前端是html正常启动

后端是node app.js

后端app.js核心代码

javascript 复制代码
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部分

javascript 复制代码
<!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,欢迎询问,也欢迎接单选手>>>>>

相关推荐
哈乐3 小时前
网工应用题:配置命令补全类题目
服务器·前端·网络
雯0609~3 小时前
宝塔配置:IP文件配置,根据端口配置多个项目文件(不配置域名的情况)
服务器·网络协议·tcp/ip
梁正雄3 小时前
19、docker跨主机网络 Overlay\Underlay
网络·docker·容器
沧澜sincerely4 小时前
运输层协议概述及UDP
网络·udp·运输层
国科安芯4 小时前
抗辐照MCU芯片在无人叉车领域的性能评估与选型建议
网络·人工智能·单片机·嵌入式硬件·安全
国科安芯5 小时前
抗辐照MCU芯片在激光雷达领域的适配性分析
网络·人工智能·单片机·嵌入式硬件·fpga开发
xixixi777775 小时前
水坑攻击的攻击原理和特点+案例和防御方法
网络·安全·web安全
王道长服务器 | 亚马逊云5 小时前
AWS + WordPress:中小型外贸独立站的理想组合
服务器·网络·云计算·音视频·aws
携欢6 小时前
PortSwigger靶场之盲 SSRF(服务器端请求伪造)漏洞通关秘籍
前端·网络·安全·web安全
Xの哲學6 小时前
Linux eMMC子系统深度解析:从硬件协议到内核实现
linux·网络·算法·架构·边缘计算