Socket.io 是一个为实时应用提供双向通信的库,是前端实时通信的常用选择之一。事实上,它不仅适用于前端,也可用于后端。本篇文章将会详细介绍 Socket.io 通信机制,深入探究其原理,帮助读者从基础到进阶的了解 Socket.io 的工作方式。
基础介绍
首先,需要安装 Socket.io:npm install socket.io。 要记住的第一件事情是,Socket.io 是由两部分组成的:服务器和客户端。
服务器部分是由 Node.js 实现的,是运行 Socket.io 服务的核心。而客户端部分是由浏览器实现的,用于与服务器进行双向通信。
接下来,我们来看一下如何在服务器上初始化 Socket.io:
// www.javascriptcn.com code example
// 引入依赖模块
const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
// 监听连接事件
io.on('connection', (socket) => {
console.log('a user connected');
// 监听断开连接事件
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
// 启动服务器
http.listen(3000, () => {
console.log('listening on *:3000');
});在上面的例子中,我们初始化了一个 Express 应用程序并使用 node http 模块创建了一个 HTTP 服务器。然后,使用 Socket.io 模块将创建一个 Socket.io 服务器实例 io。最后,监听了一个 ‘connection’ 事件,并在该事件上注册了一个处理程序,应答连接请求,并记录连接成功消息及断开连接时的事件。
进阶内容
命名空间
socket.io 提供称为命名空间的功能,将侦听器绑定到单个连接,从而隔离连接。命名空间通过调用 io.of() 方法创建。接着,可以将注册事件的代码与命名空间相关联。
const nsp = io.of('/my-namespace');
nsp.on('connection', (socket) => {
console.log('someone connected');
});此代码会将名称空间限制为“/my-namespace”。这意味着,将仅处理来自该 URL 的客户端的连接。端点的名称并不太重要; url 中的名称使用多层命名空间时可能有用,但该名称本身并没有什么特别之处。
房间
另外一种 Socket.io 提供的概念是房间。它可以将侦听器绑定到组的集合,从而将信息广播到所有房间中的连接。socket.io 使用事件名称空间和房间为消息发送提供灵活性。
io.on('connection', (socket) => {
socket.join('room1');
io.to('room1').emit('message', 'hello! room1');
});这里,socket.join() 方法将一个连接加入到特定的房间中。然后,可以使用 io.to() 方法将消息广播到此房间中。
广播
广播是一种发送给所有连接的消息。socket.io 使广播变得非常容易。
io.on('connection', (socket) => {
socket.broadcast.emit('message', 'hello everyone');
});这里,socket.broadcast.emit() 将同样的消息发送给每个连接,除了当前连接。如果希望发送给每个连接,则可以使用 io.emit() 方法。
支持实时通信的交互式示例
下面是一个简单的示例,其中客户端和服务器使用 Socket.io 相连接。服务器接收来自客户端的消息之后,会将 "Hello from client" 消息返回给客户端。
服务器端代码
// www.javascriptcn.com code example
const app = require('express')();
const http = require("http").createServer(app);
const io = require("socket.io")(http)
io.on("connection", socket => {
console.log("a user connected");
socket.on("disconnect", () => {
console.log("user disconnected");
});
socket.on("chat message", (msg) => {
console.log(`message: ${msg}`);
io.emit("chat message", "Hello from server");
});
});
http.listen(3000, () => {
console.log("listening on *:3000");
});客户端代码
请注意,客户端只需发起对服务器的连接即可。通过该连接,它可以发送消息,并侦听从服务器返回的消息。
// www.javascriptcn.com code example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Socket.io example</title>
</head>
<body>
<ul id="messages"></ul>
<input id="message_input" /><button id="message_submit">send</button>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
socket.on("chat message", msg => {
console.log(msg);
const messagesEl = document.querySelector('#messages');
const newMessageEl = document.createElement('li');
newMessageEl.textContent = msg;
messagesEl.appendChild(newMessageEl);
});
document.querySelector('#message_submit').addEventListener('click', () => {
const inputEl = document.querySelector('#message_input');
const messageValue = inputEl.value;
inputEl.value = '';
socket.emit('chat message', messageValue);
});
</script>
</body>
</html>在该示例中,浏览器会连接到 localhost:3000,并构建一个 "chat" 聊天室。然后,在输入框中输入消息,单击 "send" 按钮发送消息,并在浏览器页面上查看收到的消息。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67cfeec1e46428fe9ec41ac4