基于node的websocket学习笔记二:一个简单的聊天室程序与优化方案

来源:互联网 发布:凯文先生的淘宝店 编辑:程序博客网 时间:2024/05/23 23:40

一、我们来建立一个简单的聊天室的功能:

1、简单的HTML代码如下:

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>webSocet</title></head><body><h1>Chat Room</h1><input type="text" id="sendTxt"><button id="sendBtn">发送</button><script>    //建立连接    let webSocket = new WebSocket('ws://localhost:8001/');    //开启连接    webSocket.onopen = function () {        console.log('webSocket open');        //发送信息        document.getElementById('sendBtn').onclick = function () {            var text = document.getElementById('sendTxt').value;            if (text) {                webSocket.send(text);            }        };    };    //关闭连接    webSocket.onclose = function () {        console.log('webSocket close');    };    //拿到返回    webSocket.onmessage = function (e) {        console.log(e.data);        showMessage(e.data)    };    //辅助函数    function showMessage(str){        var div=document.createElement('div');        div.innerHTML=str;        document.body.appendChild(div);    }</script></body></html>
2、node后端代码如下:
var ws = require("nodejs-websocket")var clientCount=0;//客户的个数// Scream server example: "hi" -> "HI!!!"var server = ws.createServer(function (conn) {    console.log("New connection");    clientCount++;    conn.nickName='user'+clientCount;    //给每一个客户都广播一个信息,告知有新用户进来    broadcast(conn.nickName+'comes in');    //获取连接信息    conn.on("text", function (str) {        console.log("Received "+str);        broadcast(str)    });    //断开连接的回调    conn.on("close", function (code, reason) {        console.log("Connection closed")        broadcast(conn.nickName+' leave')    });    //处理错误事件信息    conn.on('error',function(err){        console.log('throw : err');        console.log(err);    });}).listen(8001);console.log('webSocket server listening on port 8001');//建议一个公共广播的函数function broadcast(str){    //首先要拿到server的所有连接    server.connections.forEach((item)=>{        item.sendText(str)    })}
最后启动node代码之后,访问8001端口号,就可以直接访问到我们最简单的聊天室了,这个时候重新新开一个网页,在输入localhost:8001,有可以开启第二个客户身份,这个时候就可以相互通信了。
但是有两个弊端的地方:第一个地方是进入和离开的消息和我们聊天的消息同在一起。第二个是没有对发出信息的用户进行身份识别。
二、对于以上两个弊端的地方进行优化和改造
首先要分析为回出现以上两个问题:首先第一个是前端拿到的回调,webSocket.onmessage=function(e){console.log(e.data)};这个函数中e.data,就是函数本身那单的返回信息就是一个字符串的信息,这样的封装实在是过于简单了,我们需要对其进行更多后续的处理。
这个时候首先在后端server进行改造:添加一个返回信息的对象,来封装所有的返回信息,而不是以字符串的形式抛出给前端返回。
var ws = require("nodejs-websocket")var clientCount=0;//客户的个数// Scream server example: "hi" -> "HI!!!"var server = ws.createServer(function (conn) {    console.log("New connection");    clientCount++;    conn.nickName='user'+clientCount;    var message={};    message.type='enter';    message.data=conn.nickName+'comes in';    //给每一个客户都广播一个信息,告知有新用户进来    broadcast(JSON.stringify(message));    //获取连接信息    conn.on("text", function (str) {        console.log("Received "+str);        var message={};        message.type='message';        message.data=conn.nickName+": "+str;        broadcast(JSON.stringify(message));    });    //断开连接的回调    conn.on("close", function (code, reason) {        console.log("Connection closed");        var message={};        message.type='leave';        message.data=conn.nickName+' leave';        broadcast(JSON.stringify(message));    });    //处理错误事件信息    conn.on('error',function(err){        console.log('throw : err');        console.log(err);    });}).listen(8001);console.log('webSocket server listening on port 8001');//建议一个公共广播的函数function broadcast(str){    //首先要拿到server的所有连接    server.connections.forEach((item)=>{        item.sendText(str)    })}




这个时候回到前端之后,我们在冲webSocket.onmessage这个函数中拿到的e.data已经是被格式化的一个json字符串,同时对渲染函数进行改在如下:
    //拿到返回    webSocket.onmessage = function (e) {        console.log(e.data);        var message=JSON.parse(e.data);        showMessage(message.data,message.type);    };    //辅助函数    function showMessage(str,type){        var div=document.createElement('div');        div.innerHTML=str;        if(type==='enter'){            div.style.color='blue';        }else if(type==='leave'){            div.style.color='red'        }        document.body.appendChild(div);    }


这个时候满足的功能,通过返回的类型,我们可以区分,用户进来时候广播信息的样式,用户离开的时候广播信息的样式,以及用户输入的时候广播信息的样式;
因为同时我们在封装服务端返回对象的时候,给链接处理信息的message.data前面拼接了一个conn.nickName,所以在前端信息展示的时候,会自动添加上一个用户名的。
自此给予node-websocket的一个简单的聊天程序就完成了。
 
原创粉丝点击