nodejs結(jié)合Socket.IO實(shí)現(xiàn)的即時(shí)通訊功能詳解
本文實(shí)例講述了nodejs結(jié)合Socket.IO實(shí)現(xiàn)的即時(shí)通訊功能。分享給大家供大家參考,具體如下:
動(dòng)態(tài)web
在html5以前,web的設(shè)計(jì)上并沒(méi)有考慮過(guò)動(dòng)態(tài),他一直是圍繞著文檔設(shè)計(jì)的,我們看以前比較老的網(wǎng)站,基本上都是某一刻用來(lái)顯示單一的文檔的,用戶(hù)請(qǐng)求一次web頁(yè)面,獲取一個(gè)頁(yè)面,但是隨著時(shí)間的推移,人們想要web做更多的事情了,而不是簡(jiǎn)單的要顯示文檔,而javaScript一直處于開(kāi)發(fā)人員推動(dòng)web頁(yè)面功能的發(fā)展中心。
Ajax無(wú)疑是動(dòng)態(tài)Web頁(yè)面的一個(gè)重大發(fā)展,他不再需要我們即使更新一點(diǎn)內(nèi)容,也需要刷新整個(gè)頁(yè)面了,但是有些方面,又體現(xiàn)了他的不足。如果從服務(wù)器請(qǐng)求數(shù)據(jù),他固然號(hào),但是如果服務(wù)器想要將數(shù)據(jù)推送到瀏覽器呢。Ajax技術(shù)無(wú)法很容易的支持將數(shù)據(jù)推送到客戶(hù),雖然可以,但是需要跨國(guó)很多的障礙才行,而且不同的瀏覽器工作方式也不同,例如IE和FireBox他們的內(nèi)核就不一樣,從而工作方式也不一樣。
WebSocket是在對(duì)服務(wù)器和客戶(hù)端之間實(shí)現(xiàn)雙向通信問(wèn)題的相應(yīng)。他的思想是,從頭開(kāi)始,設(shè)計(jì)一個(gè)開(kāi)發(fā)人員可以使用的標(biāo)準(zhǔn)以便以一直的方式創(chuàng)建應(yīng)用程序,而不是通過(guò)復(fù)雜的,并不總能設(shè)置所有瀏覽器的工作。他的思想是Web服務(wù)器和瀏覽器之間保持持久打開(kāi),這就使得不管是服務(wù)器還是瀏覽器都可以在想要的時(shí)候推送數(shù)據(jù)。因?yàn)檫B接是持久的,所以數(shù)據(jù)的交換非常的快,也就成了實(shí)時(shí)的了。
Socket.IO
說(shuō)了那么多,我們介紹一下正主,Socket.IO是Node.js的一個(gè)模塊,他提供通過(guò)WebSocket進(jìn)行通信的一種簡(jiǎn)單方式,WebSocket協(xié)議很復(fù)雜,但是Socket.IO提供了服務(wù)器和客戶(hù)端雙方的組件,所以只需要一個(gè)模塊就可以給應(yīng)用程序加入對(duì)WebSocket的支持。而且還能支持不同的瀏覽器。
基礎(chǔ)的Socket.IO
Socket.IO既能在服務(wù)端也能在客戶(hù)端工作,要使用它,必須將其添加到服務(wù)器端的JavaScript(Node.js)和客戶(hù)端的JavaScript(JQuery)中,這是以為內(nèi)通信通常是雙向的,所以Sokcet.IO需要能在兩邊工作。
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庫(kù)包含起來(lái),才能加入Socket.IO的功能。
var io = require('socket.io').listen(server);
然后加入一個(gè)事件來(lái)響應(yīng)客戶(hù)端到底是連接了,還是斷開(kāi)了。事件如下:
io.sockets.on('connection',function(socket){
console.log('User connected');
socket.on('disconnect',function(){
console.log('User disconnected');
});
});
是不是覺(jué)得非常的簡(jiǎn)單,下面我們看一下完整的代碼實(shí)現(xiàn)是如何實(shí)現(xiàn)的吧:
簡(jiǎn)單Socket.IO應(yīng)用
新建app.js
新建文件夾socket.io,在該文件夾下新建app.js,寫(xiě)如下代碼:
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
新建index.html文件,代碼如下:
<!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
新建package.json來(lái)引入模塊。
{
"name":"socketio_example",
"version":"4.13.2",
"private":true,
"dependencies":{
"socket.io":"1.4.5"
}
}
版本號(hào)大家可以輸入自己的nodejs -V,或者socket.io -v來(lái)查看自己的版本號(hào)。
運(yùn)行
如果大家沒(méi)有安裝Socket.IO,可以運(yùn)行如下代碼,如果安裝了,自動(dòng)跳過(guò)這一步。
npm install socket.io
從終端運(yùn)行如下命令安裝模塊
npm install
運(yùn)行如下命令啟動(dòng)服務(wù)器
node app.js
打開(kāi)瀏覽器,輸入http://127.0.0.1:3000/,多打開(kāi)幾個(gè)頁(yè)簽,都輸入該網(wǎng)址,再任意關(guān)閉一個(gè)頁(yè)簽,然后看看我們的cmd命令窗口是不是如下:

