这里websocket的历史我就不说了。不要把websocket和长连接弄混了就行了。
Websocket是基于HTTP协议的,借用了HTTP的协议来完成一部分握手。
websocket握手
客户端到服务端:
GET / HTTP/1.1
Connection:Upgrade
Host:127.0.0.1:8088
Origin:null
Sec-WebSocket-Extensions:x-webkit-deflate-frame
Sec-WebSocket-Key:puVOuWb7rel6z2AVZBKnfw==
Sec-WebSocket-Version:13
Upgrade:websocket
服务端到客户端:
HTTP/1.1 101 Switching Protocols
Connection:Upgrade
Server:beetle websocket server
Upgrade:WebSocket
Date:Mon, 26 Nov 2013 23:42:44 GMT
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:content-type
Sec-WebSocket-Accept:FCKgUr8c7OsDsLFeJTWrJw6WO8Q=
经过一次HTTP请求,就可以做到源源不断的信息传送了。(在程序设计中,这种设计叫做回调,即:你有信息了再来通知我,而不是我傻乎乎的每次跑来问你)
这样的协议解决了上面同步有延迟,而且还非常消耗资源的这种情况。
- 长连接
ajax轮询(心跳多次询问) 和 long roll(阻塞式) 这两种方式都不如websocket
这里的io.socket就是集合了这几种方式
Adobe® Flash® Socket
AJAX long polling
AJAX multipart streaming
Forever Iframe
JSONP Polling
这边发下我自己用io.socket的代码
服务端:
var http = require('http');
var express = require('express');
var socket = require('socket.io');
var app = express();
var server = http.createServer(app);
var io = socket.listen(server);
server.listen(3000);
app.get('/', function(req, res) {
res.sendfile(__dirname + '/index.html');
});
var connectList = {};
io.sockets.on('connection', function(socket) {
var socketId = socket.id;
connectList[socketId] = {'socket': socket};
socket.on('join', function(data) {
connectList[socketId].userName = data.userName;
socket.broadcast.emit('broadcast_join', data);
});
socket.on('disconnect', function() {
if (connectList[socketId].userName) {
socket.broadcast.emit('broadcast_quit', {
'userName': connectList[socketId].userName
});
}
delete connectList[socketId];
});
socket.on('say', function(data) {
socket.broadcast.emit('boradcast_say', {
'userName': connectList[socketId].userName,
'text': data.text
});
})
})
客户端:
<!DOCTYE html>
<html>
<head><title></title></head>
<body>
<input type="text" id="txt" />
<input type="button" onClick="submitSay()" value="says" />
</body>
<script type="text/javascript" src="./UUID.js"></script>
<script type="text/javascript" src="http://localhost:3000/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io.connect('http://localhost:3000');
var userName = Math.uuid();
socket.emit('join', {'userName': userName});
socket.on('broadcast_join', function(data) {
console.log(data.userName + "joins room");
});
socket.on('broadcast_quit', function(data) {
console.log(data.userName + "leaves room");
});
socket.on('boradcast_say', function(data) {
console.log(data.userName + " says " + data.text);
});
function submitSay() {
var txt = document.getElementById('txt');
socket.emit('say', {"userName": userName, "text": 'hello everyone, I am ' + userName});
}
</script>
</html>
这里为了省事直接github上拿了别人实现的插件来实现socket。大概的思想就是这样。
比较详细的两篇文章
socket.io介绍
websocket介绍