關於Socket.IO

好吧,四月的第一篇學習筆記,我知道我是偷懶了,<攤手>,一些整理參考《nodejs入門經典》,僅供我的學習。javascript

一 動態web的簡史css

    從歷史上說,web在設計上並無考錄動態,它是圍繞着文檔設計的能夠在一個時刻閱讀單一的文檔。用戶從瀏覽器請求一個web頁面,得到響應,而後瀏覽器顯示頁面——這樣的循環是許多爲web提供力量的技術的設計基礎。隨着時間的推移,開發人員更多的想法,不僅是顯示文檔,而JavaScript就是推進web頁面功能發展的中心。在20世紀90年代後期,DHTML這個術語出現了,它描述的是使用JavaScript,css和html更改頁面的某些部分的能力,從而讓web頁面更有交互性,也就是動態性。它引入了諸如ticker,顯示頁面的隱藏部分以及簡單的動畫等內容。DHTML本來是個行爲術語,它講解的是用戶與web頁面交互的方法以及當交互發生時會發生什麼。web標準社區後來採用DOM腳本,以可響應的方式來描述對web頁面的操縱,這樣當瀏覽器的某些插件不可用時,瀏覽器能夠優雅的降級。html

   Ajax是動態web頁面的下一個巨大進步,它和DHTMl同樣,描述了一組包括js,XML,html和css在內的技術。它讓開發人員能夠無需刷新web頁面就能從服務器請求數據。這意味着能夠在諸如用戶單擊按鈕這樣的特定事件發生的時候,從服務器請求新的數據。因爲整個web頁面無需刷新,就帶來了更具備交互性,動態的體驗。java

   不能否認,在建立動態web頁面上,ajax將繼續發揮極大的做用;但在某些領域,它卻極爲不足。若是從服務器請求數據,Ajax能夠工做的很好;但若是服務器想將數據推送到瀏覽器呢?Ajax技術沒法很容易地將數據推送到客戶端,雖然諸如Comet這樣的一些技術已經讓其成爲了可能。使用ajax技術能夠實現雙向數據流,但須要跨過許多障礙才行,並且不一樣的瀏覽器工做方式也不一樣。node

  WebSocket 是對在服務器和客戶端之間實現雙向實時通訊問題的響應。它的思想是,從頭開始,設計一個開發人員可使用的標準以便以一致的方式建立應用程序;而不是經過複雜的,並不總能在全部瀏覽器中都正常工做的設置來使用現有技術完成這一任務。WebSocket的基本思想是在web服務器和瀏覽器之間保持鏈接持久打開。這就使得不論是服務器仍是瀏覽器均可以在須要的時候推送數據。因爲鏈接是持久的,因此數據的交換就很是快,也就成就了‘實時’這個術語。WebSocket 不支持諸如從新鏈接處理(reconnetion handling)或者心跳(heartbeat)這樣的功能,但諸如Socket.IO這樣的庫提供了這些功能,同時還對某些跨瀏覽器的問題作了抽象。jquery

二Socket.IO是什麼?web

   Socket.IO是node.js的一個模塊,它是經過WebSocket進行通訊的一種簡單方式。WebSocket協議很複雜,從頭開始斌寫一個支持WebSocket的應用程序將須要花費不少時間。Socket.IO提供服務器和客戶端雙方的組件,因此只需一個模塊就能夠給應用程序加入對WebSocket的支持。Socket.IO也解決了各瀏覽器的支持問題(不是全部瀏覽器都支持WebSocket)並讓實時通訊能夠跨幾乎全部經常使用的瀏覽器實現。Socket.IO的設計很是好,將實時通訊帶入應用程序的過程便得很是簡單。若是想作任何涉及在web服務器和瀏覽器之間通訊的事情,那麼nodejs和Socket.IO是極好的選擇哦!。ajax

三Socket.IO示例npm

1.新建一個文件夾,我取名叫mySocketjson

2.在文件夾中建立一個名爲package.json的文件並加入如下內容來聲明依賴模塊,輸入以下內容

{
    "name":"socket.io",
    "version":"0.0.1",
    "dependencies":{
        "socket.io":"0.8.7"
    }
}

3.在文件夾中再建立一個名爲app.js的文件,輸入以下內容