這里會(huì)詳細(xì)的記錄又多少個(gè)用于連接了,也有多少個(gè)用戶(hù)斷開(kāi)連接了,這樣就能統(tǒng)計(jì)我們網(wǎng)頁(yè)的訪(fǎng)問(wèn)量了。
從服務(wù)器發(fā)送數(shù)據(jù)到客戶(hù)端
上邊的實(shí)例我們已經(jīng)實(shí)現(xiàn)了連接或者斷開(kāi)服務(wù)器做記錄了,但是我們要是想要推送消息怎么辦,例如我們好友的QQ上線(xiàn)了,騰訊都會(huì)咳嗽一下來(lái)提醒我們有好友上線(xiàn)。下面我們來(lái)做一下這個(gè)功能功能。
發(fā)送給單個(gè)用戶(hù)
io.sockets.on('connection',function(socket){
socket.emit('message',{text:'你上線(xiàn)了'});
});
發(fā)給所有用戶(hù)
io.sockets.on('connection',function(socket){
socket.broadcast.emit('message',{'你的好某XXX上線(xiàn)了'});
});
無(wú)論是發(fā)送給單個(gè)用戶(hù)還是所有用戶(hù),這個(gè)message是自己寫(xiě)的,但是要在客戶(hù)端用,所以命名要注意。
客戶(hù)端
在客戶(hù)端我們可以添加偵聽(tīng)事件來(lái)接收數(shù)據(jù)。
var socket = io.connect('http://127.0.0.1:3000');
socket.on('message',function(data){
alert(data.text);
})
通過(guò)這些功能,我們就在第一個(gè)例子的基礎(chǔ)上,實(shí)現(xiàn)用戶(hù)數(shù)量的統(tǒng)計(jì)。這里只需要在服務(wù)端設(shè)置一個(gè)變量,count,如果有一個(gè)上線(xiàn),那么就數(shù)量+1,并通知所有用戶(hù),最新的在線(xiàn)人數(shù)。
新建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(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});
});
});
創(chuàng)建index.html文件
<!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>
創(chuàng)建package.json文件
{
"name":"socketio_example",
"version":"4.13.2",
"private":true,
"dependencies":{
"socket.io":"1.4.5"
}
}
安裝模塊npm install
啟動(dòng)服務(wù)器node app.js
打開(kāi)瀏覽器,輸入http://127.0.0.1:3000,可以看到如下圖片:

再打開(kāi)一個(gè)連接http://127.0.0.1:3000,可以看到如下結(jié)果:

可以看到如果我們打開(kāi)兩個(gè)連接,那么兩個(gè)頁(yè)簽都會(huì)顯示當(dāng)前又兩個(gè)用戶(hù)在線(xiàn),如果關(guān)閉其中一個(gè),我們可以看到又顯示只有一個(gè)用戶(hù)在線(xiàn)。
將數(shù)據(jù)廣播給客戶(hù)端
接下來(lái)我們來(lái)看看Socket.IO是如何實(shí)現(xiàn)客戶(hù)端與客戶(hù)端的通信呢。
要想實(shí)現(xiàn)該功能,首先需要客戶(hù)端將消息發(fā)送到服務(wù)端,·然后服務(wù)端發(fā)送給除自己之外的其他客戶(hù)。服務(wù)器將消息發(fā)送給客戶(hù)端的方法在上一個(gè)例子中我們已經(jīng)實(shí)現(xiàn)了,那么我們需要的是客戶(hù)端把接收到的消息發(fā)送給服務(wù)器。
下邊的代碼思想是利用表單來(lái)實(shí)現(xiàn)的。
<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>
實(shí)現(xiàn)的思想是,將JQuery和SocketIO庫(kù)包含進(jìn)來(lái),只是瀏覽器攔截127.0.0.1:3000的服務(wù),使用Jquery的submit方法加入偵聽(tīng)期,等候用戶(hù)提交表單。
發(fā)送消息給Socket>IO服務(wù)器,文本區(qū)域的內(nèi)容位消息發(fā)送。
添加return false ,防止表單在瀏覽器窗口提交。
在上邊已經(jīng)說(shuō)過(guò)服務(wù)器如何廣播消息,下邊我們說(shuō)一下客戶(hù)端如何顯示客戶(hù)端發(fā)送的消息。
socket.on('push message', function (data) {
$('form').after('<p>' + data.text + '</p>');
})
實(shí)例實(shí)現(xiàn)
創(chuàng)建messaging的新文件夾
在文件夾下創(chuàng)建package.json文件,代碼如下:
{
"name":"socketio_example",
"version":"4.13.2",
"private":true,
"dependencies":{
"socket.io":"1.4.5"
}
}
創(chuàng)建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);
});
});
創(chuàng)建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
啟動(dòng)服務(wù)器node app.js
然后打開(kāi)瀏覽器的多個(gè)頁(yè)簽,都輸入http://127.0.0.1:3000
可以看到我們?cè)偃魏我粋€(gè)窗口輸入內(nèi)容,都會(huì)在其他的頁(yè)面顯示我們輸入的內(nèi)容,效果如下:


