Node.js学习(六)——websocket组件学习在线聊天室demo

Node.js学习(六)——websocket组件实现在线聊天室demo

要实现的功能

  1. 在线人员列表展示,上下线刷新在线人员列表
  2. 即时聊天

demo图片

用express新建项目

express -e websocketdemo

下载依赖

在websocketdemo目录下执行命令,在项目下生成node_modules目录

npm install

添加websocket模块

npm install nodejs-websocket

实现代码

项目目录

在view下添加一个chartroom.ejs页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>聊天室</title>
    <style type="text/css">

    </style>
    <script type="text/javascript">
        var ws = null;

        window.onload = function () {
            console.log("初始化成功");
            //键盘事件注册
            document.onkeydown = function (event) {
                //ctrl+enter发送消息
                if(window.event.ctrlKey && window.event.keyCode==13){
                    sendTalk();//发送消息
                }
            };


            if (window.WebSocket) {
                ws= new WebSocket('ws://127.0.0.1:8002');

                ws.onopen = function (e) {
                    console.log("连接服务器成功");
                    //初始化在线人员列表
                    var myObj = new Object();
                    myObj.code = 0;
                    var json_data = JSON.stringify(myObj);
                    ws.send(json_data);
                }
                ws.onclose = function (e) {
                    console.log("服务器关闭");
                }
                ws.onerror = function () {
                    console.log("连接出错");
                }

                ws.onmessage = function (e) {
                    console.log("收到消息",e.data );
                    //更新内容显示框的内容
                    var serverObj = JSON.parse(e.data);
                    //如果code=1 则是发送消息的返回
                    if(serverObj.code == 1){
                        var contentArea = document.getElementById("contentArea");
                        var val = contentArea.value;
                        contentArea.innerText=val +serverObj.returnText;
                        contentArea.scrollTop = contentArea.scrollHeight;
                    }else if(serverObj.code == 2){
                        console.log("我是更新列表的消息");
                        //更新用户列表
                        var userList = document.getElementById("userList");
                        userList.value=serverObj.returnText;
                    }

                }
            }
        }

        //上线
        function upLine(){
            var upDownBtn = document.getElementById("upDownBtn");
            var uaerNameTxt = document.getElementById("uaerNameTxt");
            var userList = document.getElementById("userList");
            if(uaerNameTxt.value == ""){
                alert("请输入名称!");
                return;
            }
            if(upDownBtn.value == "上线"){
                upDownBtn.value="下线";
                uaerNameTxt.readOnly = true;
                //上线完成,添加用户
                var myObj = new Object();
                myObj.code = 2;
                myObj.type = "add";
                myObj.name = uaerNameTxt.value;
                var json_data = JSON.stringify(myObj);
                ws.send(json_data);
            }else{
                upDownBtn.value="上线";
                uaerNameTxt.readOnly = false;
                //下线完成,删除用户
                var myObj = new Object();
                myObj.code = 2;
                myObj.type = "del";
                myObj.name = uaerNameTxt.value;
                var json_data = JSON.stringify(myObj);
                ws.send(json_data);
            }

        }

        //发言
        function sendTalk(){
            var upDownBtn = document.getElementById("upDownBtn");
            if(upDownBtn.value == "上线") {
                alert("请先上线!");
                return;
            }
            var userName = document.getElementById("uaerNameTxt").value;
            var sendContent = document.getElementById("sendContent");
            var myDate = new Date();
            var dateStr = myDate.getHours()+":"+myDate.getMinutes()+":"+myDate.getSeconds();
            //往服务器发消息
            var myObj = new Object();
            myObj.code = 1;
            myObj.name = userName;
            myObj.date=dateStr;
            myObj.sendContent=sendContent.value;
            var json_data = JSON.stringify(myObj);
            ws.send(json_data);
            sendContent.value = "";
            sendContent.focus();
        }

        window.onbeforeunload = onbeforeunload_handler;
        //浏览器关闭事件 发起删除登录人消息
        function onbeforeunload_handler(){
            var uaerNameTxt = document.getElementById("uaerNameTxt");
            var myObj = new Object();
            myObj.code = 2;
            myObj.type = "del";
            myObj.name = uaerNameTxt.value;
            var json_data = JSON.stringify(myObj);
            ws.send(json_data);
        }
    </script>
