nodejs与websocket模拟简单的聊天室

nodejs与websocket模拟简单的聊天室

server.js



const http = require('http')
const fs = require('fs')

var userip


var server = http.createServer((req,res)=>{
    res.writeHead(200,{'Content-Type':'text/html;charset=utf8'})
    
    res.end(fs.readFileSync('./index.html'))
    userip = req.connection.remoteAddress
    userip = userip.replace('10.9.166.','')
})


//socket
const Server = require('ws').Server

//建立好了服务端
var wss = new Server({server})

//存放前端连接的socket
var clientMap = {}
var count = 0
var id = 0
//当客户端连接上的就会触发,回调会接收一个socket对象
wss.on("connection",function (socket) {
    count++
    id++
    socket.id = id
    clientMap[socket.id] = socket
    socket.nickname = '好友'
    console.log(`现在有${count}人连接了`)
    broadClients(socket.nickname,1)


    //当这个客户端发送数据的时候会触发
    socket.on("message",function (msg) {
        //console.log(`客户端${socket.id} 说:${msg}`)
        let info = JSON.parse(msg)
        if(socket.nickname!=info.nickname){
            socket.nickname = info.nickname
            broadClients()
        }
        socket.nickname = info.nickname
        broadcast(socket,info.msg)
    })

    //当客户端断开的时候触发
    socket.on("close",function () {
        //console.log(`客户端${socket.id} 说:${msg}`)
        count--
        let nickname = socket.nickname
        delete clientMap[socket.id]
        broadClients(nickname,2)
       
      
    })

    //当客户端连接出错的时候
    socket.on("error",function (err) {
        console.log(err)
    })

})

//广播函数,像所有的客户端发送某一个客户端说的话
function  broadcast(socket,msg) {
    let info = {nickname:socket.nickname+userip,msg:msg,type:'msg'}
    for(var id in clientMap){
        info.isMe = socket.id==id?'true':false
        clientMap[id].send(JSON.stringify(info))
    }
}

function  broadClients(nickname,type) {
    let clients = []
    for(var id in clientMap){
        clients.push(clientMap[id].nickname)
    }
    for(var id in clientMap){
        clientMap[id].send(JSON.stringify({
            count,clients,
            type:'count',
            nickname:nickname+userip,
            _type:type
        }))
    }
}



 server.listen(2000,'10.9.166.56')



index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>wechat</title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<style>
    html,body{
        height: 100%;
        display: flex;justify-content: center;align-items: center;
    }
    #room{
         600px;
        height: 600px;
        position: relative;
    }
    #room .panel-body{
        padding: 0;
    }
    #room .content{
        height: 460px;overflow-y: auto;
        padding: 10px;
        background: #fff;
    }
    #room .control-box{
        height: 90px;
        padding: 10px;
        display: flex;
        flex-wrap: nowrap;
        align-items: center;
    }
    #room .control-box .btn{
        margin: 0px 15px;
    }
    .list-group-item{
        border: none;
    }
    .list-group-item.other span:after{
        content: ':';
        display: inline-block;
        margin: 0px 3px;
    }
    .list-group-item.me span:before{
        content: ':';
        display: inline-block;
        margin: 0px 3px;
    }
    .list-group-item.me{
        display: flex;
        align-items: center;
        flex-direction: row-reverse;
    }
    .numbers{
        position: absolute;
         150px;
        top:0;left: -150px;
    }
    .numbers .online,.numbers .clients{
         80%;
        margin-left: 10%;
    }
    .numbers .clients{
        margin-top: 15px;
        height: 400px;
        overflow: auto;
    }
    .p-info{
        font-size: 12px;
        color: rgb(172, 170, 170);
    }
</style>
<body>

    <div id="room" class="panel panel-primary">
        <div class="panel-heading clearfix">
                wechat
            <input id="nickname" placeholder="昵称,默认为好友" style="200px;" type="text" class="form-control pull-right">
        </div>
        <div class="panel-body">
            <div class="content">
                <ul class="list-group msgs"></ul>
            </div>
            <div class="control-box">
                <input id="word" type="text" class="form-control">
                <button id="send" class="btn btn-success">发送</button>
            </div>
        </div>

        <div class="numbers">
            <button class="btn btn-info online">
                在线人数:<span class="count"></span>
            </button>
            <ul class="list-group clients">
                  
            </ul>
        </div>

    </div>
    

    
   
</body>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script>
    //创建客户端的连接socket
  var wsc = new WebSocket('ws://10.9.166.56:2000');

  wsc.onopen = function (e) {//当客户端连接上的时候就会触发
    //console.log('我已经连接上服务端了')
  };

  wsc.onmessage = function (e) {//当服务端返回消息的时候触发
        //  console.log(e.data);
        let info = JSON.parse(e.data)
        switch(info.type){
            case 'msg':
            handleMsg(info);break;
            case 'count':
            handleCount(info);break;
        }

        
         
  };

  function handleMsg(info) {
    let str = `
    <li class="list-group-item ${info.isMe?'me':'other'}">
        <span>${info.nickname}</span>
        <button class="btn btn-success">${info.msg}</button>                    
    </li>
    `
    let li = $(str)       
    $(".msgs").append(li)
    li[0].scrollIntoView()
    word.value = ''
  }

  function handleCount(info) {
      $(".count").html(info.count)
      var str = ''
      info.clients.forEach(item => {
          str+='<li class="list-group-item list-group-item-info text-center">'+item+'</li>'
      });
      $(".clients").html(str)
      //如果有人来或者有人走,需要报一个消息
      if(info.nickname&&info._type){
          $(".msgs").append('<p class="p-info text-center">'+info.nickname+(info._type==1?'加入群聊':'离开群聊')+'</p>')
      }
  }

  $("#send").click(function () {
      send()
  })
  $("#word").keyup(function (e) {
      if(e.keyCode==13){
          send()
      }
  })

    function send() {
      var nickname = $("#nickname").val() || '好友'
      var msg = $("#word").val()
      var  reg = /<[^>]+>/g
      if(msg!=''){
        if(!reg.test(msg)&&!reg.test(nickname)){
            wsc.send(JSON.stringify({nickname:nickname,msg:msg}))
        }else{
            alert('输入框内请勿输入非法字符')
        }    
      }else{
          alert('发送内容不能为空,请重新输入')
      }
      
    }

  var canUse = true
  wsc.onclose = function (e) {//当服务端关闭的时候触发
      // alert('聊天服务已经关闭了')
      canUse = false
  };






  wsc.onerror = function (e) {//错误情况触发
      console.log(e)
  }


</script>
</html>


在终端中输入node server即可运行服务器,在浏览器输入你的IP地址+端口号

这里我的ip地址是10.9.166.56,端口号是2000,改成你的ip地址,即可开始运行,赶紧运行,和你的朋友聊起来吧

原文地址:https://www.cnblogs.com/happ0/p/7923103.html