websocket
实现聊天室一般是用长连接的方式实现,而不用轮询。轮询每次请求都要额外消耗资源,并且做不到瞬时聊天(除非轮询时间间隔很短)。
websocket是一种长连接,双工通信(客户端可向服务端发送消息。服务端可向客户端发送消息,这是ajax做不到的。)
node的socket.io模块
这次构建我所用的是socket.io模块,非原生socket,是一种socket的框架。为什么不用原生socket?因为原生socket过于复杂,没有特殊需求经量用框架吧,下面上传一下原生socket构建的简单过程 :
图1.原生socket1
图2.原生socket
所用模块安装命令 : cnpm i socket.io -D
也可全局安装,自己选择吧。
node.js代码
```node.js
const io = require('socket.io');
const http = require('http');
//socket是长连接,借助http协议
//可以主动给浏览器发信息;
let server = http.createServer((req,res)=>{
})
server.listen(8080);//端口号为8080 ,什么都行,一般是80或8080
let wsServer = io.listen(server);
let socketList = [];
wsServer.on('connection',sock=>{//每次有连接都会回调这个函数
console.log(socketList.length);
socketList.push(sock);
sock.on('msg',(str)=>{//每次有消息都会回调这个函数,这个msg是这个消息的名字,和前端商量好,什么都行,abc什么的。
socketList.forEach(s=>{
if(s!=sock){ //给其他人发送消息,不用发给自己;
s.emit('msg',str);
}
})
})
sock.on('disconnect',()=>{
//因为连接在浏览器关闭之后,不会自动断开,要靠服务器自己断开。
let n = socketList.indexOf(sock);
if(n!=-1){
socketList.splice(n,1);
}
})
})
运行服务端:
html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
</style>
<script src="http://localhost:8080/socket.io/socket.io.js" charset="utf-8"></script>
<script>
//上面的script用于引入socket库的js,skocket.io自带;
let sock = io.connect('ws://localhost:8080/');
// sock.emit('名字',参数列表);
// sock.on('名字',回调函数);
window.onload = function(){
let input = document.getElementById("text");
let btn = document.getElementById("btn");
let oul = document.getElementById("oul");
let errBox= document.getElementById("errBox");
let p;
sock.on('msg',(str)=>{//这里于后台的msg对应
p = document.createElement('li');
p.appendChild(document.createTextNode(str));
oul.appendChild(p);
})
sock.on('connect',()=>{
console.log("已连接");
console.log(errBox.style.display)
errBox.style.display = "none";
btn.onclick = function(){
if(input.value != ' '&&input.value != undefined)
{
p = document.createElement('li');
p.appendChild(document.createTextNode(input.value));
p.style.color = 'red';
oul.appendChild(p);
sock.emit('msg',input.value);//这里于后台的msg对应
}else{
alert("不能发送空消息");
}
}
})
sock.on('disconnect',()=>{
errBox.style.display = "block";
console.log("已断开");
btn.onclick = function(){
alert("发送失败,连接已经断开");
}
})
}
</script>
</head>
<body>
<div id="errBox" style="height: 20px;line-height: 20px;width: 100%;color: red;display: block;">
websocket连接失败,请检查网络.
</div>
<ul id="oul" style="height: 300px;width: 500px;border: 1px solid black;">
</ul>
<textarea id="text" cols="60" rows="4" ></textarea>
<input type="button" id="btn" value="提交" />
</body>
</html>
结果: