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

相关推荐
燕雀安知鸿鹄之志哉.10 分钟前
攻防世界 web ics-06
网络·经验分享·安全·web安全·网络安全
ProcessOn官方账号1 小时前
如何绘制网络拓扑图?附详细分类解说和用户案例!
网络·职场和发展·流程图·拓扑学
Ven%1 小时前
如何在防火墙上指定ip访问服务器上任何端口呢
linux·服务器·网络·深度学习·tcp/ip
神的孩子都在歌唱2 小时前
TCP/IP 模型中,网络层对 IP 地址的分配与路由选择
网络·tcp/ip·智能路由器
阿雄不会写代码2 小时前
ubuntu安装nginx
linux·服务器·网络
starstarzz2 小时前
计算机网络实验四:Cisco交换机配置VLAN
网络·计算机网络·智能路由器·vlan·虚拟局域网
EasyDSS3 小时前
国标GB28181-2022平台EasyGBS:安防监控中P2P的穿透方法
网络协议·php·音视频·p2p
网安墨雨4 小时前
常用网络协议
网络·网络协议
Tlzns4 小时前
Linux网络——UDP的运用
linux·网络·udp
黑客老陈4 小时前
新手小白如何挖掘cnvd通用漏洞之存储xss漏洞(利用xss钓鱼)
运维·服务器·前端·网络·安全·web3·xss