最近看到别人搭建了自己的实时聊天室便产生了兴趣,于是乎自己也着手搭建了一个。在socket这里我选用了socket.io这个模块,在网上看了很多的博客不过还是一头雾水,于是上了socket.io的官网看了下soket.io的各个内置函数以及事件。网址:https://socket.io/get-started/chat/
虽然是英文的,不过慢慢看还是能够看懂的,看懂归看懂,实操才是真理。下面是实现过程
准备工作
服务器与前端实时通信实现关键点:
//服务器端代码
//myserver.js
var app=require('express')();
var http=require('http').createServer(app);//将express框架注册到http服务器中
var io=require('socket.io')(http);//将http服务器注册到socket.io中,返回一个io对象,管控着所有的客户端与服务器的连接
var user=0; //统计用户数量
var ip={}; //用户ip
var content=""; //保存用户发送的消息内容,这里可以保存到数据库中
app.get('/',(req,res)=>{
res.sendFile(__dirname+'/myclient.html');//将当前目录下的客户端文件发送到浏览器
})
http.listen(8080,function () {//监听8080端口
console.log('listening 8080')
})
io.on('connection',(socket)=>{ //监听用户连接,并返回一个socket对象(服务器与当前连接用户的socket对象)
socket.emit('id',socket.id.toString().slice(0,5)); //获取用户id的前5位
user++; //连接上socket用户+1
var tem=socket.handshake.headers['x-forwarded-for'];//ip地
if(ip[tem]==undefined){ //ip中如果不存在tem这个ip地址会返回undefined
ip[tem]=1; //不存在则将tem这个键保存在ip中
console.log('新用户',tem); //控制台输出新用户+ip地址
}
else{ //存在则将消息全部发送到当前的客户端
console.log('旧用户',tem); //控制台输出新用户+ip地址
socket.emit('init',content); //把之前的聊天记录发送
}
console.log('a user connected') //服务器 控制台输出 a user connected
socket.on('disconnect',()=>{ //监听当前用户与服务器的是否失去连接
console.log('断开连接') //服务器 控制台输出 断开连接
user--; //用户数-1
})
socket.on('sendMsg',function(msg) {//监听当前用户是否向服务器发送消息,事件触发回调一个msg的参数
console.log(msg) //显示用户发送过来的消息
content=content+msg+'
';//保存用户发送过的消息
io.emit('sendMsg', msg); //服务器将当前用户发送过来的消息广播到所有的客户端
})
io.emit('user',user); //服务器将当前用户数量广播到所有的客户端
})
前端代码
//html+jQuery
<!doctype html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/><!--使页面适应手机界面>
<meta charset="UTF-8">
<title>聊天室</title>
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css"><!--引入boostrap框架css文件-->
</head>
<body>
<style type="text/css">
.msgs{
}
<!--这里是消息的样式,暂时不需要-->
</style>
<div >
<div id='user' class="text-center" ></div>
<form style="">
<label></label>
<div class="col-xs-12 col-md-12">
<div id="textarea"style="width:100vw;height:100vw;border:3px solid #000;overflow-y:scroll; overflow-x:scroll;" ></div>
</div> <!--div显示框,overflow实现了滚动条的功能-->
<div >
<div class="col-xs-12 col-md-12 center-block">
<input id="text1" type="text" value="" style="width:100%;height:30px;" onkeydown="return ClearSubmit(event)"/>
</div><!--这里的input由于是在表单标签内,在输入时直接按回车会自动提交表单并刷新,ClearSubmit函数监听回车键,并屏蔽掉-->
<div class="col-xs-12 col-md-12 center-block">
<button type="button" onclick="sendMsg();" style="width:100%;height:30px;"class="btn btn-primary "><i class="fa fa-paper-plane">send<i></button></div>
</div>
</form>
</div>
<script src="/socket.io/socket.io.js"></script><!--socket.io模块-->
<script src="https://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script> <!--jQuery文件,使用bootstrap框架要用到,并且需要放在Bootstrap文件上面-->
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script><!--bootstrap文件,相关使用教程可百度-->
<script type="text/javascript">
var socket = io(); //获取socket对象
var userid=false; //userid 用于识别用户
var div = document.getElementById('textarea');
div.scrollTop = div.scrollHeight;////实现页面初始化滚动条自动跑到底部的效果
socket.on('sendMsg',function(msg){ //监听服务器发送消息事件,这里的sendMsg是可以自定义的,只要有相关的事件触发器和监听器就可以
console.log(msg)//浏览器控制台输出服务器发来的消息
})
socket.on('id',function (id) { //监听服务器发送用户id
userid=id;
})
socket.on('user',function (user) { //监听服务器发送用户的在线人数,这里的在线人数只是简单的客户端数,但一个ip可以同时打开多个客户端,真正的在线人数应当是ip数,当然考虑到局域网下用户公用同一个ip问题,可以做一个注册页面来解决这些问题
document.getElementById('user').innerHTML="本聊天室在线人数:"
+user+'';//原生js改变DOM的内容
})
function sendMsg () {//发送消息按钮会触发该函数
var msg=document.getElementById('text1');
var date=new Date();
socket.emit('sendMsg','('+date.getHours()+':'+date.getMinutes()+':'+date.getSeconds()+')'+"用户"+userid+'>>> '+msg.value)
}//触发sendMsg事件,将消息发送到服务器端
//var flag=false;
socket.on('init',function(msg){ //该事件在用户打开页面时将已有消息发送到客户端
var tem=$('').text(msg);//以msg为内容创建一个div标签
$('#textarea').append(tem);//将该div标签插入到id=textaread的容器中
tem[0].innerHTML=msg;//改变该div标签的内容
//console.log('这是新增的对象',tem[0].innerHTML);
});
socket.on('sendMsg', function(msg){ //监听服务器发送来的消息
var tem=$('').text(msg);
tem.addClass('msgs')
$('#textarea').append(tem);
var div = document.getElementById('textarea');
div.scrollTop = div.scrollHeight;//实现发送消息滚动条自动跑到底部的效果
});
function ClearSubmit(e){//屏蔽回车键
if(e.keyCode==13){
return false;
}
}
</script>
</body>
</html>
代码写好后就可以布置到自己的服务器上了,或者在本机也ok
效果网址
http://wocnz.club:8080
第一次写这么多字的博客,如果本文对你有帮助的话还请点赞支持一下。
另外如果哪里有错误的话还请各位大佬指出来,互相学习。