一看就会的node聊天室案例,socket.io实现多人聊天

实例效果:

实例效果:

1 用户登录以后,进入群聊界面。顶部显示在线人数

2 每次有新用户进入以后,顶部在线人数加1,界面提示该用户加入群聊,离开时减1,界面提示该用户离开

同时小气泡显示进入来的用户名称

3 用户登录进入以后输入内容点击提交内容会在界面显示出来。并且显示发送人和发送的内容

项目结构:

-----  node_modules

------socket

         chart.html

-------chart.js

根目录下有一个chart.js文件。即为该demo启动的服务器文件

/socket/chart.html页面代码:

<!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>Document</title>

<style>

body{background: #f7f7f7;font-size: 14px;display:flex;justify-content: center;}

#fm1{width:30px;height: 200px;margin:70px auto }

#fm2{display: none;position: fixed;bottom: 10px;left:0;}

.joinTip{padding:10px;background: rgba(0,0,0,0.1);font-size: 12px;color:#000;width: 300px;border-radius: 9px;margin: 15px}

#container{margin-top: 80px;}

li{width: 60px;padding:10px;background: #d2a5e9;border-radius: 18px;float: left;margin-right:2px;color:#fff; }

ul{padding:10px;border-bottom:1px solid #ddd;margin-top: 50px;min-height: 100px}

#conts{height: 400px;overflow: auto}

#conts p{padding: 10px;border-radius: 18px;}

#conts p:nth-child(odd){text-align: left;background: #eee}

p:nth-child(even){text-align: right;background:#d0ed9c;}

</style>

<script src="/socket.io/socket.io.js"></script>

</head>

<body>

<div style="background: #000;position: fixed;top:0;left: 0;padding: 20px;width: 100%;color:#fff" >当前在线人数:<span id="num"></span></div>

<ul id="nicknames"></ul>

<form action="" id="fm1">

<input type="text" placeholder="请填写昵称" id="nickInput"/>

<input type="submit" value="提交"/>

</form>

<div id="container">

<div id="conts"></div>

</div>

<form action="" id="fm2">

<textarea name="" cols="30" rows="5" value="" id="msgInput"></textarea>

<input type="submit" value="提交"/>

</form>

</body>

<script>

window.οnlοad=function(){

var fm1=document.getElementById("fm1")

var fm2=document.getElementById("fm2")

var num=document.getElementById("num")

var container=document.getElementById("container")

var nickInput=document.getElementById("nickInput")

var msgInput=document.getElementById("msgInput")

var nickbox=document.getElementById("nicknames")

var msgbox=document.getElementById("conts")

var socket=io.connect("http://localhost:9999");

fm1.οnsubmit=function(e){

e.preventDefault();

socket.emit("nickname",nickInput.value,function(flag){

console.log("falg的值:",flag)

if(!flag){

var p=document.createElement("p");

p.innerHTML="该用户名已经存在";

document.body.appendChild(p);

}else{

fm1.style.display="none";

fm2.style.display="block";

}

})

}

fm2.οnsubmit=function(e){

e.preventDefault();

console.log("msg:",msgInput.value)

socket.emit("userMsg",msgInput.value);

msgInput.value="";

msgInput.focus()

}

 

socket.on("nicknames",function(data){

nicknames.innerHTML="";

console.log("nicknames-----data:",data)

var str="";

for(var i=0;i<data.nickArr.length;i++){

str+="<li>"+data.nickArr[i]+"</li>"

}

nickbox.innerHTML=str;

 

//设置加入/离开群聊的新成员

var newNode=document.createElement("div");

newNode.className="joinTip";

if(data.isLogin){

//加入群聊

newNode.innerHTML=data.name+"加入了群聊";

container.appendChild(newNode)

num.innerHTML=data.count

 

}else{

//离开群聊

newNode.innerHTML=data.name+"离开了群聊";

container.appendChild(newNode)

//显示当前在线人数

num.innerHTML=data.count

 

}

 

})

 

socket.on("userMsg",function(data){

console.log("客户端接收到的消息:",data)

// var str="<strong>"+data.nick+"</strong><span>"+data.msg+"</span>";

var p=document.createElement("p");

var span=document.createElement("span")

span.innerHTML=data.nick+":"+data.msg

p.appendChild(span);

msgbox.appendChild(p)

})

}

 

</script>

</html>

----------------------------------后端chart.js代码-----------------------------------------------

var fs=require("fs");

var http=require("http");

 

var server=http.createServer(function(req,res){

var stream=fs.createReadStream("./chart4.html");

stream.setEncoding("utf8");

stream.pipe(res)

}).listen(9999);

 

var count=0

var nickArr=[];

var io=require("socket.io").listen(server);

 

io.sockets.on("connection",function(socket){

socket.on("nickname",function(data,callback){

console.log("接收客户端nickname:",data)

if(nickArr.indexOf(data)!==-1){

console.log("false")

callback(false)

 

}else{

console.log("true")

count++;

callback(true);

socket.nickname=data;

nickArr.push(data);

io.sockets.emit("nicknames",{

nickArr:nickArr,

name: data ,

count:count,

isLogin:true

})

}

})

 

socket.on("userMsg",function(data){

console.log("服务端的usermsg:",data)

io.sockets.emit("userMsg",{

nick:socket.nickname,

msg:data

})

})

socket.on("disconnect",function(){

if(!socket.nickname){

return

}else{

nickArr.splice(nickArr.indexOf(socket.nickname),1);

count--;

console.log("退出以后count是:",count)

io.sockets.emit("nicknames",{

nickArr:nickArr,

name: socket.nickname ,

count:count,

isLogin:false

})

 

}

})

 

})

代码很简单。注意点如下:

1在用户离开和进入的时候,界面提示xx用户进入/离开,其实dom操作差不多,那么如何复用,如何判断当前用户是离开开始进入呢?我们在服务器的每次发送nicknames事件给前端的时候加一个isLogin字段,这样前端在接受的时候结可以通过该值进行判断

2在登录的时候。可能存在名称一致的情况,那如何规避这个问题,在服务器的nickname事件中,我们通过数组中是否存在用户输入的名称的方式来判断,确认是否存在之后通过传入一个回调函数,把true/false通过值传给客户端以后,在客户端的nickname事件中通过socket.emit("nickname",nickInput.value,function(flag){

  if(falg){

}else{

}

}来进行判断

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值