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

前言

源码获取: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,欢迎询问,也欢迎接单选手>>>>>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苦逼的猿宝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值