基于Node.js和Socket.IO實(shí)現(xiàn)實(shí)時(shí)通信功能
引言
在現(xiàn)代網(wǎng)絡(luò)應(yīng)用中,實(shí)時(shí)通信變得越來(lái)越重要。Node.js,作為一個(gè)基于Chrome V8引擎的JavaScript運(yùn)行環(huán)境,使得開發(fā)者能夠在服務(wù)器端運(yùn)行JavaScript代碼,而Socket.IO則為Node.js提供了一個(gè)強(qiáng)大的實(shí)時(shí)通信庫(kù)。本文將通過(guò)一個(gè)簡(jiǎn)單的示例,展示如何使用Node.js和Socket.IO創(chuàng)建一個(gè)能夠?qū)崿F(xiàn)實(shí)時(shí)通信的服務(wù)器。
1. 環(huán)境準(zhǔn)備
在開始之前,請(qǐng)確保你已經(jīng)安裝了Node.js。你還需要安裝Socket.IO庫(kù),可以通過(guò)npm(Node.js的包管理器)來(lái)安裝:
npm install socket.io
2. 創(chuàng)建HTTP服務(wù)器
首先,我們需要?jiǎng)?chuàng)建一個(gè)HTTP服務(wù)器,用于提供靜態(tài)文件服務(wù),比如HTML頁(yè)面。以下是創(chuàng)建HTTP服務(wù)器的代碼:
const http = require("http");
const fs = require("fs");
// 創(chuàng)建HTTP服務(wù)器
let server = http.createServer((request, response) => {
// 讀取HTMLPage.html文件
fs.readFile("HTMLPage.html", (error, data) => {
response.writeHead(200, { 'Content-Type': 'text/html' });
response.end(data);
});
}).listen(52273, () => {
console.log('服務(wù)器地址: http://127.0.0.1:52273');
});
在這段代碼中,我們使用了Node.js的http模塊來(lái)創(chuàng)建一個(gè)服務(wù)器,該服務(wù)器監(jiān)聽52273端口。當(dāng)有HTTP請(qǐng)求到達(dá)時(shí),服務(wù)器會(huì)讀取并返回HTMLPage.html文件的內(nèi)容。
3. 集成Socket.IO
接下來(lái),我們將集成Socket.IO來(lái)實(shí)現(xiàn)WebSocket通信。以下是集成Socket.IO并設(shè)置WebSocket事件監(jiān)聽的代碼:
const socketio = require("socket.io");
// 創(chuàng)建WebSocket服務(wù)器
let io = socketio.listen(server);
// 監(jiān)聽WebSocket服務(wù)器的connection事件
io.sockets.on("connection", (socket) => {
console.log("客戶端已經(jīng)連接??!");
socket.on('clientData', (data) => {
console.log('客戶端發(fā)來(lái)的數(shù)據(jù):', data);
// 向客戶端發(fā)送serverData事件和數(shù)據(jù)
socket.emit('serverData', data);
});
});
在這段代碼中,我們首先引入了socket.io模塊,并使用listen方法創(chuàng)建了一個(gè)WebSocket服務(wù)器,綁定到我們之前創(chuàng)建的HTTP服務(wù)器實(shí)例上。然后,我們監(jiān)聽connection事件,當(dāng)有新的客戶端連接時(shí),會(huì)觸發(fā)這個(gè)事件。
在客戶端中接收:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!--
這行代碼通過(guò) <script> 標(biāo)簽引入了 socket.io 的客戶端庫(kù)。
這個(gè)庫(kù)允許瀏覽器與服務(wù)器建立 WebSocket 連接,并發(fā)送或接收事件。
socket.io.js 文件通常由服務(wù)器端的 socket.io 庫(kù)在指定的路徑下提供。
-->
<script src="/socket.io/socket.io.js"></script>
<script>
window.onload = function(){
// 連接socket
// 這行代碼創(chuàng)建了一個(gè)新的 socket 對(duì)象,用于與服務(wù)器建立連接。
// io.connect() 方法是 socket.io 庫(kù)提供的一個(gè)函數(shù),用于初始化一個(gè)新的連接。
// 如果沒有指定服務(wù)器地址,它默認(rèn)嘗試連接到與當(dāng)前頁(yè)面相同的主機(jī)和端口。
// 指定地址如:const socket = io.connect('http://localhost:3000');
var socket = io.connect();
// 監(jiān)聽服務(wù)端的事件和數(shù)據(jù)
socket.on('serverData',(data)=>{
alert(data) // 這里就是服務(wù)端發(fā)來(lái)的數(shù)據(jù)
})
// 創(chuàng)建表單點(diǎn)擊事件
document.getElementById('button').onclick = ()=>{
// 獲取表單數(shù)據(jù)
var text = document.getElementById('text').value;
// 向服務(wù)端發(fā)送clientData事件和數(shù)據(jù)
socket.emit('clientData',text);
}
}
</script>
</head>
<body>
<input type="text" id="text">
<input type="button" id="button" value="send">
</body>
</html>
4. 實(shí)現(xiàn)實(shí)時(shí)通信
在WebSocket連接建立后,我們可以監(jiān)聽客戶端發(fā)送的事件,并根據(jù)需要向客戶端發(fā)送事件。以下是實(shí)現(xiàn)實(shí)時(shí)通信的核心代碼:
socket.on('clientData', (data) => {
console.log('客戶端發(fā)來(lái)的數(shù)據(jù):', data);
// 向客戶端發(fā)送serverData事件和數(shù)據(jù)
socket.emit('serverData', data);
});
這段代碼監(jiān)聽了名為clientData的事件,當(dāng)客戶端發(fā)送這個(gè)事件時(shí),服務(wù)器會(huì)接收到數(shù)據(jù),并打印出來(lái)。然后,服務(wù)器使用emit方法向客戶端發(fā)送一個(gè)名為serverData的事件,并將接收到的數(shù)據(jù)作為參數(shù)發(fā)送回去。
5. 通信類型
在注釋中提到了四種通信類型:
單向通信:只有發(fā)送事件的客戶端可以收到消息。
io.on('connection', function (socket) {
socket.on('private message', function (msg) {
socket.emit('serverData', data);
});
});
公共通信:所有客戶端(包括發(fā)送事件的客戶端)都可以收到消息。
io.on('connection', function (socket) {
socket.on('private message', function (msg) {
io.sockets.emit('serverData', data);
});
});
廣播通信:除了發(fā)送事件的客戶端外,所有其他客戶端都可以收到消息。
io.on('connection', function (socket) {
socket.on('private message', function (msg) {
socket.broadcast.emit('serverData', data);
});
});
指定通信:可以確保只有指定的客戶端接收到消息,而其他客戶端則不會(huì)收到這些信息。
io.on('connection', function (socket) {
socket.on('private message', function (msg) {
io.to(socket.id).emit('private message', msg);
});
});
這些通信類型為開發(fā)者提供了靈活的選擇,可以根據(jù)應(yīng)用的需求選擇合適的通信方式。
6. 整體代碼
服務(wù)端(后端)代碼:
// 引入模塊
const http = require("http")
const fs = require("fs")
const socketio = require("socket.io")
// 創(chuàng)建服務(wù)器
let server = http.createServer((request, response) => {
// 讀取HTMLPage.html文件
fs.readFile("HTMLPage.html", (error, data) => {
response.writeHead(200, { 'Content-Type': 'text/html' })
response.end(data)
});
}).listen(52273, () => {
console.log('服務(wù)器地址: http://127.0.0.1:52273')
})
// 創(chuàng)建WebSocket服務(wù)器
// let io = socket.io.listen(server);:使用 socket.io 模塊的 listen 方法創(chuàng)建一個(gè) WebSocket 服務(wù)器,
// 并將其綁定到之前創(chuàng)建的 HTTP 服務(wù)器實(shí)例上。
let io = socketio.listen(server);
// 監(jiān)聽 WebSocket 服務(wù)器的 connection 事件,當(dāng)有新的 WebSocket 客戶端連接時(shí)觸發(fā)。
var id=0
io.sockets.on("connection", (socket) => {
// 在回調(diào)函數(shù)中,socket 參數(shù)代表與客戶端的 WebSocket 連接。
console.log("客戶端已經(jīng)連接??!")
id = socket.id
console.log('用戶已上線,自動(dòng)分配了一個(gè)id:',id)
socket.on('clientData', (data) => {
// 輸出客戶端發(fā)來(lái)的數(shù)據(jù)
console.log('客戶端發(fā)來(lái)的數(shù)據(jù):', data);
// 這個(gè)代碼發(fā)給的就是最新的id對(duì)應(yīng)的服務(wù)端;例如:有A、B、C三個(gè)客服端;A發(fā)信息的話就會(huì)發(fā)給C
io.sockets.to(id).emit('serverData',data)
// 向客戶端發(fā)送serverData事件和數(shù)據(jù)
// socket.emit('serverData', data);
// 1.單向通信類型:某個(gè)客戶端發(fā)送事件和數(shù)據(jù)的時(shí)候,只有他自己可以收到消息
// 代碼: socket.emit('serverData', data);
// 2.public 通信類型:某個(gè)客戶端發(fā)送事件和數(shù)據(jù)的時(shí)候,其他所有的客戶端都可以收到消息,包括 發(fā)消息的客戶端本身
// 代碼: io.sockets.emit('serverData',data)
// 3.broadcast 通信類型:某個(gè)客戶端發(fā)送事件和數(shù)據(jù)的時(shí)候,其他所有的客戶端都可以收到消息,除了 發(fā)消息的客戶端本身
// 代碼: socket.broadcast.emit('serverData',data)
// 4.private 通信類型:某個(gè)客戶端向指定的(id)某個(gè)客戶端發(fā)送事件和數(shù)據(jù)
// 代碼:
// id = socket.id
// io.socket.to(id).emit('serverData',data)
})
})
客戶端(前端)代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!--
這行代碼通過(guò) <script> 標(biāo)簽引入了 socket.io 的客戶端庫(kù)。
這個(gè)庫(kù)允許瀏覽器與服務(wù)器建立 WebSocket 連接,并發(fā)送或接收事件。
socket.io.js 文件通常由服務(wù)器端的 socket.io 庫(kù)在指定的路徑下提供。
-->
<script src="/socket.io/socket.io.js"></script>
<script>
window.onload = function(){
// 連接socket
// 這行代碼創(chuàng)建了一個(gè)新的 socket 對(duì)象,用于與服務(wù)器建立連接。
// io.connect() 方法是 socket.io 庫(kù)提供的一個(gè)函數(shù),用于初始化一個(gè)新的連接。
// 如果沒有指定服務(wù)器地址,它默認(rèn)嘗試連接到與當(dāng)前頁(yè)面相同的主機(jī)和端口。
var socket = io.connect();
// 監(jiān)聽服務(wù)端的事件和數(shù)據(jù)
socket.on('serverData',(data)=>{
alert(data)
})
// 創(chuàng)建表單點(diǎn)擊事件
document.getElementById('button').onclick = ()=>{
// 獲取表單數(shù)據(jù)
var text = document.getElementById('text').value;
// 向服務(wù)端發(fā)送clientData事件和數(shù)據(jù)
socket.emit('clientData',text);
}
}
</script>
</head>
<body>
<input type="text" id="text">
<input type="button" id="button" value="send">
</body>
</html>
7. 結(jié)論
通過(guò)上述步驟,我們創(chuàng)建了一個(gè)簡(jiǎn)單的Node.js服務(wù)器,它能夠處理HTTP請(qǐng)求,并使用Socket.IO實(shí)現(xiàn)WebSocket通信。這個(gè)服務(wù)器能夠接收客戶端發(fā)送的數(shù)據(jù),并能夠向客戶端發(fā)送數(shù)據(jù),實(shí)現(xiàn)實(shí)時(shí)通信。這只是一個(gè)基礎(chǔ)示例,Socket.IO和Node.js的強(qiáng)大功能遠(yuǎn)不止于此,它們可以支持更復(fù)雜的實(shí)時(shí)應(yīng)用場(chǎng)景,如多人聊天室、實(shí)時(shí)游戲等。
以上就是基于Node.js和Socket.IO實(shí)現(xiàn)實(shí)時(shí)通信功能的詳細(xì)內(nèi)容,更多關(guān)于Node.js Socket.IO實(shí)時(shí)通信的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- 淺析如何在Bash中調(diào)用Node運(yùn)行JS文件進(jìn)行數(shù)據(jù)通信
- Node.js中的進(jìn)程間通信
- 基于node的tcp客戶端和服務(wù)端的簡(jiǎn)單通信
- Node與Python 雙向通信的實(shí)現(xiàn)代碼
- Nodejs環(huán)境實(shí)現(xiàn)socket通信過(guò)程解析
- node實(shí)現(xiàn)socket鏈接與GPRS進(jìn)行通信的方法
- node 利用進(jìn)程通信實(shí)現(xiàn)Cluster共享內(nèi)存
- Node.js進(jìn)行串口通信的實(shí)現(xiàn)示例
相關(guān)文章
nodejs中request庫(kù)使用HTTPS代理的方法
這篇文章主要介紹了nodejs中request庫(kù)使用HTTPS代理的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-04-04
node實(shí)現(xiàn)簡(jiǎn)單的反向代理服務(wù)器
本篇文章主要介紹了node實(shí)現(xiàn)簡(jiǎn)單的反向代理,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07
nodejs 使用http進(jìn)行post或get請(qǐng)求的實(shí)例(攜帶cookie)
今天小編就為大家分享一篇nodejs 使用http進(jìn)行post或get請(qǐng)求的實(shí)例(攜帶cookie),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
NodeJS感知和控制自身進(jìn)程的運(yùn)行環(huán)境和狀態(tài)
NodeJS可以感知和控制自身進(jìn)程的運(yùn)行環(huán)境和狀態(tài),也可以創(chuàng)建子進(jìn)程并與其協(xié)同工作,這使得NodeJS可以把多個(gè)程序組合在一起共同完成某項(xiàng)工作,并在其中充當(dāng)膠水和調(diào)度器的作用,和進(jìn)程管理相關(guān)的API單獨(dú)介紹起來(lái)比較枯燥,這里從一些典型的應(yīng)用場(chǎng)景出發(fā)2024-01-01
Node.js?搭建后端服務(wù)器內(nèi)置模塊(?http+url+querystring?的使用)
這篇文章主要介紹了Node.js搭建后端服務(wù)器內(nèi)置模塊(http+url+querystring的使用),文章圍繞主題展開詳細(xì)的內(nèi)容戒殺,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-09-09
node實(shí)現(xiàn)將json轉(zhuǎn)為excel
平時(shí)我們寫代碼處理的數(shù)據(jù)格式一般都是json格式的數(shù)據(jù),但有時(shí)候我們也需要將數(shù)據(jù)轉(zhuǎn)為excel格式進(jìn)行保存或分享,所以下面我們就來(lái)學(xué)習(xí)一下如何通過(guò)node實(shí)現(xiàn)json轉(zhuǎn)excel吧2024-11-11
Node.js 與 Webpack 模塊化工程化入門指南教程
本文介紹了Node.js的基礎(chǔ)知識(shí),包括什么是Node.js、如何執(zhí)行代碼、fs和path模塊的使用方法,以及簡(jiǎn)易前端工程化實(shí)踐,隨后,文章講解了Web服務(wù)基礎(chǔ)、模塊化開發(fā)、npm包管理,以及使用Webpack進(jìn)行前端工程化和優(yōu)化,感興趣的朋友跟隨小編一起看看吧2026-03-03

