一、我们来建立一个简单的聊天室的功能:
1、简单的HTML代码如下:
2、node后端代码如下:<!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>
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的一个简单的聊天程序就完成了。