下面是“node.js中Socket.IO的进阶使用技巧”的完整攻略,包含两条示例说明。
Socket.IO概述
Socket.IO是一个实时应用程序框架,它使得在Web浏览器和服务器之间进行实时双向通信变得非常容易。它允许在混合Websockets、HTTP请求和轮询之间动态选择最佳的通信通道。在Node.js中,Socket.IO利用了底层的EventEmitter来实现事件处理和回调。
Socket.IO基础功能
1.连接
要与服务器建立Socket.IO连接,客户端所需要做的就是通过Socket.IO库创建一个新的socket对象并连接到服务器。
const socket = io.connect('http://example.com');
在这里,io
是全局Socket.IO库的一个实例,它创建了一个新的socket对象,以连接到指定的服务器。如果省略参数,则将连接到当前URL。
在连接成功后,Socket.IO将触发一个名为connect
的事件。
2.传递数据
一旦连接建立,双方就可以开始在服务器和客户端之间传递数据。在客户端,可以使用socket.emit()
方法向服务器发送数据:
socket.emit('message', 'Hello, server!');
在服务器端,可以监听message
事件并通过回调函数获取客户端发送的数据:
socket.on('message', (data) => {
console.log('Received message:', data);
});
特别的,Socket.IO还提供了socket.send()
方法作为socket.emit('message', ...)
的快捷方式。
3.关闭连接
要从服务器断开连接,可以使用socket.disconnect()
方法:
socket.disconnect();
在客户端调用该方法时,Socket.IO将向服务器发送一个关闭连接的请求,并在成功关闭连接后触发disconnect
事件。
Socket.IO进阶功能
1.房间功能
在Socket.IO中,房间是用于将多个socket连接组织在一起的抽象概念。它类似于信仰群或讨论组,所有属于该房间的成员都可以接收到对房间的广播消息。
对于每个socket对象,Socket.IO都提供了一个join()
方法和一个leave()
方法,可以用于加入或离开某个房间。服务器可以使用socket.broadcast.to(room).emit()
方法将消息发送到房间中的其他socket连接:
io.on('connection', (socket) => {
console.log('A new client has connected');
// 加入房间
socket.join('chatroom');
// 监听来自客户端的消息
socket.on('message', (data) => {
console.log('Received message:', data);
// 将消息发送到所在房间内的其他客户端
socket.broadcast.to('chatroom').emit('message', data);
});
// 断开连接时离开房间
socket.on('disconnect', () => {
console.log('A client has disconnected');
socket.leave('chatroom');
});
});
2.命名空间
命名空间是用于将socket.IO连接分组的另一种方式。每个socket.IO连接都必须隶属于某个命名空间,而每个命名空间又可以包含若干个房间。
在Node.js中,可以通过创建新的Socket.IO实例来创建新的命名空间:
const nsp = io.of('/my-namespace');
创建了名为/my-namespace
的新命名空间后,就可以如下使用:
nsp.on('connection', (socket) => {
console.log('A new client has connected to my-namespace');
// ...
socket.on('disconnect', () => {
console.log('A client has disconnected from my-namespace');
});
});
示例1:使用命名空间
下面是一个关于如何在Socket.IO中使用命名空间及房间的例子,它可以让多个用户加入同一个聊天室,并接收到其他用户所发的信息。
服务器代码:
const http = require('http');
const socketIO = require('socket.io');
const server = http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello, world!\n');
});
server.listen(3000, () => {
console.log('Server is listening on port 3000');
});
const io = socketIO(server);
// 创建名为'/chat'的命名空间
const chatNamespace = io.of('/chat');
// 监听连接事件
chatNamespace.on('connection', (socket) => {
console.log(`A new client connected to chat namespace: ${socket.id}`);
// 监听加入聊天室事件
socket.on('join room', (roomName) => {
// 加入指定聊天室
socket.join(roomName);
console.log(`User ${socket.id} joined room ${roomName}`);
});
// 监听离开聊天室事件
socket.on('leave room', (roomName) => {
// 离开指定聊天室
socket.leave(roomName);
console.log(`User ${socket.id} left room ${roomName}`);
});
// 监听发送消息事件
socket.on('send message', (data) => {
// 将消息发送到指定房间
chatNamespace.to(data.room).emit('message', {
username: data.username,
message: data.message
});
console.log(`User ${socket.id} sent a message to room ${data.room}`);
});
// 监听断开连接事件
socket.on('disconnect', () => {
console.log(`A client disconnected from chat namespace: ${socket.id}`);
});
});
客户端代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Socket.IO Example</title>
</head>
<body>
<h1>聊天室</h1>
<input type="text" id="username" placeholder="用户名"><br/>
<input type="text" id="roomName" placeholder="聊天室名称"><br/>
<textarea id="message" rows="5" cols="30" placeholder="输入消息"></textarea><br/>
<button id="joinRoom">加入聊天室</button>
<button id="leaveRoom">离开聊天室</button>
<button id="sendMessage">发送消息</button>
<hr>
<ul id="messages"></ul>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io('/chat');
const messages = document.getElementById('messages');
// 监听连接事件
socket.on('connect', () => {
console.log(`Connected to server: ${socket.id}`);
});
// 监听断开连接事件
socket.on('disconnect', () => {
console.log(`Disconnected from server: ${socket.id}`);
});
// 监听消息事件
socket.on('message', (data) => {
console.log('Received message:', data);
messages.innerHTML += `<li><strong>${data.username}:</strong> ${data.message}</li>`;
});
// 点击加入聊天室按钮
document.getElementById('joinRoom').addEventListener('click', () => {
const roomName = document.getElementById('roomName').value;
socket.emit('join room', roomName);
});
// 点击离开聊天室按钮
document.getElementById('leaveRoom').addEventListener('click', () => {
const roomName = document.getElementById('roomName').value;
socket.emit('leave room', roomName);
});
// 点击发送消息按钮
document.getElementById('sendMessage').addEventListener('click', () => {
const username = document.getElementById('username').value;
const roomName = document.getElementById('roomName').value;
const message = document.getElementById('message').value;
socket.emit('send message', {username, room: roomName, message});
});
</script>
</body>
</html>
示例2:使用嵌套的命名空间
以下示例演示了如何在Socket.IO中创建嵌套命名空间。命名空间/finance
下还有一个名为/stock
的子命名空间,用户可以在其中关注某一种股票,并收到该股票最新的价格信息。
服务器代码:
const http = require('http');
const socketIO = require('socket.io');
const server = http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello, world!\n');
});
server.listen(3000, () => {
console.log('Server is listening on port 3000');
});
const io = socketIO(server);
// 创建名为'/finance'的命名空间
const financeNamespace = io.of('/finance');
// 创建名为'/stock'的子命名空间
const stockNamespace = financeNamespace.of('/stock');
// 模拟几只股票的当前价格
let stocks = {
'AAPL': 138.72,
'GOOG': 2329.96,
'AMZN': 3454.91,
'TSLA': 609.89
};
// 定时更新股票价格
setInterval(() => {
// 随机选择一只股票并更改其价格
const keys = Object.keys(stocks);
const randomKey = keys[Math.floor(Math.random() * keys.length)];
stocks[randomKey] += Math.random() * 20 - 10;
// 将新价格广播给所有关注该股票的客户端
stockNamespace.to(randomKey).emit('update price', {
symbol: randomKey,
price: stocks[randomKey]
});
console.log(`Stock ${randomKey} updated to ${stocks[randomKey]}`);
}, 3000);
// 监听连接事件
stockNamespace.on('connection', (socket) => {
console.log(`A new client connected to stock namespace: ${socket.id}`);
// 监听关注股票事件
socket.on('follow stock', (symbol) => {
// 加入以股票名字为房间名的房间,用于接收最新价格信息
socket.join(symbol);
console.log(`User ${socket.id} followed stock ${symbol}`);
});
// 监听取消关注事件
socket.on('unfollow stock', (symbol) => {
// 离开以股票名字为房间名的房间
socket.leave(symbol);
console.log(`User ${socket.id} unfollowed stock ${symbol}`);
});
// 监听断开连接事件
socket.on('disconnect', () => {
console.log(`A client disconnected from stock namespace: ${socket.id}`);
});
});
客户端代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Socket.IO Example</title>
</head>
<body>
<h1>关注股票</h1>
<input type="text" id="symbol" placeholder="股票代码"><br/>
<button id="follow">关注</button>
<button id="unfollow">取消关注</button>
<hr>
<ul id="messages"></ul>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io('/finance/stock');
const messages = document.getElementById('messages');
// 监听连接事件
socket.on('connect', () => {
console.log(`Connected to server: ${socket.id}`);
});
// 监听断开连接事件
socket.on('disconnect', () => {
console.log(`Disconnected from server: ${socket.id}`);
});
// 监听收到新价格事件
socket.on('update price', (data) => {
console.log('Received update:', data);
messages.innerHTML += `<li>${data.symbol} - ${data.price}</li>`;
});
// 点击关注按钮
document.getElementById('follow').addEventListener('click', () => {
const symbol = document.getElementById('symbol').value;
socket.emit('follow stock', symbol);
});
// 点击取消关注按钮
document.getElementById('unfollow').addEventListener('click', () => {
const symbol = document.getElementById('symbol').value;
socket.emit('unfollow stock', symbol);
});
</script>
</body>
</html>
以上就是Node.js中Socket.IO的进阶使用技巧的完整攻略,包括Socket.IO的基础功能和进阶功能。希望对你有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:node.js中Socket.IO的进阶使用技巧 - Python技术站