NodeJs实现简单聊天室效果

流氓凡 资源分享 2019-11-05 4.17 K 0

基于NodeJs 利用express框架实现聊天室效果,

    主要需要模块如下:express、socket.io、ejs  还需要加载jquery和bootstarp模块(可选)

    功能实现:主要实现多人在线实时群聊

    鸣谢:模版制作@梦凡

image.png

以下是js代码:

//加载express框架
var express = require("express");
//创建应用
var app = express();
//创建服务
var server = require('http').Server(app);
//加载socket模块
var io = require('socket.io')(server);
//设置静态资源
app.use(express.static("node_modules"));
//加载模版
app.set("view engine", "ejs");
//设置模版目录
app.set("views", "./views");
//设置路由
app.get('/', function (req, res) {
res.render('index');
res.end();
});
//连接socket服务
io.on("connection", function (socket) {
//设置端口 接收并广播消息数据
socket.on('44', function (data) {
// console.log(data);
//广播消息数据
socket.broadcast.emit('44', data);
})
})
//设置监听端口
server.listen(8080);


ejs引擎模版中代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>在线聊天 By:NodeJs</title>
<link rel="stylesheet" href="/liaotian/css/style.css">
<link rel="stylesheet" href="https://at.alicdn.com/t/font_1465982_zggqnzvtvm.css">
<script src="/liaotian/js/jquery-1.8.3.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<div class="maxbox">
<div class="box">
<div class="gn">
<div class="tx">
<img src="/liaotian/images/tx.jpg" alt="" onselectstart="return false;">
</div>
<ul class="tab">
<li><i class="iconfont icon-xiaoxi"></i></li>
<li><i class="iconfont icon-duoren"></i></li>
<li><i class="iconfont icon-shoucang"></i></li>
<li><i class="iconfont icon-wenjian"></i></li>
</ul>
</div>
<div class="lxr">
<div class="top">
<div class="ss">
<div class="fdj"><i class="iconfont icon-fangdajing"></i></div>
<input type="text" placeholder="搜索" onselectstart="return false;">
</div>
<div id="tj">
<i class="iconfont icon-jia"></i>
</div>
</div>
<div class="lb">
<ul class="lsdh">
<li id="dq">
<div class="lxrtx">
<img src="/liaotian/images/1.jpg" alt="">
</div>
<div class="nc">
<span onselectstart="return false;">小骚逼群聊</span>
</div>
<div class="sclt" style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">
<span onselectstart="return false;"></span>
</div>
<div class="sj">
<span onselectstart="return false;"></span>
</div>
</li>
</ul>
</div>
</div>
<div class="fs">
<div class="fstop">
<div class="mz">
<span onselectstart="return false;" id="nickName">小骚逼群聊</span>
</div>
</div>
<!-- 消息框(将来自己的消息和回复的消息都会出现在这里) -->
<div class="lsxx">

</div>

<div class="sr">
<div id="srk">
<textarea name="" id="dwb"></textarea>
</div>
<div class="fsxx">
<button id="ffss" style="cursor:pointer;">发送</button>
</div>
</div>

<div id="bnk" style="display: none;">
<!-- 自己消息(用于后面克隆) -->
<div class="zjxx clearfix">
<div class="zjtx">
<div class="picName" style="background: chocolate;"></div>
</div>
<div class="zjxxk">
<span></span>
</div>
</div>
</div>

</div>
</div>
</div>
</body>
<script>
//获取最后消息时间函数
function getDate(){
var date=new Date;
var h=date.getHours();
var m=date.getMinutes();
var sj=h+':'+m;
//将时间插入到页面中
$(".sj span").html(sj);
}

//获取当前时间
getDate();
//清空名字
$(".nc span").html("");
//定义访问者名字
var name=prompt("请输入你的名字");
//连接socket服务
var socket=io.connect("/");
//判断名字不能为空
if(name==""){
//如果为空则再次输入
var name=prompt("请输入你的名字");
}
//设置自己的头像
$(".zjtx .picName").html(name.substr(0,1));
//设置自己的名字
$(".nc span").html(name);
//绑定发送按钮
$("#ffss").click(function(){
if($("#dwb").val()==""){
alert("请输入内容");
return false;
}
//将内容输出到消息栏
$("#bnk span").html(fun($("#dwb").val()));
//克隆元素
var me=$("#bnk .zjxx").clone();
//将元素插入到消息栏后面
$(".lsxx").append(me);
//滚动条跟随
$('.lsxx').scrollTop( $('.lsxx')[0].scrollHeight );

//向群组发送消息请求
socket.emit('44',{name:$(".nc span").html(),data:$("#dwb").val()});
//清空发送框内容
$("#dwb").val("");

})

