Node.js学习(六)——websocket组件实现在线聊天室demo
要实现的功能
- 在线人员列表展示,上下线刷新在线人员列表
- 即时聊天
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修改
- 添加跳转到页面的路由
- 添加websocket服务器
- 服务器中3种类型的逻辑处理
- code=0,代表初始化客户端请求。1.将当前连接放入在线人集合中。2.向所有在线人发出更新在线人的消息。
- code=1,代表发送消息。将所有在线人的消息界面追加上当前发送的消息。
- 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;