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