版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38355456/article/details/78451266
一、我们来建立一个简单的聊天室的功能:
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的一个简单的聊天程序就完成了。