Socket.IO介绍
Socket.io是一个跨浏览器支持WebSocket的实时通讯的JS。它不仅简化了接口,使得操作更容易,而且对于那些不支持WebSocket的浏览器,会自动降为Ajax连接,最大限度地保证了兼容性。它的目标是统一通信机制,使得所有浏览器和移动设备都可以进行实时通信。
Socket.io实际上是WebSocket的父集,Socket.io封装了WebSocket和轮询等方法,会根据情况选择方法来进行通讯。
Socket.io将WebSocket和Polling机制以及其它的实时通信方式封装成通用的接口,并在服务端实现了这些实时机制相应代码。这就是说,WebSocket仅仅是Socket.io实现实时通信的一个子集,那么Socket.io都实现了Polling中那些通信机制呢?
Adobe Flash Socket
大部分PC浏览器都支持的Socket模式,不过是通过第三方嵌入到浏览器,不在W3C规范内,可能将逐步被淘汰。况且,大部分手机浏览器并不支持此种模式。
AJAX Long Polling
定时向服务端发送请求,缺点是给服务端带来压力并出现信息更新不及时的现象。
AJAX multipart streaming
在XMLHttpRequest对象上使用某些浏览器支持的multi-part标志,AJAX请求被发送给服务端并保持打开状态(挂起状态),每次需要向客户端发送信息,就寻找一个挂起的HTTP请求响应给客户端,并且所有的响应都会通过统一连接来写入。
Forever Iframem
永存的Iframe设计了一个置于页面中隐藏的iframe标签,该标签的src属性指向返回服务端时间的Servlet路径。每次在事件到达时,Servlet写入并刷新一个新的Script标签,该标签内部带有JS代码,iframe的内容被附加上script标签,标签中的内容就会得到执行。这种方式的缺点是接收数据都是由浏览器通过HTML标签来处理的,因此无法知道连接何时在哪一端被断开,而且iframe标签在浏览器中将被逐步取消。
JSONP Polling
JSONP轮询基本与HTTP轮询一样,不同之处则是JSONP可发出跨域请求
聊天室实现
服务器端:
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(8080);
app.get('/chat3',(req,res) => {
res.sendFile(__dirname + '/www/chat3.html')
})
app.get('/chat4',(req,res) => {
res.sendFile(__dirname + '/www/chat4.html')
})
io.on('connection', (socket) => {
console.log('客户端与服务端连接成功')
//监听客户端的消息
socket.on('message',(data) => {
console.log(data)
//将信息发给每个人
io.emit('message',data);
})
//断开连接
socket.on('disconnect', () => {
console.log('连接已断开...');
});
})
客户端:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="http://static.wanlianjin.com/data/m/wlcs/js/nocar/jquery-1.7.2.min.js" type="text/javascript" charset="utf-8"></script>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<ul id="messages"></ul>
<input id="m" autocomplete="off" /><button>Send</button>
<script>
var socket = io();
$('button').click(() => {
//发送消息
socket.emit('message',{'messages':'小明'+$('#m').val()});
$('#m').val('')
})
//接收消息
socket.on('message', (data) => {
console.log(data)
$('#messages').append('<li>'+ data.messages +'</li>')
})
</script>
</body>
</html>