nodejs+koa2+pm2+ws开发聊天室(仿微信网页版界面)

nodejs+koa2+pm2+ws开发聊天室  (仿微信网页版界面)

 

https://blog.csdn.net/qq_42783610/article/details/85233555  先看我之前的博客配置koa2脚手架 #项目使用的是纯html代码的ejs

 https://blog.csdn.net/qq_42783610/article/details/85233415  配置pm2 windows开机自启动项目 ,  #这里可以不配置

 

配置完后:

cd进入目录

执行npm install mongodb --save    #保存用户登录信息,可以不使用数据库,自己判断用户

 npm install ws --save  #安装ws包

 先更改bin/www:

var http = require('http');
var app = require('../app');
var server = http.createServer(app.callback());

//改成

var server = require('../app');//让http创建在app.js

服务器端的逻辑

const WebSocket = require('ws');
//末尾添加
const server = http.createServer(app.callback()) //创建http
const wss = new WebSocket.Server({server})  //创建ws
global.userList = []; //用户登录状态
wss.on('connection',(ws)=>{
    ws.on('message',async (msg) => { //监听客户端发送消息
         const data = JSON.parse(msg);

        if (util.search(userList,data.user_id)) {  //判断是否有这个人了,避免刷新页面添加用户
          userList.push(data.user_id)
        }
        let  _id = mongodb.getObjectID(data.user_id);
        let find = await mongodb.find('user',{_id})  //查询用户信息
          if (data.check == 0) { //有人进入,就给所有人发送进来的信息,并添加至客户端的侧边栏
            let id = userList.indexOf(data.user_id)
            Array.from(wss.clients).forEach((value,index) => {
              if (id == index) { //给进来的那个人发送所有人的信息
                userList.map(async(value,index) => {
                    let  _id = mongodb.getObjectID(value);
                  let finds = await mongodb.find('user',{_id})
                  Array.from(wss.clients)[id].send(JSON.stringify({ //返回用户信息
                    "user_id": `${finds[0].user_id}`,
                    "check":`${data.check}`,
                    "user_num":`${userList.length}`
                  })) 
                })

              }else { //给其他人发送,有人进来的信息,并添加至客户端的侧边栏
                Array.from(wss.clients)[index].send(JSON.stringify({
                  "user_id": `${find[0].user_id}`,
                  "check":`${data.check}`,
                  "user_num":`${userList.length}`
                }))
              }
            })
          }else if (data.check == 2 ) {  //发送用户说的话
              let id = userList.indexOf(data.user_id);

              Array.from(wss.clients).forEach((value,index) => { //自己发的,在客户端显示右边
                if (id == index) {
                  Array.from(wss.clients)[index].send(JSON.stringify({ //过滤xss
                    "user_id": `${find[0].user_id}`,
                    "data":`${data.msg.replace(/[<">']/g, (a) => { 
                        return {
                            '<': '&lt;',
                            '"': '&quot;',
                            '>': '&gt;',
                            "'": '&#39;'
                        }[a]
                })}`,
                    "check":`${data.check}`,
                    "who":'1'
                  }))
                }else { //别人发的,在客户端显示左边
                  Array.from(wss.clients)[index].send(JSON.stringify({
                    "user_id": `${find[0].user_id}`,
                    "data":`${data.msg.replace(/[<">']/g, (a) => {
                        return {
                            '<': '&lt;',
                            '"': '&quot;',
                            '>': '&gt;',
                            "'": '&#39;'
                        }[a]
                      })}`,
                    "check":`${data.check}`,
                    "who":'2'
                  }))
                }
              })
          }
        ws.on('close',() => {  //监听客户端断开链接
          util.remove(userList,data.user_id) //退出从列表中删除
          wss.clients.forEach(function each(client){
            client.send(JSON.stringify({
              "user_id": `${find[0].user_id}`,
              "check":"1",
              "user_num":`${userList.length}` //从客户端侧边栏删除,并返回人数
            }))
          })
        })
    })
})
module.exports = server

客户端的逻辑:

<!DOCTYPE html>
<html>

<head>
  <title>
    chatRoom
  </title>
  <link rel='stylesheet' href='/css/style.css' />
  <link rel='stylesheet' href='/css/index.css' />
</head>
<body>
  <div class="wrapper">
    <div class="index">
      <div class="main">
        <div class="main_inner">
          <div class="main_left">
               <ul id="num">  <!--这里是侧边栏-->

               </ul>
          </div>
          <div class="main_right">
            <div class="top">
              chatRoom 在线人数:<span id="user_num"></span>
            </div>
            <div class="content">
              <div class="noinfo">
                暂无消息
              </div>
              <div id="info">
              </div>
            </div>
            <div class="insert">
              <textarea name="name" rows="8" cols="80" id="input"></textarea>
              <button type="button" name="button" id="send">发送</button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div class="bg"></div>
</body>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script type="text/javascript">
  $(()=>{
    let ws = new WebSocket('ws://localhost:3000') //连接
    let user_id = sessionStorage.user_id;
    ws.onopen = () => {     //连上后操作
      console.log(`[CLIENT] open()`)   
      if (user_id) {   //检测session(登录状态)是否有效
        $.ajax({
          method:'get',
          url:'../checkSession',
          data:{
            user_id:sessionStorage.user_id
          },
          success:res => {
             if (res.errCode == 0) {
               ws.send(JSON.stringify({
                 "user_id": `${user_id}`,
                 "check":"0"
               }))
             }
          },
          error:err => {
             if (err.responseJSON.errCode == 1) {
                location.replace('/')
             }
          }
        })
      }else {
        location.replace('/')
      }
      function send(event){  //发送给服务器端
        if (event.keyCode && event.keyCode!= 13) { //回车发送
           return;
        }
          if ($('#input').val()) {
            ws.send(JSON.stringify({
              "user_id": `${user_id}`,
              "msg": `${$('#input').val()}`,
              "check":"2"
            }))
            $('#input').val('') //发送后重置
          }

      }
      $('#send').on('click', send)//绑定事件
      $('#input').on('keyup',send)
    }

    ws.onmessage = (chunk) => {
      const msg = JSON.parse(chunk.data);
       if (msg.check == 0) { //侧边栏添加 有用户进来
         $("#num").append(`<li>${msg.user_id}</li>`)
         $("#user_num").text(msg.user_num)
       }else if (msg.check == 1) { //侧边栏删除 有用户离开
          $("#num li:contains("+msg.user_id+")").remove()
          $("#user_num").text(msg.user_num)
       }else if(msg.check == 2){  //获取聊天内容
         let date = new Date();
         let hour = date.getHours();
         let min = date.getMinutes();
         $('#info').css('display','block')  
         $('.noinfo').css('display','none') //把默认显示暂无消息去除
         if (sessionStorage.hour && hour - sessionStorage.hour >= 1 || sessionStorage.min && min - sessionStorage.min == 10) {  //一段时间后发送显示时间
           sessionStorage.hour = hour
            sessionStorage.min = min
           $("#info").append(`<div class="time">${hour}:${min < 10 ? min = '0'+min : min}</div>`);  
         }else if(!sessionStorage.hour || !sessionStorage.min){
           sessionStorage.hour = hour
            sessionStorage.min = min
           $("#info").append(`<div class="time">${hour}:${min < 10 ? min = '0'+min : min}</div>`);
         }

         if (msg.who == 1) {  //判断是自己发送的还是别人送的,自己在右,别人在左
           $("#info").append(`<div class='say'><div id='data'> <span>${msg.data}</span></div><img src= 'images/tou.jpg'> <p>${msg.user_id}</p></div>`)
         }else {
           $('#info').append(`<div class="ysay"> <img src="images/tou.jpg" alt=""><p>${msg.user_id}</p> <div id="data2"><span>${msg.data}</span></div></div>`)
         }
          $("#info").scrollTop($('#info').get(0).scrollHeight) //若内容超出显示滚动条,并使滚动条一直在底部
       }
    }
    ws.onclose = () => {
      console.log('server close')
    }
    ws.onerror = (err) => {
      console.log(err);
    }
  })

</script>

</html>

github完整项目地址https://github.com/MRXKing/chatRoom

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值