var http=require('http');
var fs=require('fs');
var sever=http.createServer(function(req,res){
	fs.readFile('./index.html',function(err,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(sever);//爲了在服務器上加入Socket.IO的功能,必須將Socket.IO庫包括進來,然後附加到服務器上。
io.socket.on('connection',function(socket){//在啓動了服務器的Socket.io以後,用於初始化,須要一些代碼來讓Socket.io對特定事件做出響應,Socket.io偵聽許多事件,這裏只是示例
	console.log('user conneted');
	socket.on('disconnect',function(){
		console.log('user disconnet');
	});
});

 4.在文件夾中,建立一個名爲index.html的文件,輸入以下內容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Socket.io</title>
</head>
<body>
    <h1>I Am Socket.IO</h1>
    <script src="https://cdn.bootcss.com/socket.io/1.7.3/socket.io.js"></script>
    <script>
        var socket=io.connect('http://127.0.0.1:3000');
    </script>
</body>
</html>

5.在終端運行以下命令安裝依賴模塊:
npm install

6.從終端運行以下命令啓動服務器:

node app.js(注意是在mysocket的文件路徑下運行)

7.打開瀏覽器訪問http://127.0.0.1:3000.

8.可看到顯示‘I Am socket.IO’的頁面。

9.檢查服務器記錄在終端的日誌,能夠看到‘user connected’。

10.打開另外一個瀏覽器,瀏覽http://127.0.0.1:3000

11.可在服務器日誌上看到另外一條‘ user connected’。

12.關閉瀏覽器。

13.在服務器日誌上看到‘user disconnected’。

 

這個示例僅僅是演示了當客戶端作諸如鏈接和斷開鏈接這樣的事情時,socket.io對特定事件的偵聽。

 

四 從服務器發送數據到客戶端

看如下代碼

io.sockets.on('connection',function(socket){
    socket.emit('message',{text:"you have connected"});//向客戶端發送消息
});

注意到這個示例中,Socket.IO發送的是一個JavaScript對象,也可使用更復雜的數據結構。
這段代碼須要添加到應用程序的服務器端。只要客戶端鏈接,它就將數據發送給每個新的客戶端,而若是想給當前全部的客戶端都發送消息,則須要發送廣播消息

io.sockets.on('connection',function(socket){
socket.emit('message',{text:'A new user has connected"});
socket.broadcast.emit('massage',{text:'A new user has connected'});
});

這是類似的,不一樣的只是消息發送給全部已鏈接的客戶端而不只僅是剛剛鏈接的客戶端。注意broadcast的發送不包括本身。還有一點,示例中,消息以JavaScript對象在‘message’事件下發送。‘message’這個詞能夠是任何東西,但它是重要的,由於接收到數據時須要設置客戶端偵聽‘message’事件。不必定必須以JavaScript對象來發送數據,若是須要的話也能夠發送文本,但使用JavaScript對象可讓客戶端更容易使用數據。
接下來須要作的就是客戶端要包含以下js以便首先鏈接Socket.io服務器而後偵聽在''message’事件上接收的數據,而後作出響應。

var socket=io.connect('http://127.0.0.1:3000');
socket.on('message',function(data){
alert(data.text);
});

經過使用這些功能以及客戶端js,就能夠建立實時的計數器來計算已啓用Socket.io的服務器上所鏈接的客戶端數量。其思想是:當服務器啓動後,計數器從0開始。當客戶端鏈接到服務器時它遞增1.當客戶端斷開鏈接時,它遞減1.Socket.IO的消息機制可用以實時地隨着客戶端鏈接與斷開鏈接將服務器上客戶端的數量信息更新給全部的客戶端。考慮一下,這就是站點訪問者的實時統計數據了!

那麼開始動手吧

1 建立一個名爲realtime_socket的文件夾

2.在文件夾中,建立一個名爲package.json文件,並輸入以下代碼來聲明依賴模塊

{
    "name":"realtime_socket",
    "version":"0.0.1",
    "private":true,
    "dependencies":{
        "socket.io":"0.8.7"
    }
}

3.在文件夾中,建立一個名爲app.js的文件,並輸入以下代碼

var http=require('http');
var fs=require('fs');
var count=0;

var server=http.createServer(function(req,res){
    fs.readFile('./index.html',function(err,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 conneted'+count+'users present');
    socket.emit('users',{number:count});
    socket.broadcast.emit('users',{number:count});

    socket.on('disconnect',function(){
        count--;
      console.log('user disconnected'+count+'users present');
      socket.broadcast.emit('users',{number:count});
    });
});

4.在文件夾中,建立index.html文件,並輸入以下代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title> Realtime Socket.io</title>
</head>
<body>
    <h1>Realtime Socket.IO</h1>
    <h2> how many users are connect?</h2>
    <p id="count"></p>
     <script src="http://localhost:3000/socket.io/socket.io.js "/>
    <script>
        var socket=io.connect('http://127.0.0.1:3000');
        var count =document.getElementById('count');
        socket.on('users',function(data){ //偵聽users事件
            console.log('Got update from the server');
            console.log('there are'+data.number+'users');
            count.innerHtml=data.number;
        })
    </script>
</body>
</html>

5.從終端運行以下命令安裝依賴模塊
npm install

6.從終端運行以下命令啓動服務器

node app.js(注意是在realtime_Socket.IO的文件路徑下)

7.打開瀏覽器瀏覽:http://127.0.0.1:3000。

8.能夠看到一個頁面,顯示「Realtime Socket.IO」等等頁面信息

9.打開拎一個瀏覽器訪問:http://127.0.0.1:3000。

10.服務器更新信息,瀏覽器更新信息。

 五 進階:將數據廣播給客戶端

    實時計數器展現了客戶端數量數據如何實時往外推送給客戶端。可是若是想讓客戶端之間作通訊呢?有可能須要添加聊天功能的場合,或者有須要在客戶端之間發送消息的遊戲。爲了讓客戶端能夠互相通訊,首先須要從客戶端發送一條消息給服務器而後從服務器將消息推送給客戶端。過程以下:

1客戶端鏈接到Socket.IO Node.js服務器。

2一個客戶端發送消息給服務器。

3服務器接受此消息

4.服務器將消息廣播給全部其餘客戶端。

咱們已經在上一個示例中看到,能夠從Socket.IO服務器將消息廣播給客戶端:

socket.broadcast.emit('message',{text:' this goes to everyone'});

咱們還看到,能夠從服務器給單個客戶端發送消息:

socket.emit('message',{text:' this goes to single client'});

從客戶端發送消息給服務器代碼徹底相同!與實時計數器示例不一樣的是,消息是在客戶端原發的,並且來自客戶端的JavaScript。因而,在客戶端上,必需要有能讓用戶添加消息並提交給服務器的方法。一種實現這個功能的方法是建立一個表單而後使用一些JavaScript來捕獲用戶輸入到表單中的內容並將其發送給服務器。

好吧,原理說這麼多,開始實幹吧

1.建立一個名爲Socket.IO node.js的文件夾

2在文件夾中建立一個名爲package.json的文件,並輸入以下內容:

{
    "name":"socket_nodejs",
    "version":"0.0.1",
    "private":true,
    "dependencies":{
        "socket.io":"0.8.7"
    }
}

3.在文件夾中建立一個名爲app.js文件,並輸入以下內容:

var http = require('http');
var fs = require('fs');


var server = http.createServer(function(req, res) {
    fs.readFile('./index.html', function(err, 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) {//偵聽客戶端的message事件
        socket.broadcast.emit('push message', data);
    });
});

4.在文件夾中建立一個名爲index.html的文件,並輸入以下內容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>  Socket.io  Nodejs</title>
</head>
<body>
    <h1> Socket.IO Nodejs</h1>
    <form action="#" id="message_form">
        <textarea  id="message" cols="30" rows="10"></textarea>
        <input type="submit" value="Send message"/>
    </form>
    <!-- 將jquery和Socket.IO庫包含進來 -->
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
     <script src="http://localhost:3000/socket.io/socket.io.js "/>
    <script>

        var socket=io.connect('http://127.0.0.1:3000');//指示瀏覽器鏈接位於http://127.0.0.1:3000的Socket.IO服務器
    var message=document.getElementById('message');
    $('#message_form').submit(function(){//將jquery的submit()方法加入偵聽器,等候用戶提交表單
        socket.emit('message',{text:message.value});//發送消息給服務器,文本區域的內容做爲消息發送
        return false;//防止表單在瀏覽器窗口中提交。
    });
        socket.on('push message',function(data){ //偵聽push message事件
            $('form').after('<p>'+data.text+'</p>');//捕捉接收的數據,寫入dom
            
        });
    </script>
</body>
</html>

5.在終端輸入:
npm install

6.從終端啓動服務器:

node app.js(在文件夾路徑下)

7.打開瀏覽器瀏覽:http://127.0.0.1:3000

8打開另外一個瀏覽器訪問:http://127.0.0.1:3000

9在文本框中輸入內容並單擊submit。

10在另外一個瀏覽器中可看到消息出現

擴展:

ajax和socket.io之間有什麼區別?
Socket.IO提供的功能比ajax要多得多,好比很容易就能實時地將數據推送給客戶端。若是可使用WebSocket,那麼客戶端和服務器之間的鏈接就會是持久的。而對於ajax而言,每次都須要從新鏈接

另外,WebSocket和ajax的服務目標不一樣,因此很差說使用哪一個不使用哪一個。ajax適合瀏覽器須要時不時請求數據而且數據有可能須要緩衝的場景。若是常常須要在客戶端之間接收發送數據,並且有不少客戶端,那麼應該使用WebSocket。若是要構建一個客戶端能互相通訊的聯網應用程序,那麼WebSocket是更好的選擇

推送和拉取消息之間有何不一樣?

推送消息意味着新的消息經過持久鏈接推送到客戶端。這意味着客戶端無需請求得到新消息。做爲對比,拉取消息意味着客戶端必須檢查服務器上的內容,看看是否有新的消息可用。

WebSocket當前對瀏覽器的支持如何?

訪問http://canuuse.com並輸入WebSocket,就會看到WebSocket的支持狀況。在移動設備上,對websocket的支持不是很好因而這就增長了使用Socket.IO的籌碼了。

使用socket.io比起單純使用websock有何優點?

若是不能使用websocket,socket.io會使用其餘傳輸方法,來處理並不徹底支持websocket的瀏覽器問題,(Socket.IO會嘗試使用Adobe flash socket,ajax長輪詢,ajax多部分流,forever iframe 或者jsonp輪詢)。這就意味着無需編寫更多的代碼就可讓應用程序支持更多瀏覽器。

相關文章
相關標籤/搜索