Node.js/基本範例程式/共筆白板:修訂版本之間的差異
出自福留子孫
(→Socket.io) |
|||
(未顯示2位用戶所作出之34次版本) | |||
第 1 行: | 第 1 行: | ||
[[分類:Node.js]] | [[分類:Node.js]] | ||
− | 範例程式:[http://twees.info/ | + | 範例程式:[http://twees.info:8080/ 原始連結]|[http://twees.info/yu/eBoard/ 測試連結] |
+ | |||
+ | Socket_test.js | ||
<pre> | <pre> | ||
− | var app = require('express')(); // | + | /* 建立 socket.io 模組 */ |
− | var http = require('http').Server(app); // | + | var app = require('express')(); // 當使用者發出請求,即載入 express 模組,並建立一個 express 的 Web 應用程式物件。 |
− | var io = require('socket.io')(http); // | + | var http = require('http').Server(app); // 載入 http 模組, http 應用 Server 引入 app,建立一個 HTTP 物件。 |
+ | var io = require('socket.io')(http); // 載入 Socket.io 模組,socket.io 建立一個 http 連線。(http 物件作為參數傳遞給 socket.io,並將上行物件與http伺服器關聯起來。) | ||
+ | const port = 8080; // 連接埠為 8080 port | ||
− | + | /* 開始接收使用者資料 */ | |
+ | app.get( // 當遠端使用者訪問根路徑時,伺服器便回傳「 Socket_test.html」給客戶端(瀏覽器)。 | ||
+ | '/', | ||
+ | function(req,res){res.sendfile('Socket_test.html');} // function(請求,回覆) | ||
+ | ); | ||
− | + | io.on( // 當遠端使用者進入連上 io 時,利用 socket 去監聽使用者有沒有釋出任何事件 | |
− | + | 'connection', | |
− | }); | + | function(socket){console.log('a user connected');} |
+ | ); | ||
− | io.on('connection', function(socket){ | + | http.listen(port); // 啟動 HTTP 伺服器,並監聽指定的埠號。 |
− | + | ||
+ | /* 應付多個前端 io */ | ||
+ | io.sockets.on('connection',function(socket) // 當 on 接收到 'connection' 表示有人連上線,即執行函式 function(socket),利用 socket 去監聽使用者有沒有釋出任何的「事件」 | ||
+ | { | ||
+ | socket.on('login',function(data) // 當伺服器監聽由 使用者(html) 傳來的 'login' 事件,表示有使用者登入,即執行函式 function(data)。 | ||
+ | { | ||
+ | /* 伺服端訊息 */ | ||
+ | console.log("connected"); // 使用者畫面印出 connected 資訊 | ||
+ | /* 宣告物件,放置訊息 */ | ||
+ | var obj = new Object; | ||
+ | obj.name = data.name; | ||
+ | obj.msg = data.name + ' 已上線'; | ||
+ | console.log(obj.msg); // 印出:XXX 已上線 | ||
+ | |||
+ | /* 將在前端輸入的名稱記錄下來 */ | ||
+ | socket.name = data.name; | ||
+ | /* 將自己上線訊息傳給自己的網頁 */ | ||
+ | io.emit('msg',obj); | ||
+ | /* 告訴其他人你上線了 */ | ||
+ | socket.broadcast.emit('msg', obj); | ||
+ | }); | ||
+ | /* 接受、發送訊息 */ | ||
+ | socket.on('sendMessage', function(data) // 監聽 'sendMessage' 事件,當有使用者傳送訊息時,執行函式。 | ||
+ | { | ||
+ | /* 發送receiveMessage事件 */ | ||
+ | data.message = socket.name +" 說: "+ data.message; | ||
+ | io.sockets.emit('receiveMessage', data); | ||
+ | }); | ||
+ | /* 接受畫布作業訊息 */ | ||
+ | socket.on('draw',function(data) // 監聽 'draw' 事件,當有使用者在畫板上繪圖時,執行函式。 | ||
+ | { | ||
+ | /* 將畫布作業訊息傳給其他線上的人 */ | ||
+ | socket.broadcast.emit('show', data); | ||
+ | }); | ||
+ | /* 離開 */ | ||
+ | socket.on('disconnect',function() // 監聽斷開連接事件,當使用者離開時,執行函式。 | ||
+ | { | ||
+ | /* 宣告物件,放置訊息 */ | ||
+ | var obj = new Object; | ||
+ | obj.msg = socket.name + ' 已離開'; | ||
+ | console.log(obj.msg); | ||
+ | /* 通知所有人自己已經離開 */ | ||
+ | io.sockets.emit('msg', obj); | ||
+ | }); | ||
}); | }); | ||
+ | </pre> | ||
− | http.listen(port) | + | '''方法列表:''' |
+ | *app | ||
+ | *#app.get(路徑,函式):當遠端的使用者訪問指定路徑時,執行函式,函式中指示客戶端請求與伺服器回應 | ||
+ | *#*第一個參數是路徑,用來匹配客戶端請求的 URL 路徑,可以是字串或正規表達式。如,/home、/about、/contact 等。 | ||
+ | *#*第二個參數是函式,當客戶端請求匹配到路徑時,該函式就會被執行。<br/>函式有兩個參數:一個是客戶端請求的 request 物件,另一個是伺服器回應的 response 物件。<br/>函式中,我們可以使用各種技術處理 request 物件,如讀取query string、POST資料、cookies等,然後使用 response 物件回應一些東西給客戶端。 | ||
+ | *io<br/>- Socket.io庫是一個在Web瀏覽器和伺服器之間進行即時雙向通信的庫,建立在WebSocket協議之上,並且在WebSocket不可用時使用HTTP長輪詢來實現即時通信。<br/>- io.on( )方法是socket.io庫提供的一個監聽事件的方法,允許你在伺服器端監聽客戶端發送的事件。<br/>- 在應用程序中,你可以使用io對象來發送其他事件,從而實現伺服器端和客戶端之間的雙向通信。 | ||
+ | *#io物件.on('connection',函式) | ||
+ | *#*指令是 Socket.IO 中用於監聽新連線事件的函式,可以在有新的客戶端連線到伺服器時觸發相應的操作。 | ||
+ | *#*在Socket.io中,當有新的客戶端連線到伺服器時,伺服器會觸發一個'connection'事件,這個事件可以用.on()方法來監聽,而當這個事件被觸發時,對應的函式就會被執行。 | ||
+ | *#*在這個指令中,'connection'是要監聽的事件名稱,而函式則是當事件被觸發時要執行的程式碼,通常用來處理新連線的客戶端所發送的訊息。 | ||
+ | *#io物件.on('disconnect',函式) | ||
+ | *#*'''disconnect:一個預定義的事件名稱,用於表示客戶端與伺服器端斷開連接的事件。''' | ||
+ | *#*當客戶端斷開連接時,socket.io會自動觸發disconnect事件,並且該事件的回調函式會被調用。 | ||
+ | *#*你可以使用io.on('disconnect',函式)來註冊斷開連接事件的回調函式,在該函式中處理斷開連接事件。 | ||
+ | *#*在斷開連接事件的回調函式中,你可以清除該客戶端的狀態或者在伺服器端顯示斷開連接的消息等。 | ||
+ | *#*disconnect事件是socket.io庫自動觸發的,因此不需要額外的設置或者調用。 | ||
+ | *#*在應用程序中,你可以使用io對象來監聽其他事件,並向客戶端發送事件和資料,從而實現伺服器端和客戶端之間的雙向通信。 | ||
+ | *#io物件.on('login',函式) | ||
+ | *#*'''login:一個自定義的事件名稱,用於表示客戶端登錄成功的事件。你可以在客戶端和伺服器端定義該事件。''' | ||
+ | *#*當客戶端登錄成功時,可以使用socket.emit('login', data)向伺服器端發送login事件和資料。 | ||
+ | *#*伺服器端可以使用io.on('login', function(data){})來監聽login事件,並且在事件的回調函式中處理事件和資料。 | ||
+ | *#*在login事件的回調函式中,你可以處理客戶端傳遞過來的資料,例如驗證資料的正確性、更新客戶端狀態等。 | ||
+ | *#*在伺服器端,你可以使用socket.broadcast.emit('login', data)來向所有已連接的客戶端發送login事件和資料。 | ||
+ | *#*你也可以使用socket.emit( )方法來向特定的客戶端發送login事件和資料,例如socket.emit('login', data)。 | ||
+ | *#*login事件是一個自定義的事件,你可以在應用程序中使用任何事件名稱和資料格式。但是,需要確保事件名稱和資料格式在客戶端和伺服器端之間保持一致。 | ||
+ | *#io物件.on('sendMessage',函式) | ||
+ | *#*'''sendMessage:一個自定義的事件名稱,用於表示客戶端發送消息的事件。你可以在客戶端和伺服器端定義該事件。''' | ||
+ | *#*當客戶端發送消息時,可以使用socket.emit('sendMessage', data)向伺服器端發送sendMessage事件和資料。 | ||
+ | *#*伺服器端可以使用io.on('sendMessage', function(data){})來監聽sendMessage事件,並且在事件的回調函式中處理事件和資料。 | ||
+ | *#*在sendMessage事件的回調函式中,你可以處理客戶端傳遞過來的資料,例如將消息存儲到資料庫中、向其他客戶端轉發消息等。 | ||
+ | *#*在伺服器端,你可以使用socket.broadcast.emit('sendMessage', data)來向所有已連接的客戶端發送sendMessage事件和資料,但不會發送給自己。 | ||
+ | *#*你也可以使用socket.emit( )方法來向特定的客戶端發送sendMessage事件和資料,例如socket.emit('sendMessage', data)。 | ||
+ | *#*sendMessage事件是一個自定義的事件,你可以在應用程序中使用任何事件名稱和資料格式。但是,需要確保事件名稱和資料格式在客戶端和伺服器端之間保持一致。 | ||
+ | *#io物件.emit('msg',obj): | ||
+ | *#*.emit()發射的意思,事件:'msg',帶什麼資訊帶出去:obj。 | ||
+ | *#*'''io.emit( ):socket.io庫提供的一個發送事件的方法,允許你向所有已連接的客戶端發送事件和資料。''' | ||
+ | *#*'msg'是一個自定義的事件名稱,用於表示消息事件。你可以在客戶端和伺服器端定義該事件。 | ||
+ | *#*obj是一個包含資料的物件,你可以在事件發送時將該物件傳遞給客戶端。 | ||
+ | *#*當你調用io.emit('msg', obj)時,socket.io庫會向所有已連接的客戶端發送'msg'事件和obj物件資料。 | ||
+ | *#*客戶端可以使用socket.on('msg', function(data){ })來監聽'msg'事件,並且在事件的回調函式中處理事件和資料。 | ||
+ | *#*在'msg'事件的回調函式中,你可以處理伺服器端傳遞過來的資料,例如將消息顯示在客戶端畫面上等。 | ||
+ | *#*你也可以使用socket.emit('msg', obj)方法來向特定的客戶端發送'msg'事件和資料。 | ||
+ | *#*'msg'事件是一個自定義的事件,你可以在應用程序中使用任何事件名稱和資料格式。但是,需要確保事件名稱和資料格式在客戶端和伺服器端之間保持一致。 | ||
+ | *#io物件.broadcast.emit('msg',obj) | ||
+ | *#*'''io.broadcast.emit( ):socket.io庫提供的一個發送事件的方法,類似於io.emit()方法,但是不會向發送事件的socket本身發送事件,而是向其他已連接的socket發送事件和資料。''' | ||
+ | *#*msg是一個自定義的事件名稱,用於表示消息事件。你可以在客戶端和伺服器端定義該事件。 | ||
+ | *#*obj是一個包含資料的物件,你可以在事件發送時將該物件傳遞給其他已連接的socket。 | ||
+ | *#*當你調用io.broadcast.emit('msg', obj)時,socket.io庫會向除發送事件的socket本身以外的所有已連接的socket發送'msg'事件和obj物件資料。 | ||
+ | *#*客戶端可以使用socket.on('msg', function(data){})來監聽'msg'事件,並且在事件的回調函式中處理事件和資料。 | ||
+ | *#*在 msg 事件的回調函式中,你可以處理伺服器端傳遞過來的資料,例如將消息顯示在客戶端畫面上等。 | ||
+ | *#*你也可以使用socket.broadcast.emit('msg', obj)方法來向特定的socket發送'msg'事件和資料。 | ||
+ | *#*使用io.broadcast.emit( )方法需要注意,當已連接的socket數量增加時,該方法會影響伺服器端的性能和效率。因此,建議在發送事件時,只向需要接收該事件的socket發送,而不是向所有已連接的socket發送。 | ||
+ | *#io物件.broadcast.emit('show',data) | ||
+ | *#*'''io.broadcast.emit( ):socket.io庫提供的一個發送事件的方法,類似於io.emit()方法,但是不會向發送事件的socket本身發送事件,而是向其他已連接的socket發送事件和資料。''' | ||
+ | *#*show是一個自定義的事件名稱,用於表示展示事件。你可以在客戶端和伺服器端定義該事件。 | ||
+ | *#*data是一個包含資料的物件,你可以在事件發送時將該物件傳遞給其他已連接的socket。 | ||
+ | *#*當你調用io.broadcast.emit('show', data)時,socket.io庫會向除發送事件的socket本身以外的所有已連接的socket發送'show'事件和data物件資料。 | ||
+ | *#*客戶端可以使用socket.on('show', function(data){})來監聽'show'事件,並且在事件的回調函式中處理事件和資料。 | ||
+ | *#*在 show 事件的回調函式中,你可以處理伺服器端傳遞過來的資料,例如將資料顯示在客戶端畫面上等。 | ||
+ | *#*你也可以使用socket.broadcast.emit('show', data)方法來向特定的socket發送'show'事件和資料。 | ||
+ | *#*show事件是一個自定義的事件,你可以在應用程序中使用任何事件名稱和資料格式。但是,需要確保事件名稱和資料格式在客戶端和伺服器端之間保持一致。 | ||
+ | *#*使用io.broadcast.emit()方法需要注意,當已連接的socket數量增加時,該方法會影響伺服器端的性能和效率。因此,建議在發送事件時,只向需要接收該事件的socket發送,而不是向所有已連接的socket | ||
+ | *#io.sockets.on('connection',函式) | ||
+ | *#*在 Node.js 中,使用 Socket.IO 庫建立 WebSocket 連接。 | ||
+ | *#*程式碼範例: | ||
+ | *#*:io.sockets.on('connection', function(socket) { }); | ||
+ | *#*代碼的含義如下: | ||
+ | *#*:io:Socket.IO 庫創建的一個 Socket 實例。 | ||
+ | *#*:sockets:一個包含所有連接到該 Socket 實例的客戶端的集合。 | ||
+ | *#*:on:用於監聽客戶端事件的事件監聽函式。 | ||
+ | *#*:connection:一個預定義的事件名稱,表示客戶端連接到伺服器。 | ||
+ | *#*:function(socket) {...}:事件回調函式,用於處理客戶端連接事件,其中 socket 表示客戶端連接的 Socket 實例對象。 | ||
+ | *#io.sockets.emit('receiveMessage',data) | ||
+ | *#*在 Node.js 中,使用 Socket.IO 庫建立 WebSocket 連接。 | ||
+ | *#*程式碼範例: | ||
+ | *#*:io.sockets.emit('receiveMessage', data); | ||
+ | *#*代碼的含義如下: | ||
+ | *#*:io:Socket.IO 庫創建的一個 Socket 實例。 | ||
+ | *#*:sockets:一個包含所有連接到該 Socket 實例的客戶端的集合。 | ||
+ | *#*:emit:用於發送事件給客戶端的方法。 | ||
+ | *#*:receiveMessage:自定義的一個事件名稱,表示接收到了一個消息。 | ||
+ | *#*:data:要傳遞給客戶端的數據,可以是任何 JavaScript 對象。 | ||
+ | *http | ||
+ | *#http.listen(port,ip,函式) | ||
+ | *#*在 Node.js 中,使用 HTTP 模組創建一個 Web 服務器。 | ||
+ | *#*程式碼範例: | ||
+ | *#*:http.listen(port, ip, function() { | ||
+ | *#*::console.log("Server is listening at http://" + ip + ":" + port); | ||
+ | *#*:}); | ||
+ | *#*代碼的含義如下: | ||
+ | *#*:http:是使用 Node.js 的 HTTP 模組創建的一個 Web 服務器對象。 | ||
+ | *#*:listen:是 HTTP 服務器對象的一個方法,用於啟動服務器。 | ||
+ | *#*:port:是服務器要監聽的端口號,可以是任何整數。 | ||
+ | *#*:ip:是服務器要監聽的 IP 地址,可以是任何合法的 IP 地址字符串。 | ||
+ | *#*:function() {...}:是一個回調函式,當服務器啟動成功後會執行該函式。 | ||
+ | *#*:console.log("Server is listening at http://" + ip + ":" + port):是回調函式中的代碼,印出服務器啟動成功的消息,包括服務器的地址和端口號。 | ||
− | io | + | ==Socket.io== |
− | + | #本身是(最基礎)通訊協定,可以實現低延遲、高效率的數據傳輸。 | |
− | + | #讓使用者之間建立溝通管道,讓兩台主機間可以對話。(例如:字串)<br/><img src='http://jendo.org/~游士賢/使用說明/Socketio/Socketio通訊架構.png' width='600px' /> | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ===範例一、文字溝通=== | |
− | + | A使用者和B使用者間,利用文字溝通。以下是程式碼解說:<br/> | |
− | + | '''A使用者_html''' | |
− | + | <pre> | |
− | + | //發送訊息函式 | |
− | + | function sendMessage(){ | |
− | + | let txt = $('#sendtxt').val(); | |
− | + | $('#sendtxt').val(''); | |
− | + | if(txt){ | |
+ | /*觸發 sendMessage 事件*/ | ||
+ | socket.emit('sendMessage', { message: txt}); | ||
+ | } | ||
+ | } | ||
+ | </pre> | ||
− | + | '''socket.io.js''' | |
− | + | <pre> | |
− | + | //接受、發送訊息 | |
− | + | socket.on('sendMessage', function(data){ | |
− | + | /*發送receiveMessage事件*/ | |
− | + | data.message = socket.name +" 說: "+ data.message; | |
− | + | o.sockets.emit('receiveMessage', data) | |
− | + | }) | |
− | + | </pre> | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | '''B使用者_html''' | |
− | + | <pre> | |
− | + | //接收訊息的反應 | |
− | + | socket.on('receiveMessage', function(data){ | |
− | + | document.getElementById('member_msg').innerText += `${data.message}\n`; | |
− | + | }) | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | }) | + | |
</pre> | </pre> | ||
− | + | ===範例二、畫布溝通=== | |
− | + | 範例二:A使用者和B使用者間,利用畫布互動,以下是程式碼解說<br/> | |
− | + | '''A使用者_html''' | |
− | + | <pre> | |
− | + | //畫圖,並將繪畫座標傳給網頁上的其他使用者 | |
+ | function drawLine(x, y, new_x, new_y) | ||
+ | { | ||
+ | //繪圖 | ||
+ | ctx.beginPath(); | ||
+ | ctx.moveTo(x, y); | ||
+ | ctx.lineTo(new_x, new_y); | ||
+ | ctx.closePath(); | ||
+ | ctx.stroke(); | ||
− | + | //將繪畫座標透過 node.js 傳給使用者 | |
− | * | + | var obj = new Object; |
− | * | + | obj.x = x; |
− | + | obj.y = y; | |
− | + | obj.new_x = new_x; | |
+ | obj.new_y = new_y; | ||
+ | obj.size = $('#size').val(); | ||
+ | |||
+ | //document.getElementById('member_msg').innerText += `${obj.x}\n`; | ||
+ | socket.emit('draw', obj); | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | '''socket.io.js''' | ||
+ | <pre> | ||
+ | /* 接受畫布作業訊息 */ | ||
+ | socket.on('draw',function(data){ // 監聽 'draw' 事件,當有使用者在畫板上繪圖時,執行函式。 | ||
+ | /* 將畫布作業訊息傳給其他線上的人 */ | ||
+ | socket.broadcast.emit('show', data); | ||
+ | }); | ||
+ | </pre> | ||
+ | |||
+ | '''B使用者_html''' | ||
+ | <pre> | ||
+ | //別人畫布上的動作,呈現在我們自己的頁面上 | ||
+ | socket.on('show', function(data){ | ||
+ | //設定筆尖大小 | ||
+ | $('#size').val( data.size ); | ||
+ | ctx.lineWidth = data.size; | ||
+ | |||
+ | //繪圖 | ||
+ | ctx.beginPath(); | ||
+ | ctx.moveTo(data.x, data.y); | ||
+ | ctx.lineTo(data.new_x, data.new_y); | ||
+ | ctx.closePath(); | ||
+ | ctx.stroke(); | ||
+ | }); | ||
+ | </pre> |
2023年4月18日 (二) 13:23的最新修訂版本
Socket_test.js
/* 建立 socket.io 模組 */ var app = require('express')(); // 當使用者發出請求,即載入 express 模組,並建立一個 express 的 Web 應用程式物件。 var http = require('http').Server(app); // 載入 http 模組, http 應用 Server 引入 app,建立一個 HTTP 物件。 var io = require('socket.io')(http); // 載入 Socket.io 模組,socket.io 建立一個 http 連線。(http 物件作為參數傳遞給 socket.io,並將上行物件與http伺服器關聯起來。) const port = 8080; // 連接埠為 8080 port /* 開始接收使用者資料 */ app.get( // 當遠端使用者訪問根路徑時,伺服器便回傳「 Socket_test.html」給客戶端(瀏覽器)。 '/', function(req,res){res.sendfile('Socket_test.html');} // function(請求,回覆) ); io.on( // 當遠端使用者進入連上 io 時,利用 socket 去監聽使用者有沒有釋出任何事件 'connection', function(socket){console.log('a user connected');} ); http.listen(port); // 啟動 HTTP 伺服器,並監聽指定的埠號。 /* 應付多個前端 io */ io.sockets.on('connection',function(socket) // 當 on 接收到 'connection' 表示有人連上線,即執行函式 function(socket),利用 socket 去監聽使用者有沒有釋出任何的「事件」 { socket.on('login',function(data) // 當伺服器監聽由 使用者(html) 傳來的 'login' 事件,表示有使用者登入,即執行函式 function(data)。 { /* 伺服端訊息 */ console.log("connected"); // 使用者畫面印出 connected 資訊 /* 宣告物件,放置訊息 */ var obj = new Object; obj.name = data.name; obj.msg = data.name + ' 已上線'; console.log(obj.msg); // 印出:XXX 已上線 /* 將在前端輸入的名稱記錄下來 */ socket.name = data.name; /* 將自己上線訊息傳給自己的網頁 */ io.emit('msg',obj); /* 告訴其他人你上線了 */ socket.broadcast.emit('msg', obj); }); /* 接受、發送訊息 */ socket.on('sendMessage', function(data) // 監聽 'sendMessage' 事件,當有使用者傳送訊息時,執行函式。 { /* 發送receiveMessage事件 */ data.message = socket.name +" 說: "+ data.message; io.sockets.emit('receiveMessage', data); }); /* 接受畫布作業訊息 */ socket.on('draw',function(data) // 監聽 'draw' 事件,當有使用者在畫板上繪圖時,執行函式。 { /* 將畫布作業訊息傳給其他線上的人 */ socket.broadcast.emit('show', data); }); /* 離開 */ socket.on('disconnect',function() // 監聽斷開連接事件,當使用者離開時,執行函式。 { /* 宣告物件,放置訊息 */ var obj = new Object; obj.msg = socket.name + ' 已離開'; console.log(obj.msg); /* 通知所有人自己已經離開 */ io.sockets.emit('msg', obj); }); });
方法列表:
- app
- app.get(路徑,函式):當遠端的使用者訪問指定路徑時,執行函式,函式中指示客戶端請求與伺服器回應
- 第一個參數是路徑,用來匹配客戶端請求的 URL 路徑,可以是字串或正規表達式。如,/home、/about、/contact 等。
- 第二個參數是函式,當客戶端請求匹配到路徑時,該函式就會被執行。
函式有兩個參數:一個是客戶端請求的 request 物件,另一個是伺服器回應的 response 物件。
函式中,我們可以使用各種技術處理 request 物件,如讀取query string、POST資料、cookies等,然後使用 response 物件回應一些東西給客戶端。
- app.get(路徑,函式):當遠端的使用者訪問指定路徑時,執行函式,函式中指示客戶端請求與伺服器回應
- io
- Socket.io庫是一個在Web瀏覽器和伺服器之間進行即時雙向通信的庫,建立在WebSocket協議之上,並且在WebSocket不可用時使用HTTP長輪詢來實現即時通信。
- io.on( )方法是socket.io庫提供的一個監聽事件的方法,允許你在伺服器端監聽客戶端發送的事件。
- 在應用程序中,你可以使用io對象來發送其他事件,從而實現伺服器端和客戶端之間的雙向通信。- io物件.on('connection',函式)
- 指令是 Socket.IO 中用於監聽新連線事件的函式,可以在有新的客戶端連線到伺服器時觸發相應的操作。
- 在Socket.io中,當有新的客戶端連線到伺服器時,伺服器會觸發一個'connection'事件,這個事件可以用.on()方法來監聽,而當這個事件被觸發時,對應的函式就會被執行。
- 在這個指令中,'connection'是要監聽的事件名稱,而函式則是當事件被觸發時要執行的程式碼,通常用來處理新連線的客戶端所發送的訊息。
- io物件.on('disconnect',函式)
- disconnect:一個預定義的事件名稱,用於表示客戶端與伺服器端斷開連接的事件。
- 當客戶端斷開連接時,socket.io會自動觸發disconnect事件,並且該事件的回調函式會被調用。
- 你可以使用io.on('disconnect',函式)來註冊斷開連接事件的回調函式,在該函式中處理斷開連接事件。
- 在斷開連接事件的回調函式中,你可以清除該客戶端的狀態或者在伺服器端顯示斷開連接的消息等。
- disconnect事件是socket.io庫自動觸發的,因此不需要額外的設置或者調用。
- 在應用程序中,你可以使用io對象來監聽其他事件,並向客戶端發送事件和資料,從而實現伺服器端和客戶端之間的雙向通信。
- io物件.on('login',函式)
- login:一個自定義的事件名稱,用於表示客戶端登錄成功的事件。你可以在客戶端和伺服器端定義該事件。
- 當客戶端登錄成功時,可以使用socket.emit('login', data)向伺服器端發送login事件和資料。
- 伺服器端可以使用io.on('login', function(data){})來監聽login事件,並且在事件的回調函式中處理事件和資料。
- 在login事件的回調函式中,你可以處理客戶端傳遞過來的資料,例如驗證資料的正確性、更新客戶端狀態等。
- 在伺服器端,你可以使用socket.broadcast.emit('login', data)來向所有已連接的客戶端發送login事件和資料。
- 你也可以使用socket.emit( )方法來向特定的客戶端發送login事件和資料,例如socket.emit('login', data)。
- login事件是一個自定義的事件,你可以在應用程序中使用任何事件名稱和資料格式。但是,需要確保事件名稱和資料格式在客戶端和伺服器端之間保持一致。
- io物件.on('sendMessage',函式)
- sendMessage:一個自定義的事件名稱,用於表示客戶端發送消息的事件。你可以在客戶端和伺服器端定義該事件。
- 當客戶端發送消息時,可以使用socket.emit('sendMessage', data)向伺服器端發送sendMessage事件和資料。
- 伺服器端可以使用io.on('sendMessage', function(data){})來監聽sendMessage事件,並且在事件的回調函式中處理事件和資料。
- 在sendMessage事件的回調函式中,你可以處理客戶端傳遞過來的資料,例如將消息存儲到資料庫中、向其他客戶端轉發消息等。
- 在伺服器端,你可以使用socket.broadcast.emit('sendMessage', data)來向所有已連接的客戶端發送sendMessage事件和資料,但不會發送給自己。
- 你也可以使用socket.emit( )方法來向特定的客戶端發送sendMessage事件和資料,例如socket.emit('sendMessage', data)。
- sendMessage事件是一個自定義的事件,你可以在應用程序中使用任何事件名稱和資料格式。但是,需要確保事件名稱和資料格式在客戶端和伺服器端之間保持一致。
- io物件.emit('msg',obj):
- .emit()發射的意思,事件:'msg',帶什麼資訊帶出去:obj。
- io.emit( ):socket.io庫提供的一個發送事件的方法,允許你向所有已連接的客戶端發送事件和資料。
- 'msg'是一個自定義的事件名稱,用於表示消息事件。你可以在客戶端和伺服器端定義該事件。
- obj是一個包含資料的物件,你可以在事件發送時將該物件傳遞給客戶端。
- 當你調用io.emit('msg', obj)時,socket.io庫會向所有已連接的客戶端發送'msg'事件和obj物件資料。
- 客戶端可以使用socket.on('msg', function(data){ })來監聽'msg'事件,並且在事件的回調函式中處理事件和資料。
- 在'msg'事件的回調函式中,你可以處理伺服器端傳遞過來的資料,例如將消息顯示在客戶端畫面上等。
- 你也可以使用socket.emit('msg', obj)方法來向特定的客戶端發送'msg'事件和資料。
- 'msg'事件是一個自定義的事件,你可以在應用程序中使用任何事件名稱和資料格式。但是,需要確保事件名稱和資料格式在客戶端和伺服器端之間保持一致。
- io物件.broadcast.emit('msg',obj)
- io.broadcast.emit( ):socket.io庫提供的一個發送事件的方法,類似於io.emit()方法,但是不會向發送事件的socket本身發送事件,而是向其他已連接的socket發送事件和資料。
- msg是一個自定義的事件名稱,用於表示消息事件。你可以在客戶端和伺服器端定義該事件。
- obj是一個包含資料的物件,你可以在事件發送時將該物件傳遞給其他已連接的socket。
- 當你調用io.broadcast.emit('msg', obj)時,socket.io庫會向除發送事件的socket本身以外的所有已連接的socket發送'msg'事件和obj物件資料。
- 客戶端可以使用socket.on('msg', function(data){})來監聽'msg'事件,並且在事件的回調函式中處理事件和資料。
- 在 msg 事件的回調函式中,你可以處理伺服器端傳遞過來的資料,例如將消息顯示在客戶端畫面上等。
- 你也可以使用socket.broadcast.emit('msg', obj)方法來向特定的socket發送'msg'事件和資料。
- 使用io.broadcast.emit( )方法需要注意,當已連接的socket數量增加時,該方法會影響伺服器端的性能和效率。因此,建議在發送事件時,只向需要接收該事件的socket發送,而不是向所有已連接的socket發送。
- io物件.broadcast.emit('show',data)
- io.broadcast.emit( ):socket.io庫提供的一個發送事件的方法,類似於io.emit()方法,但是不會向發送事件的socket本身發送事件,而是向其他已連接的socket發送事件和資料。
- show是一個自定義的事件名稱,用於表示展示事件。你可以在客戶端和伺服器端定義該事件。
- data是一個包含資料的物件,你可以在事件發送時將該物件傳遞給其他已連接的socket。
- 當你調用io.broadcast.emit('show', data)時,socket.io庫會向除發送事件的socket本身以外的所有已連接的socket發送'show'事件和data物件資料。
- 客戶端可以使用socket.on('show', function(data){})來監聽'show'事件,並且在事件的回調函式中處理事件和資料。
- 在 show 事件的回調函式中,你可以處理伺服器端傳遞過來的資料,例如將資料顯示在客戶端畫面上等。
- 你也可以使用socket.broadcast.emit('show', data)方法來向特定的socket發送'show'事件和資料。
- show事件是一個自定義的事件,你可以在應用程序中使用任何事件名稱和資料格式。但是,需要確保事件名稱和資料格式在客戶端和伺服器端之間保持一致。
- 使用io.broadcast.emit()方法需要注意,當已連接的socket數量增加時,該方法會影響伺服器端的性能和效率。因此,建議在發送事件時,只向需要接收該事件的socket發送,而不是向所有已連接的socket
- io.sockets.on('connection',函式)
- 在 Node.js 中,使用 Socket.IO 庫建立 WebSocket 連接。
- 程式碼範例:
- io.sockets.on('connection', function(socket) { });
- 代碼的含義如下:
- io:Socket.IO 庫創建的一個 Socket 實例。
- sockets:一個包含所有連接到該 Socket 實例的客戶端的集合。
- on:用於監聽客戶端事件的事件監聽函式。
- connection:一個預定義的事件名稱,表示客戶端連接到伺服器。
- function(socket) {...}:事件回調函式,用於處理客戶端連接事件,其中 socket 表示客戶端連接的 Socket 實例對象。
- io.sockets.emit('receiveMessage',data)
- 在 Node.js 中,使用 Socket.IO 庫建立 WebSocket 連接。
- 程式碼範例:
- io.sockets.emit('receiveMessage', data);
- 代碼的含義如下:
- io:Socket.IO 庫創建的一個 Socket 實例。
- sockets:一個包含所有連接到該 Socket 實例的客戶端的集合。
- emit:用於發送事件給客戶端的方法。
- receiveMessage:自定義的一個事件名稱,表示接收到了一個消息。
- data:要傳遞給客戶端的數據,可以是任何 JavaScript 對象。
- io物件.on('connection',函式)
- http
- http.listen(port,ip,函式)
- 在 Node.js 中,使用 HTTP 模組創建一個 Web 服務器。
- 程式碼範例:
- http.listen(port, ip, function() {
- console.log("Server is listening at http://" + ip + ":" + port);
- });
- http.listen(port, ip, function() {
- 代碼的含義如下:
- http:是使用 Node.js 的 HTTP 模組創建的一個 Web 服務器對象。
- listen:是 HTTP 服務器對象的一個方法,用於啟動服務器。
- port:是服務器要監聽的端口號,可以是任何整數。
- ip:是服務器要監聽的 IP 地址,可以是任何合法的 IP 地址字符串。
- function() {...}:是一個回調函式,當服務器啟動成功後會執行該函式。
- console.log("Server is listening at http://" + ip + ":" + port):是回調函式中的代碼,印出服務器啟動成功的消息,包括服務器的地址和端口號。
- http.listen(port,ip,函式)
Socket.io
- 本身是(最基礎)通訊協定,可以實現低延遲、高效率的數據傳輸。
- 讓使用者之間建立溝通管道,讓兩台主機間可以對話。(例如:字串)
範例一、文字溝通
A使用者和B使用者間,利用文字溝通。以下是程式碼解說:
A使用者_html
//發送訊息函式 function sendMessage(){ let txt = $('#sendtxt').val(); $('#sendtxt').val(''); if(txt){ /*觸發 sendMessage 事件*/ socket.emit('sendMessage', { message: txt}); } }
socket.io.js
//接受、發送訊息 socket.on('sendMessage', function(data){ /*發送receiveMessage事件*/ data.message = socket.name +" 說: "+ data.message; o.sockets.emit('receiveMessage', data) })
B使用者_html
//接收訊息的反應 socket.on('receiveMessage', function(data){ document.getElementById('member_msg').innerText += `${data.message}\n`; })
範例二、畫布溝通
範例二:A使用者和B使用者間,利用畫布互動,以下是程式碼解說
A使用者_html
//畫圖,並將繪畫座標傳給網頁上的其他使用者 function drawLine(x, y, new_x, new_y) { //繪圖 ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(new_x, new_y); ctx.closePath(); ctx.stroke(); //將繪畫座標透過 node.js 傳給使用者 var obj = new Object; obj.x = x; obj.y = y; obj.new_x = new_x; obj.new_y = new_y; obj.size = $('#size').val(); //document.getElementById('member_msg').innerText += `${obj.x}\n`; socket.emit('draw', obj); }
socket.io.js
/* 接受畫布作業訊息 */ socket.on('draw',function(data){ // 監聽 'draw' 事件,當有使用者在畫板上繪圖時,執行函式。 /* 將畫布作業訊息傳給其他線上的人 */ socket.broadcast.emit('show', data); });
B使用者_html
//別人畫布上的動作,呈現在我們自己的頁面上 socket.on('show', function(data){ //設定筆尖大小 $('#size').val( data.size ); ctx.lineWidth = data.size; //繪圖 ctx.beginPath(); ctx.moveTo(data.x, data.y); ctx.lineTo(data.new_x, data.new_y); ctx.closePath(); ctx.stroke(); });