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,欢迎询问,也欢迎接单选手>>>>>

相关推荐
_.Switch41 分钟前
高级Python自动化运维:容器安全与网络策略的深度解析
运维·网络·python·安全·自动化·devops
qq_2546744143 分钟前
工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置
网络
JokerSZ.1 小时前
【基于LSM的ELF文件安全模块设计】参考
运维·网络·安全
小松学前端3 小时前
第六章 7.0 LinkList
java·开发语言·网络
城南vision4 小时前
计算机网络——TCP篇
网络·tcp/ip·计算机网络
Ciderw4 小时前
块存储、文件存储和对象存储详细介绍
网络·数据库·nvme·对象存储·存储·块存储·文件存储
石牌桥网管4 小时前
OpenSSL 生成根证书、中间证书和网站证书
网络协议·https·openssl
Tony聊跨境5 小时前
独立站SEO类型及优化:来检查这些方面你有没有落下
网络·人工智能·tcp/ip·ip
2403_875736876 小时前
道品科技智慧农业中的自动气象检测站
网络·人工智能·智慧城市