</head>
<body style="">
<table border="1" style="width: 50%;height: 600px; border-color: #00B7FF;margin:0 auto">
    <tr height="40px">
        <td colspan="4">
            当前登录人:
            <input id="uaerNameTxt" type="text" width="400px" height="100%"/>
            <input id="upDownBtn" type="button" value="上线" onclick="upLine()"/>
        </td>
    </tr>
    <tr>
        <td colspan="3">
            <textarea id="contentArea" name="contentArea" disabled="disabled" style="width:100%;height:100%;padding:0px;margin:0px;"></textarea>
        </td>
        <td rowspan="3" width="150px">
            <textarea id="userList" name="userList" disabled="disabled" style="width:100%;height:560px;padding:0px;margin:0px;"></textarea>
        </td>
    </tr>
    <tr height="150px">
        <td colspan="3">
            <textarea id="sendContent"  style="width:100%;height:100%;padding:0px;margin:0px;"></textarea>
        </td>
    </tr>
    <tr height="40px">
        <td colspan="2">

        </td>
        <td width="80px" style="padding:0px;">
            <input type="button" onclick="sendTalk()" value="发送" style="width:100%;height:100%;margin:0px;border:0px;padding:0px;"/>
        </td>
    </tr>
</table>
</body>
</html>

index.js修改

  1. 添加跳转到页面的路由
  2. 添加websocket服务器
  3. 服务器中3种类型的逻辑处理
  4. code=0,代表初始化客户端请求。1.将当前连接放入在线人集合中。2.向所有在线人发出更新在线人的消息。
  5. code=1,代表发送消息。将所有在线人的消息界面追加上当前发送的消息。
  6. code=2,代表人员列表更新。上线是新增一个在线人员,下线或刷新浏览器是减少一个在线人员。
var express = require('express');
var router = express.Router();
var ws = require("nodejs-websocket");
//存所有人的连接
var onLineUser = new Array();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

//聊天室页面
router.get('/chartroom', function(req, res, next) {
  res.render('chartroom');
});

//聊天服务器8002
var server = ws.createServer(function (conn) {
  conn.on("text", function (str) {
    var obj = JSON.parse(str);
    switch(obj.code){
      case 0:initClient(conn);break;
      case 1:returnMsg(conn,obj);break;
      case 2:userListHandle(conn,obj);break;
    }
  })
  conn.on("close", function (code, reason) {
    console.log("关闭连接")
  });
  conn.on("error", function (code, reason) {
    console.log("异常关闭")
  });
}).listen(8002)

//发送消息,返回消息
function returnMsg(conn,obj){
  if(userList.length != 0){
    var returnText = obj.name+" "+obj.date+":\n"+"  "+obj.sendContent+"\n";
    var returnObj = new Object();
    returnObj.code = 1;
    returnObj.returnText=returnText;
    for(var i=0;i<onLineUser.length;i++){
      onLineUser[i].sendText(JSON.stringify(returnObj))
    }
  }
}

//初始化的消息
function initClient(conn){
  console.log("onLineUser长度:"+onLineUser.length);
  onLineUser.push(conn);
  flashUserList();
}

var userList = new Array();
//人员列表更新
function userListHandle(conn,obj){
  if(obj.type == "add"){
    userList.push(obj.name);
  }else if(obj.type == "del"){
    userList.remove(obj.name);
  }
  flashUserList();
}

//刷新所有人的用户列表
function flashUserList(){
  if(userList.length != 0){
    var myObj = new Object();
    myObj.code = 2;
    myObj.returnText =arrToStr(userList);
    for(var i=0;i<onLineUser.length;i++){
      onLineUser[i].sendText(JSON.stringify(myObj));
    }
  }
}

function arrToStr(arr){
  var str = "";
  for(var i = 0 ; i < arr.length ; i++){
    str += arr[i] + "\n";
  }
  return str;
}

Array.prototype.indexOf = function(val) {
  for (var i = 0; i < this.length; i++) {
    if (this[i] == val) return i;
  }
  return -1;
};

Array.prototype.remove = function(val) {
  var index = this.indexOf(val);
  if (index > -1) {
    this.splice(index, 1);
  }
};

module.exports = router;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

-贫寒豌豆

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

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

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

打赏作者

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

抵扣说明:

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

余额充值