<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(&#39;http&#39;), url=require(&#39;url&#39;), fs=require(&#39;fs&#39;), server; server=http.createServer(function(req,res){ //yournormalservercode varpath=url.parse(req.url).pathname; switch(path){ case&#39;/&#39;: res.writeHead(200,{&#39;Content-Type&#39;:&#39;text/html&#39;}); res.write(&#39;&lt;h1&gt;Hello!Trythe&lt;ahref=&quot;/index.html&quot;&gt;Socket.ioTest&lt;/a&gt;&lt;/h1&gt;&#39;); res.end(); break; case&#39;/index.html&#39;: fs.readFile(__dirname+path,function(err,data){ if(err)returnsend404(res); res.writeHead(200,{&#39;Content-Type&#39;:path==&#39;json.js&#39;?&#39;text/javascript&#39;:&#39;text/html&#39;}) res.write(data,&#39;utf8&#39;); res.end(); }); break; default:send404(res); } }), send404=function(res){ res.writeHead(404); res.write(&#39;404&#39;); res.end(); }; server.listen(8080); vario=require(&#39;socket.io&#39;).listen(server); io.sockets.on(&#39;connection&#39;,function(socket){ console.log(&quot;Connection&quot;+socket.id+&quot;accepted.&quot;); socket.on(&#39;message&#39;,function(message){ console.log(&quot;Receivedmessage:&quot;+message+&quot;-fromclient&quot;+socket.id); }); socket.on(&#39;disconnect&#39;,function(){ console.log(&quot;Connection&quot;+socket.id+&quot;terminated.&quot;); }); });</pre><p>客户端编程模型</p><p>客户端编程也是相似的处理方式,连接服务器,交互信息。比如下面的index.html页面:</p><pre class="brush:html;toolbar:false">&lt;!doctypehtml&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;Socket.ioTest&lt;/title&gt; &lt;scriptsrc=&quot;/json.js&quot;&gt;&lt;/script&gt;&lt;!--forie--&gt; &lt;scriptsrc=&quot;/socket.io/socket.io.js&quot;&gt;&lt;/script&gt; &lt;/head&gt; &lt;body&gt; &lt;script&gt; varsocket; varfirstconnect=true; functionconnect(){ if(firstconnect){ socket=io.connect(null); socket.on(&#39;message&#39;,function(data){message(data);}); socket.on(&#39;connect&#39;,function(){status_update(&quot;ConnectedtoServer&quot;);}); socket.on(&#39;disconnect&#39;,function(){status_update(&quot;DisconnectedfromServer&quot;);}); socket.on(&#39;reconnect&#39;,function(){status_update(&quot;ReconnectedtoServer&quot;);}); socket.on(&#39;reconnecting&#39;,function(nextRetry){status_update(&quot;Reconnectingin&quot; +nextRetry+&quot;seconds&quot;);}); socket.on(&#39;reconnect_failed&#39;,function(){message(&quot;ReconnectFailed&quot;);}); firstconnect=false; }else{ socket.socket.reconnect(); } } functiondisconnect(){ socket.disconnect(); } functionmessage(data){ document.getElementById(&#39;message&#39;).innerHTML=&quot;Serversays:&quot;+data; } functionstatus_update(txt){ document.getElementById(&#39;status&#39;).innerHTML=txt; } functionesc(msg){ returnmsg.replace(/&lt;/g,&#39;&lt;&#39;).replace(/&gt;/g,&#39;&gt;&#39;); } functionsend(){ socket.send(&quot;HelloServer!&quot;); }; &lt;/script&gt; &lt;h1&gt;Socket.ioTest&lt;/h1&gt; &lt;div&gt;&lt;pid=&quot;status&quot;&gt;Waitingforinput&lt;/p&gt;&lt;/div&gt; &lt;div&gt;&lt;pid=&quot;message&quot;&gt;&lt;/p&gt;&lt;/div&gt; &lt;buttonid=&quot;connect&quot;onClick=&#39;connect()&#39;/&gt;Connect&lt;/button&gt; &lt;buttonid=&quot;disconnect&quot;onClick=&#39;disconnect()&#39;&gt;Disconnect&lt;/button&gt; &lt;buttonid=&quot;send&quot;onClick=&#39;send()&#39;/&gt;SendMessage&lt;/button&gt; &lt;/body&gt; &lt;/html&gt;</pre><p></p><p>1. 启动服务器还是交给node,打开命令行窗口,定位到server.js所在文件夹,输入node server.js启动服务器。</p><p> 在上面的index.html中,注意这行:&lt;script src=&quot;/socket.io/socket.io.js&quot;&gt;&lt;/script&gt;。如果不想使用本地的socket.io脚本,可以直接使用下面这个公开的脚本:</p><p>&lt;script src=&quot;http://cdn.socket.io/stable/socket.io.js&quot;&gt;&lt;/script&gt;</p><p>此外需要注意这行:socket = io.connect(null)。这里的null代表连接本地服务,可以换成&quot;localhost&quot;,效果也是一样的。</p><p>2. 可以使用socket.io直接启动http服务。例如:</p><pre class="brush:js;toolbar:false">vario=require(&#39;socket.io&#39;).listen(80); io.sockets.on(&#39;connection&#39;,function(socket){ io.sockets.emit(&#39;this&#39;,{will:&#39;bereceivedbyeveryone&#39;}); });</pre><p>3. socket.io可以直接通过send方法发送消息,使用message事件接收消息,例如:</p><pre class="brush:js;toolbar:false">//server.js vario=require(&#39;socket.io&#39;).listen(80); io.sockets.on(&#39;connection&#39;,function(socket){ socket.on(&#39;message&#39;,function(){}); }); //index.html &lt;script&gt; varsocket=io.connect(&#39;http://localhost/&#39;); socket.on(&#39;connect&#39;,function(){ socket.send(&#39;hi&#39;); socket.on(&#39;message&#39;,function(msg){ //mymsg }); }); &lt;/script&gt;</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(&#39;connection&#39;,function(socket){ socket.emit(&#39;news&#39;,{hello:&#39;world&#39;}); socket.on(&#39;myotherevent&#39;,function(data){ console.log(data); }); });</pre><p></p><p>//客户端:</p><pre class="brush:js;toolbar:false">&lt;scriptsrc=&quot;/socket.io/socket.io.js&quot;&gt;&lt;/script&gt; &lt;script&gt; varsocket=io.connect(&#39;http://localhost&#39;); socket.on(&#39;news&#39;,function(data){ console.log(data); socket.emit(&#39;myotherevent&#39;,{my:&#39;data&#39;}); }); &lt;/script&gt;</pre><p>5. 从上面可以看出来,发送数据的时候,send和emit是都可以使用的。只不过emit更是强化了自定义事件的处理。</p><p>6. 可以在服务端使用socket的get/set方法存储客服端的相关数据,例如:</p><p>//服务端</p><pre class="brush:js;toolbar:false">vario=require(&#39;socket.io&#39;).listen(80); io.sockets.on(&#39;connection&#39;,function(socket){ socket.on(&#39;setnickname&#39;,function(name){ socket.set(&#39;nickname&#39;,name,function(){socket.emit(&#39;ready&#39;);}); }); socket.on(&#39;msg&#39;,function(){ socket.get(&#39;nickname&#39;,function(err,name){ console.log(&#39;Chatmessageby&#39;,name); }); }); });</pre><p>//客户端</p><pre class="brush:js;toolbar:false">&lt;script&gt; varsocket=io.connect(&#39;http://localhost&#39;); socket.on(&#39;connect&#39;,function(){ socket.emit(&#39;setnickname&#39;,confirm(&#39;Whatisyournickname?&#39;)); socket.on(&#39;ready&#39;,function(){ console.log(&#39;Connected!&#39;); socket.emit(&#39;msg&#39;,confirm(&#39;Whatisyourmessage?&#39;)); }); }); &lt;/script&gt;</pre>
返回顶部 留言