<p>为什么需要socket.io?</p><p> node.js提供了高效的服务端运行环境,但是由于浏览器端对HTML5的支持不一,为了兼容所有浏览器,提供卓越的实时的用户体验,并且为程序员提供客户端与服务端一致的编程体验,于是socket.io诞生。</p><p> socket.io设计的目标是支持任何的浏览器,任何Mobile设备。目前支持主流的PC浏览器 (IE,Safari,Chrome,Firefox,Opera等),Mobile浏览器(iphone Safari/ipad Safari/android WebKit/WebOS WebKit等)。socket.io基于node.js并简化了WebSocket API,统一了通信的API。它支持:WebSocket, Flash Socket, AJAX long-polling, AJAX multipart streaming, Forever IFrame, JSONP polling。</p><p> socket.io解决了实时的通信问题,并统一了服务端与客户端的编程方式。启动了socket以后,就像建立了一条客户端与服务端的管道,两边可以互通有无。</p><p>安装</p><p>在命令行中执行:npm install socket.io 即可安装。</p><p>服务端编程模型</p><p>服务端编程还是与普通服务器一样,启动服务器,提供服务,处理事件。比如下面的server.js:</p><pre class="brush:js;toolbar:false">varhttp=require('http'),
url=require('url'),
fs=require('fs'),
server;
server=http.createServer(function(req,res){
//yournormalservercode
varpath=url.parse(req.url).pathname;
switch(path){
case'/':
res.writeHead(200,{'Content-Type':'text/html'});
res.write('<h1>Hello!Trythe<ahref="/index.html">Socket.ioTest</a></h1>');
res.end();
break;
case'/index.html':
fs.readFile(__dirname+path,function(err,data){
if(err)returnsend404(res);
res.writeHead(200,{'Content-Type':path=='json.js'?'text/javascript':'text/html'})
res.write(data,'utf8');
res.end();
});
break;
default:send404(res);
}
}),
send404=function(res){
res.writeHead(404);
res.write('404');
res.end();
};
server.listen(8080);
vario=require('socket.io').listen(server);
io.sockets.on('connection',function(socket){
console.log("Connection"+socket.id+"accepted.");
socket.on('message',function(message){
console.log("Receivedmessage:"+message+"-fromclient"+socket.id);
});
socket.on('disconnect',function(){
console.log("Connection"+socket.id+"terminated.");
});
});</pre><p>客户端编程模型</p><p>客户端编程也是相似的处理方式,连接服务器,交互信息。比如下面的index.html页面:</p><pre class="brush:html;toolbar:false"><!doctypehtml>
<html>
<head>
<title>Socket.ioTest</title>
<scriptsrc="/json.js"></script><!--forie-->
<scriptsrc="/socket.io/socket.io.js"></script>
</head>
<body>
<script>
varsocket;
varfirstconnect=true;
functionconnect(){
if(firstconnect){
socket=io.connect(null);
socket.on('message',function(data){message(data);});
socket.on('connect',function(){status_update("ConnectedtoServer");});
socket.on('disconnect',function(){status_update("DisconnectedfromServer");});
socket.on('reconnect',function(){status_update("ReconnectedtoServer");});
socket.on('reconnecting',function(nextRetry){status_update("Reconnectingin"
+nextRetry+"seconds");});
socket.on('reconnect_failed',function(){message("ReconnectFailed");});
firstconnect=false;
}else{
socket.socket.reconnect();
}
}
functiondisconnect(){
socket.disconnect();
}
functionmessage(data){
document.getElementById('message').innerHTML="Serversays:"+data;
}
functionstatus_update(txt){
document.getElementById('status').innerHTML=txt;
}
functionesc(msg){
returnmsg.replace(/</g,'<').replace(/>/g,'>');
}
functionsend(){
socket.send("HelloServer!");
};
</script>
<h1>Socket.ioTest</h1>
<div><pid="status">Waitingforinput</p></div>
<div><pid="message"></p></div>
<buttonid="connect"onClick='connect()'/>Connect</button>
<buttonid="disconnect"onClick='disconnect()'>Disconnect</button>
<buttonid="send"onClick='send()'/>SendMessage</button>
</body>
</html></pre><p></p><p>1. 启动服务器还是交给node,打开命令行窗口,定位到server.js所在文件夹,输入node server.js启动服务器。</p><p> 在上面的index.html中,注意这行:<script src="/socket.io/socket.io.js"></script>。如果不想使用本地的socket.io脚本,可以直接使用下面这个公开的脚本:</p><p><script src="http://cdn.socket.io/stable/socket.io.js"></script></p><p>此外需要注意这行:socket = io.connect(null)。这里的null代表连接本地服务,可以换成"localhost",效果也是一样的。</p><p>2. 可以使用socket.io直接启动http服务。例如:</p><pre class="brush:js;toolbar:false">vario=require('socket.io').listen(80);
io.sockets.on('connection',function(socket){
io.sockets.emit('this',{will:'bereceivedbyeveryone'});
});</pre><p>3. socket.io可以直接通过send方法发送消息,使用message事件接收消息,例如:</p><pre class="brush:js;toolbar:false">//server.js
vario=require('socket.io').listen(80);
io.sockets.on('connection',function(socket){
socket.on('message',function(){});
});
//index.html
<script>
varsocket=io.connect('http://localhost/');
socket.on('connect',function(){
socket.send('hi');
socket.on('message',function(msg){
//mymsg
});
});
</script></pre><p>4. 发送和处理数据</p><p> 两端可以互发事件,互发数据,相互通信。发送事件的代码为:socket.emit(action, data, function),其中action为事件的名称,data为数据,function为回调函数;处理事件代码 为:socket.on(action,function),如果emit发送的时候有数据data,则function中参数包含了这个数据。 socket.io除了发送和处理内置事件,如connect, disconnect, message。还允许发送和处理自定义事件,例如:</p><p>//服务端:</p><pre class="brush:js;toolbar:false">io.sockets.on('connection',function(socket){
socket.emit('news',{hello:'world'});
socket.on('myotherevent',function(data){
console.log(data);
});
});</pre><p></p><p>//客户端:</p><pre class="brush:js;toolbar:false"><scriptsrc="/socket.io/socket.io.js"></script>
<script>
varsocket=io.connect('http://localhost');
socket.on('news',function(data){
console.log(data);
socket.emit('myotherevent',{my:'data'});
});
</script></pre><p>5. 从上面可以看出来,发送数据的时候,send和emit是都可以使用的。只不过emit更是强化了自定义事件的处理。</p><p>6. 可以在服务端使用socket的get/set方法存储客服端的相关数据,例如:</p><p>//服务端</p><pre class="brush:js;toolbar:false">vario=require('socket.io').listen(80);
io.sockets.on('connection',function(socket){
socket.on('setnickname',function(name){
socket.set('nickname',name,function(){socket.emit('ready');});
});
socket.on('msg',function(){
socket.get('nickname',function(err,name){
console.log('Chatmessageby',name);
});
});
});</pre><p>//客户端</p><pre class="brush:js;toolbar:false"><script>
varsocket=io.connect('http://localhost');
socket.on('connect',function(){
socket.emit('setnickname',confirm('Whatisyournickname?'));
socket.on('ready',function(){
console.log('Connected!');
socket.emit('msg',confirm('Whatisyourmessage?'));
});
});
</script></pre>