//绑定键盘事件
$("#dwb").keydown(function(e){
//组合键按下实现换行
if(e.ctrlKey && e.keyCode==13){
$(this).val($(this).val()+'\r\n');
return false;
}
//实现回车键发送消息
if(e.keyCode==13){
//执行按钮点击事件
$("#ffss").trigger("click");
//清空发送框内容
$(this).val("");
//取消按键默认行为
return false;
}
})

//接收消息
socket.on('44',function(data){
//更新时间
getDate();
//设置他人头像
var szm=data.name.substr(0,1);
//创建一个回复消息盒子以及里面的内容
var hd=$('<div class="dmxx clearfix"><div class="dmtx"><div class="picName">'+szm+'</div></div><div id="nickNames" style="width:120px;height:20px;color: #aaa;font-size:12px;padding-left:50px;">'+data.name+'</div><div class="dmxxk"><span>'+fun(data.data)+'</span></div></div>');
//将最后回复消息同时插入到左边群组下方消息框
$(".sclt").html(fun(data.data));
//将回复消息盒子及内容插入到消息框末尾
$(".lsxx").append(hd);
//再次执行滚动条跟随
$('.lsxx').scrollTop( $('.lsxx')[0].scrollHeight );

})

//消息内容正则 过滤
function fun(obj){
//定义一个敏感词数组
var list=['<','>','alert'];
list.forEach(function(ele){
var reg=new RegExp(ele,"g");
obj=obj.replace(reg,"*");
})
return obj;
}

</script>
</html>


css布局样式代码

*{
margin:0px;
padding:0px;
}
/*
 * 解决高度塌陷问题clearfix
 */
.clearfix:before,
.clearfix:after{
content: "";
display: table;
clear: both;
}
.clearfix{
zoom:1;
}
ul li{
list-style: none;
}
.maxbox{
background: #ccc;
width:100%;
height:720px;
overflow: hidden;
}
.box{
width:1000px;
height: 600px;
background:rgba(0,0,0,0.5);
position: relative;
top:0px;
left:0px;
}
.gn{
width:75px;
height: 100%;
background:rgba(0,0,0,0.5);
position: absolute;
}
.tx{
width:43px;
height:43px;
margin:25px auto 0;
}
.tx img{
width:100%;
}
.tab{
width:43px;
margin:36px auto 0;

}
.tab li{
width:43px;
height:43px;
margin-top:38px;
cursor: pointer;
}
.tab li:first-child{
margin-top:0px;
}
.tab li i{
font-size: 28px;
color:#959595;
width:28px;
margin:0 auto;
display: block;
line-height: 43px;
}
.lxr{
width:313px;
height:100%;
background: #e2e1e0;
position: absolute;
left:75px;
}
.top{
width:100%;
height:78px;
background: #ebeaea;
}
.ss{
width:238px;
height:31px;
border-radius:7px;
background: #dbd9d8;
position: absolute;
top:31px;
left:21px;
}
.ss input{
position: absolute;
width:200px;
height:31px;
top:0px;
left:30px;
background: none;
border: none;
outline: none;
}
.fdj{
width:15px;
height:100%;
line-height: 31px;
margin-left:7px;
}
.fdj i{
font-size: 15px;
color:#6e6d6d;
width:15px;
margin:0 auto;
display: block;
line-height: 31px;
}
#tj{
width:31px;
height:31px;
border-radius:7px;
background: #dbd9d8;
position: absolute;
top:31px;
right:16px;
cursor: pointer;
}
#tj i{
font-size:14px;
color: #626262;;
width:14px;
display: block;
margin:0 auto;
line-height: 31px;
}
.lb{
width:100%;
height: 522px;
overflow: auto;
position: relative;
}
.lsdh li{
width:100%;
height:80px;
position: relative;
cursor: pointer;
background: #eae8e7;
}
.lxrtx{
width:50px;
height:50px;
background: #888;
position: absolute;
left:15px;
top:15px;
}
.lxrtx img{
width:100%;
}
.nc{
width:150px;
height:25px;
position: absolute;
left:75px;
top:20px;
}
.nc span{
font-size: 16px;
color:#333;
}
.sclt{
width:150px;
height:18px;
position: absolute;
left:75px;
top:40px;
}
.sclt span{
font-size:12px;
color:#666;
}
#dq{
background: #c3c3c3;
}
.sj{
width:30px;
height:20px;
position: absolute;
right:10px;
top:15px;
}
.sj span{
font-size: 12px;
color:#888;
}
.fs{
width:612px;
height: 100%;
background: #f5f5f5;
position: absolute;
right:0px;
}

