在html5之前,web的設計上並無考慮過動態,他一直是圍繞着文檔設計的,咱們看之前比較老的網站,基本上都是某一刻用來顯示單一的文檔的,用戶請求一次web頁面,獲取一個頁面,可是隨着時間的推移,人們想要web作更多的事情了,而不是簡單的要顯示文檔,而JavaScript一直處於開發人員推進web頁面功能的發展中心。
Ajax無疑是動態Web頁面的一個重大發展,他再也不須要咱們即便更新一點內容,也須要刷新整個頁面了,可是有些方面,又體現了他的不足。若是從服務器請求數據,他當然號,可是若是服務器想要將數據推送到瀏覽器呢。Ajax技術沒法很容易的支持將數據推送到客戶,雖然能夠,可是須要跨國不少的障礙才行,並且不一樣的瀏覽器工做方式也不一樣,例如IE和FireBox他們的內核就不同,從而工做方式也不同。
WebSocket是在對服務器和客戶端之間實現雙向通訊問題的相應。他的思想是,從頭開始,設計一個開發人員可使用的標準以便以一直的方式建立應用程序,而不是經過複雜的,並不總能設置全部瀏覽器的工做。他的思想是Web服務器和瀏覽器之間保持持久打開,這就使得不論是服務器仍是瀏覽器均可以在想要的時候推送數據。由於鏈接是持久的,因此數據的交換很是的快,也就成了實時的了。javascript
說了那麼多,咱們介紹一下正主,Socket.IO是Node.js的一個模塊,他提供經過WebSocket進行通訊的一種簡單方式,WebSocket協議很複雜,可是Socket.IO提供了服務器和客戶端雙方的組件,因此只須要一個模塊就能夠給應用程序加入對WebSocket的支持。並且還能支持不一樣的瀏覽器。html
Socket.IO既能在服務端也能在客戶端工做,要使用它,必須將其添加到服務器端的JavaScript(Node.js)和客戶端的JavaScript(jQuery)中,這是覺得內通訊一般是雙向的,因此Sokcet.IO須要能在兩邊工做。html5
var server = http.createServer(function (req,res){ fs.readFile('./index.html',function(error,data){ res.writeHead(200,{'Content-Type':'text/html'}); res.end(data,'utf-8'); }); }).listen(3000,"127.0.0.1"); console.log('Server running at http://127.0.0.1:3000/');
並且必須將Socket.IO庫包含起來,才能加入Socket.IO的功能。java
var io = require('socket.io').listen(server);
而後加入一個事件來響應客戶端究竟是鏈接了,仍是斷開了。事件以下:node
io.sockets.on('connection',function(socket){ console.log('User connected'); socket.on('disconnect',function(){ console.log('User disconnected'); }); });
是否是以爲很是的簡單,下面咱們看一下完整的代碼實現是如何實現的吧:jquery
新建文件夾socket.io,在該文件夾下新建app.js,寫以下代碼:web
var http = require('http'); var fs = require('fs'); var server = http.createServer(function (req,res){ fs.readFile('./index.html',function(error,data){ res.writeHead(200,{'Content-Type':'text/html'}); res.end(data,'utf-8'); }); }).listen(3000,"127.0.0.1"); console.log('Server running at http://127.0.0.1:3000/'); var io = require('socket.io').listen(server); io.sockets.on('connection',function(socket){ console.log('User connected'); socket.on('disconnect',function(){ console.log('User disconnected'); }); });
新建index.html文件,代碼以下:npm
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Socket.IO Example</title> </head> <body> <h1>Socket.IO Example</h1> <script src="/socket.io/socket.io.js"></script> <script> var socket = io.connect('http://127.0.0.1:3000'); </script> </body> </html>
新建package.json來引入模塊。json
{
"name":"socketio_example", "version":"4.13.2", "private":true, "dependencies":{ "socket.io":"1.4.5" } }
版本號你們能夠輸入本身的nodejs -V,或者socket.io -v來查看本身的版本號。瀏覽器
若是你們沒有安裝Socket.IO,能夠運行以下代碼,若是安裝了,自動跳過這一步。 npm install socket.io
從終端運行以下命令安裝模塊 npm install
運行以下命令啓動服務器 node app.js
打開瀏覽器,輸入http://127.0.0.1:3000/,多打開幾個頁籤,都輸入該網址,再任意關閉一個頁籤,而後看看咱們的cmd命令窗口是否是以下:
這裏會詳細的記錄又多少個用於鏈接了,也有多少個用戶斷開鏈接了,這樣就能統計咱們網頁的訪問量了。
上邊的實例咱們已經實現了鏈接或者斷開服務器作記錄了,可是咱們要是想要推送消息怎麼辦,例如咱們好友的QQ上線了,騰訊都會咳嗽一下來提醒咱們有好友上線。下面咱們來作一下這個功能功能。
io.sockets.on('connection',function(socket){ socket.emit('message',{text:'你上線了'}); });
io.sockets.on('connection',function(socket){ socket.broadcast.emit('message',{'你的好某XXX上線了'}); });
不管是發送給單個用戶仍是全部用戶,這個message是本身寫的,可是要在客戶端用,因此命名要注意。
在客戶端咱們能夠添加偵聽事件來接收數據。
var socket = io.connect('http://127.0.0.1:3000'); socket.on('message',function(data){ alert(data.text); })
經過這些功能,咱們就在第一個例子的基礎上,實現用戶數量的統計。這裏只須要在服務端設置一個變量,count,若是有一個上線,那麼就數量+1,並通知全部用戶,最新的在線人數。
var http = require('http'); var fs = require('fs'); var count = 0; var server = http.createServer(function (req,res){ fs.readFile('./index.html',function(error,data){ res.writeHead(200,{'Content-Type':'text/html'}); res.end(data,'utf-8'); }); }).listen(3000,"127.0.0.1"); console.log('Server running at http://127.0.0.1:3000/'); var io = require('socket.io').listen(server); io.sockets.on('connection',function(socket){ count++; console.log('User connected' + count + 'user(s) present'); socket.emit('users',{number:count}); socket.broadcast.emit('users',{number:count}); socket.on('disconnect',function(){ count--; console.log('User disconnected'); socket.broadcast.emit('users',{number:count}); }); });
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Socket.IO Example</title> </head> <body> <h1>Socket.IO Example</h1> <h2>How many users are here?</h2> <p id="count"></p> <script src="http://***.***.**.***:9001/jquery.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script> var socket = io.connect('http://127.0.0.1:3000'); var count = document.getElementById('count'); socket.on('users',function(data){ console.log('Got update from the server'); console.log('There are ' + data.number + 'users'); count.innerHTML = data.number }); </script> </body> </html>
{
"name":"socketio_example", "version":"4.13.2", "private":true, "dependencies":{ "socket.io":"1.4.5" } }
安裝模塊npm install
啓動服務器node app.js
打開瀏覽器,輸入http://127.0.0.1:3000,能夠看到以下圖片:
再打開一個鏈接http://127.0.0.1:3000,能夠看到以下結果:
能夠看到若是咱們打開兩個鏈接,那麼兩個頁籤都會顯示當前又兩個用戶在線,若是關閉其中一個,咱們能夠看到又顯示只有一個用戶在線。
接下來咱們來看看Socket.IO是如何實現客戶端與客戶端的通訊呢。
要想實現該功能,首先須要客戶端將消息發送到服務端,·而後服務端發送給除本身以外的其餘客戶。服務器將消息發送給客戶端的方法在上一個例子中咱們已經實現了,那麼咱們須要的是客戶端把接收到的消息發送給服務器。
下邊的代碼思想是利用表單來實現的。
<form id="message-form" action="#"> <textarea id="message" rows="4" cols="30"></textarea> <input type="submit" value="Send message" /> </form> <script src="http://***.***.***.**:9001/jquery.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script> var socket = io.connect('http://127.0.0.1:3000'); var message = document.getElementById('message'); $(message.form).submit(function() { socket.emit('message', { text: message.value }); return false; }); socket.on('push message', function (data) { $('form').after('<p>' + data.text + '</p>'); }); </script>
實現的思想是,將JQuery和SocketIO庫包含進來,只是瀏覽器攔截127.0.0.1:3000的服務,使用Jquery的submit方法加入偵聽期,等候用戶提交表單。
發送消息給Socket>IO服務器,文本區域的內容位消息發送。
添加return false ,防止表單在瀏覽器窗口提交。
在上邊已經說過服務器如何廣播消息,下邊咱們說一下客戶端如何顯示客戶端發送的消息。
socket.on('push message', function (data) { $('form').after('<p>' + data.text + '</p>'); })
建立messaging的新文件夾
在文件夾下建立package.json文件,代碼以下:
{
"name":"socketio_example", "version":"4.13.2", "private":true, "dependencies":{ "socket.io":"1.4.5" } }
建立app.js文件,代碼以下:
var http = require('http'); var fs = require('fs'); var server = http.createServer(function (req,res){ fs.readFile('./index.html',function(error,data){ res.writeHead(200,{'Content-Type':'text/html'}); res.end(data,'utf-8'); }); }).listen(3000,"127.0.0.1"); console.log('Server running at http://127.0.0.1:3000/'); var io = require('socket.io').listen(server); io.sockets.on('connection',function(socket){ socket.on('message',function(data){ socket.broadcast.emit('push message',data); }); });
建立index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Socket.IO Example</title> </head> <body> <h1>Socket.IO Example</h1> <form id="message-form" action="#"> <textarea id="message" rows="4" cols="30"></textarea> <input type="submit" value="Send message" /> </form> <script src="http://222.222.124.77:9001/jquery.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script> var socket = io.connect('http://127.0.0.1:3000'); var message = document.getElementById('message'); $(message.form).submit(function() { socket.emit('message', { text: message.value }); return false; }); socket.on('push message', function (data) { $('form').after('<p>' + data.text + '</p>'); }); </script> </body> </html>
加載模塊npm install
啓動服務器node app.js
而後打開瀏覽器的多個頁籤,都輸入http://127.0.0.1:3000
能夠看到咱們再任何一個窗口輸入內容,都會在其餘的頁面顯示咱們輸入的內容,效果以下:
這篇博客好長,其實說了這麼多,仍是有不少的東西沒有說,可是咱們仍是討論了Socket.IO如何實現動態的,經過服務端能顯示用戶的鏈接,和統計連接次數統計,到最後的消息的通知和聊天功能的實現。在咱們的生活中這種例子比比解釋,例如QQ,例如淘寶的搶購,都是能夠經過這種方式實現的,這樣咱們就能實時的實現動態的功能了。