理解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>