/*滚动条样式*/
.lb::-webkit-scrollbar {/*滚动条整体样式*/
width: 4px;     /*高宽分别对应横竖滚动条的尺寸*/
height: 4px;
}
.lb::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
border-radius: 5px;
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
background: rgba(0,0,0,0.2);
}
.lb::-webkit-scrollbar-track {/*滚动条里面轨道*/
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
border-radius: 0;
background: rgba(0,0,0,0.1);
}
.fstop{
width:100%;
height:78px;
background: #f5f5f5;
border-bottom: 1px solid #e7e7e7;
}
.mz{
width: 130px;
height:30px;
position: relative;
top:35px;
left:38px;
}
.mz span{
font-size:18px;
font-weight: 500;
color:#333;
}
.sr{
width:100%;
height: 141px;
background: #fff;
position: absolute;
bottom:0px;
border-top:1px solid #ececec;
}
#srk{
width:572px;
height:80px;
position: absolute;
top:50px;
left:50%;
margin-left:-286px;
}
#dwb{
width:572px;
height:80px;
font-size:18px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
overflow: auto;
resize:none;
background: none;
border:none;
outline: none;
}
.fsxx{
position: absolute;
right:20px;
bottom: 20px;
}
.fsxx button{
width:85px;
height:33px;
color:#fff;
border: none;
outline: none;
background: #09bb07;
}
.zj-lsxx{
width:100%;
height:339px;
background:#f5f5f5;
overflow: auto;
}
.zjxx{
width:541px;
margin: 20px auto 30px;
}
.zjtx{
width:43px;
height:43px;
float:right;
}
.zjtx img{
width:100%;
}

.lsxx{
width:100%;
height:339px;
background:#f5f5f5;
overflow: auto;
}
.zjxx{
width:541px;
margin: 20px auto 30px;
}
.zjtx{
width:43px;
height:43px;
float:right;
}
.zjtx img{
width:100%;
}
.dmxx{
width:541px;
margin: 20px auto 30px;
}
.dmtx{
width:43px;
height:43px;
float:left;
}
.dmtx img{
width:100%;
}
.zjxxk{
max-width: 300px;
background: #9eea6a;
float:right;
margin-right:10px;
border-radius: 5px;
padding: 10px;
}
.zjxxk span{
white-space:normal;
word-break:break-all;
overflow:hidden;
line-height: 20px;
font-size:14px;
color:#333;
text-align: left;
}
.dmxxk{
max-width: 300px;
background: #fff;
float:left;
margin-left:10px;
border-radius: 2px;
padding: 6px;
}
.dmxxk span{
white-space:normal;
word-break:break-all;
overflow:hidden;
line-height: 20px;
font-size:14px;
color:#333;
text-align: left;
}
.lsxx::-webkit-scrollbar {/*滚动条整体样式*/
width: 4px;     /*高宽分别对应横竖滚动条的尺寸*/
height: 4px;
}
.lsxx::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
border-radius: 5px;
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
background: rgba(0,0,0,0.2);
}
.lsxx::-webkit-scrollbar-track {/*滚动条里面轨道*/
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
border-radius: 0;
background: rgba(0,0,0,0.1);
}
.picName {
width: 40;
height:40px;
border-radius:2px;
background:#47A1F8;
color:#fff;
font-weight:bold;
line-height:40px;
text-align:center;
font-size:23px;
}





评论