update(\"data\")”这样⼀个字符串,意味着以data为参数调⽤客户端update函数进⾏客户端view更新。基本模型如下所⽰:可以看到comet技术是针对客户端请求服务器响应模型⽽模拟出的⼀个服务端推送数据实时更新技术。⽽且由于浏览器兼容性不能够⼴泛应⽤。
可以看到comet技术是针对客户端请求服务器响应模型⽽模拟出的⼀个服务端推送数据实时更新技术。⽽且由于浏览器兼容性不能够⼴泛应⽤。
当然并不是说这些技术没有⽤,就算websocket已经作为规范被提出并实现,但是对于⽼式浏览器,我们依然需要将它降级为以上⽅式来实现实时交互和服务端数据推送。到此为⽌,我们明⽩了websocket的原理,下⾯通过⼀个简单的聊天应⽤来再次加深下对websocket的理解。该应⽤需求很简单,就是在web选项卡中打开两个⽹页,模拟两个web客户端实现聊天功能。⾸先是客户端如下:client.html
    
客户端js代码
var oUl=document.getElementById('content');
var oConnect=document.getElementById('connect');    var oSend=document.getElementById('send');    var oInput=document.getElementById('message');    var ws=null;
oConnect.onclick=function(){
ws=new WebSocket('ws://localhost:5000');         ws.onopen=function(){
oUl.innerHTML+=\"
客户端已连接\";         }ws.onmessage=function(evt){
oUl.innerHTML+=\"
\"+evt.data+\"\";        }ws.onclose=function(){
oUl.innerHTML+=\"
客户端已断开连接\";        };ws.onerror=function(evt){
oUl.innerHTML+=\"
\"+evt.data+\"\";        };    };oSend.onclick=function(){        if(ws){
ws.send(oInput.value);        }    }
这⾥使⽤的是w3c规范中关于HTML5 websocket API的原⽣API,这些api很简单,就是利⽤new WebSocket创建⼀个指定连接服务端地址的ws实例,然后为该实例注册onopen(连接服务端),onmessage(接受服务端数据),onclose(关闭连接)以及ws.send(建⽴连接后)发送请求。上⾯说了那么多,事实上可以看到html5 websocket API本⾝是很简单的⼀个对象和它的⼏个⽅法⽽已。
服务端采⽤nodejs,这⾥需要基于⼀个nodejs-websocket的nodejs服务端的库,它是⼀个轻量级的nodejs websocket server端的实现,实际上也是使⽤nodejs提供的net模块写成的。server.js
var app=require('http').createServer(handler);var ws=require('nodejs-websocket');var fs=require('fs');app.listen(80);
function handler(req,res){
fs.readFile(__dirname+'/client.html',function(err,data){        if(err){
res.writeHead(500);            return res.end('error ');        }
res.writeHead(200);        res.end(data);    });}
var server=ws.createServer(function(conn){    console.log('new conneciton');    conn.on(\"text\        broadcast(server,str);    });
conn.on(\"close\        console.log('connection closed');    })
}).listen(5000);
function broadcast(server, msg) {
server.connections.forEach(function (conn) {        conn.sendText(msg);    })}
⾸先利⽤http模块监听⽤户的http请求并显⽰client.html界⾯,然后创建⼀个websocket服务端等待⽤户连接,在接收到⽤户发送来的数据之后将它⼴播到所有连接到的客户端。下⾯我们打开两个浏览器选项卡模拟两个客户端进⾏连接,客户端⼀连接:
请求响应报⽂如下:
可以看到这次握⼿和我们之前讲的如出⼀辙,
客户端⼆的连接过程和1是⼀样的,这⾥为了查看我们使⽤ff浏览器,两个客户端的连接情况如下:
发送消息情况如下:
可以看到,双⽅发送的消息被服务端⼴播给了每个和⾃⼰连接的客户端。
从以上我们可以看到,要想做⼀个点对点的im应⽤,websocket采取的⽅式是让所有客户端连接服务端,服务器将不同客户端发送给⾃⼰的消息进⾏转发或者⼴播,⽽对于原始的socket,只要两端建⽴连接之后,就可以发送端对端的数据,不需要经过第三⽅的转发,这也是websocket不同于socket的⼀个重要特点。
最后,本⽂为了说明html5规范中的websocket在客户端采⽤了原⽣的API,实际开发中,有⽐较著名的两个库socket.io和sockjs,它们都对原始的API做了进⼀步封装,提供了更多功能,都分为客户端和服务端的实现,实际应⽤中,可以选择使⽤。