小結(jié)
這篇博客好長(zhǎng),其實(shí)說(shuō)了這么多,還是有很多的東西沒(méi)有說(shuō),但是我們還是討論了Socket.IO如何實(shí)現(xiàn)動(dòng)態(tài)的,通過(guò)服務(wù)端能顯示用戶(hù)的連接,和統(tǒng)計(jì)鏈接次數(shù)統(tǒng)計(jì),到最后的消息的通知和聊天功能的實(shí)現(xiàn)。在我們的生活中這種例子比比解釋?zhuān)鏠Q,例如淘寶的搶購(gòu),都是可以通過(guò)這種方式實(shí)現(xiàn)的,這樣我們就能實(shí)時(shí)的實(shí)現(xiàn)動(dòng)態(tài)的功能了。尤其是12306這個(gè)網(wǎng)站,我得和他們說(shuō)說(shuō)了,哈哈。
希望本文所述對(duì)大家nodejs程序設(shè)計(jì)有所幫助。
- node.js中的Socket.IO使用實(shí)例
- node.js中Socket.IO的進(jìn)階使用技巧
- 基于socket.io和node.js搭建即時(shí)通信系統(tǒng)
- node.js中的socket.io入門(mén)實(shí)例
- node中socket.io的事件使用詳解
- node.js中的socket.io的廣播消息
- node.js中使用socket.io制作命名空間
- node.js基于socket.io快速實(shí)現(xiàn)一個(gè)實(shí)時(shí)通訊應(yīng)用
- nodejs+socket.io實(shí)現(xiàn)p2p消息實(shí)時(shí)發(fā)送的項(xiàng)目實(shí)踐
相關(guān)文章
Public?Npm?Registry模塊使用方式實(shí)例
這篇文章主要為大家介紹了Public?Npm?Registry的使用方式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
nodejs根據(jù)ip數(shù)組在百度地圖中進(jìn)行定位
本文主要介紹了nodejs根據(jù)ip數(shù)組在百度地圖中進(jìn)行定位的方法,具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-03-03
NodeJS學(xué)習(xí)筆記之網(wǎng)絡(luò)編程
Node.js采用了Google Chrome瀏覽器的V8引擎,性能很好,同時(shí)還提供了很多系統(tǒng)級(jí)的API,如文件操作、網(wǎng)絡(luò)編程等。Node.js則是一個(gè)全面的后臺(tái)運(yùn)行時(shí),為Javascript提供了其他語(yǔ)言能夠?qū)崿F(xiàn)的許多功能。今天我們來(lái)看下Nodejs的網(wǎng)絡(luò)編程2014-08-08
Windows系統(tǒng)下安裝Node.js的步驟圖文詳解
這篇文章主要給大家介紹了Windows系統(tǒng)下Node.js的安裝教程,Node.js是用于后端編程的JavaScript框架,文中給出了詳細(xì)圖文介紹,有需要的朋友可以參考下,下面來(lái)一起看看吧。2016-11-11
使用nodeJS中的fs模塊對(duì)文件及目錄進(jìn)行讀寫(xiě),刪除,追加,等操作詳解
nodeJS中fs模塊對(duì)系統(tǒng)文件及目錄進(jìn)行讀寫(xiě)操作,本文將詳細(xì)介紹nodejs中的文件操作模塊fs的使用方法2020-02-02
NodeJs Express框架實(shí)現(xiàn)服務(wù)器接口詳解
最近學(xué)習(xí)了基于前后端分離的開(kāi)發(fā)模式,我前端使用Vue框架,后端使用nodejs開(kāi)發(fā)API接口,下面這篇文章主要給大家介紹了關(guān)于nodejs使用Express框架寫(xiě)后端接口的相關(guān)資料,需要的朋友可以參考下2022-08-08

