理解socket.io(一)---相關的API
1. 什麼是Socket.IO?
Socket.IO是node.js的一個模組,它用於瀏覽器與服務端之間實時通訊。它提供了伺服器和客戶端的元件,只需一個模組就可以給應用程式對webSocket的支援。Socket.IO解決了各個瀏覽器支援的問題。
2. Socket.IO支援如下方式進行通訊,會根據瀏覽器的支援程度,自動選擇使用哪種技術進行通訊:
WebSocket Flash Socket AJAX long-polling AJAX multiple streaming Forever IFrame JSONP polling
3. Socket.IO的API
// 監聽客戶端連線,回撥函式會傳遞本次連線的socket io.on('connection', function(socket){}); // 給所有客戶端廣播訊息 io.sockets.emit('event_name', data); // 給指定的客戶端傳送訊息 io.sockets.socket(socketid).emit('event_name', data); // 監聽傳送的訊息 socket.on('event_name', function(data) {}); // 給該socket的客戶端傳送訊息 socket.emit('event_name', data); // 給除了自己以外的客戶端廣播訊息 socket.broadcast.emit("event_name", data);
客戶端:
1. 建立一個socket連線
var socket = io("ws:///xxxxx");
2. 監聽服務訊息
socket.on('msg', function(data) { socket.emit('msg', {xx: xx1}); // 向伺服器傳送訊息 console.log(data); });
3. 監聽socket斷開
socket.on('disconnect', function(){ console.log('與伺服器斷開'); });
4. 監聽socket的重連
socket.on('reconnect', function() { console.log('重新連線到伺服器'); });
客戶端socket.on()監聽的事件:
connect: 連線成功
connecting: 正在連線
disconnect: 斷開連線
connect_failed: 連線失敗
error: 發生錯誤
message: 接收到訊息事件
reconnect_failed: 重連失敗
reconnect: 重連成功
reconnecting: 正在重連
1-1:給當前的客戶端傳送訊息的demo
下面我們簡單的來看一個demo,頁面有一個文字域和一個按鈕,點選按鈕後。
首先需要安裝一下 socket.io;
命令列如下:
npm install --save socket.io
以下是專案中package.json,如下:
{ "name": "socket-demo1", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "socket.io": "^2.1.0" }, "devDependencies": { "fs": "0.0.1-security", "http": "0.0.0" } }
html程式碼如下:
<!DOCTYPE html> <html> <head> <title>socket.io node.js</title> <style> </style> </head> <body> <h1>socket.io</h1> <form action="#" id="form"> <textarea id="message" cols="30" rows="10"></textarea> <input type="submit" value="send message" id="submit"/> </form> <script src="http://localhost:3000/socket.io/socket.io.js"></script> <script> var socket = io.connect('http://127.0.0.1:3000'); var msg = document.getElementById('message'); var submit = document.getElementById('submit'); submit.onclick = function(e) { socket.emit('msg', {text: msg.value}); // 發生textarea的值給伺服器 return false; }; // 監聽msg事件 socket.on('msg', function(data) { console.log(data); }) </script> </body> </html>
app.js程式碼如下:
var http = require('http'); var fs = require('fs'); var server = http.createServer(function(res, 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) { // 偵聽客戶端的msg事件 socket.on('msg', function(data) { // 給除了自己以外的客戶端廣播訊息 // socket.broadcast.emit('msg', data); // 給當前的客戶端傳送訊息 socket.emit('msg', data); }) });
進入對應的專案,命令列 執行 node app.js, 然後在瀏覽器下執行 http://127.0.0.1:3000/ 後即可,傳送訊息後,在控制檯看到能監聽到訊息;
簡單程式碼分析:
首先是通過點選按鈕,獲取到文字域的值,然後使用 socket.emit('msg', {text: msg.value}); 傳送訊息,伺服器端(也就是app.js)程式碼內通過
io.sockets.on('connection', function(socket) {}), 該函式能監聽客戶端連線,然後使用 socket.on('msg', function(data) {})能監聽到客戶端的msg事件,
最後通過 socket.emit('msg', data); 給客戶端傳送訊息,最後客戶端通過如下程式碼就能監聽服務端回來的訊息。
// 監聽msg事件 socket.on('msg', function(data) { console.log(data); }) // 因此 整個程式碼如下: io.sockets.on('connection', function(socket) { // 偵聽客戶端的msg事件 socket.on('msg', function(data) { // 給當前的客戶端傳送訊息 socket.emit('msg', data); }) })
1-2: 如果想給除了自己以外的客戶端廣播訊息
可以把上面客戶端的程式碼 socket.emit('msg', data); 改成 socket.broadcast.emit('msg', data);
因此開啟瀏覽器訪問http://127.0.0.1:3000,同時開啟另一個瀏覽器或者多個瀏覽器,瀏覽http://127.0.0.1:3000,當在第一個標籤頁的傳送訊息的時候,在第二個標籤頁面或其他標籤頁面的控制檯可以看到訊息。
1-3:如果想給當前所有的客戶端都傳送訊息的話,需要傳送廣播訊息,程式碼可以改成如下:
io.sockets.on('connection', function(socket) { // 偵聽客戶端的msg事件 socket.on('msg', function(data) { // 給除了自己以外的客戶端廣播訊息 socket.broadcast.emit('msg', data); // 給當前的客戶端傳送訊息 socket.emit('msg', data); }) });
二. 實現一個簡單的計數器來監聽伺服器上所連線客戶端的數量。
思路是:當伺服器啟動後,計算器是從0開始,當開啟瀏覽器訪問http://127.0.0.1:3000後,客戶端連線到伺服器時它就增加1,當關閉一個瀏覽器時,它就
減少1。這或是可以理解為 站點實時統計訪問者的資料的一個簡單的列子吧。
app.js 程式碼如下:
var http = require('http'); var fs = require('fs'); var count = 0; var server = http.createServer(function(res, 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 connected" + count + 'users'); socket.emit('users', {number: count}); socket.broadcast.emit('users', {number: count}); socket.on('disconnect', function() { count--; console.log('user disconnected' + count + 'users'); socket.broadcast.emit('users', {number: count}); }); });
html程式碼如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>socket.io node.js</title> <style> </style> </head> <body> <h3>socket.io實時監聽伺服器上所連線客戶端的數量</h3> <p id="count"></p> <script src="http://localhost:3000/socket.io/socket.io.js"></script> <script> var socket = io.connect('http://127.0.0.1:3000'); var count = document.getElementById('count'); // 偵聽users的事件 socket.on('users', function(data) { console.log(data); count.innerHTML = data.number; }); </script> </body> </html>