zoukankan      html  css  js  c++  java
  • 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地址,即可开始运行,赶紧运行,和你的朋友聊起来吧

  • 相关阅读:
    青檬音乐台闲时听听电台吧
    [转]What is AOP?
    实现页面元素拖动效果的JS函数
    gorithms.算法概论.习题答案
    Asp.Net读取并显示Excel文件中的内容(OleDb方式)
    收藏的一些小软件
    Master Page Path (MasterPage 相对路径)
    rundll32 netplwiz.dll,UsersRunDll
    关于锁
    我的回帖保存
  • 原文地址:https://www.cnblogs.com/happ0/p/7923103.html
Copyright © 2011-2022 走看看