命名空間
命名空間是一種通訊管道,讓您可以在單一共享連線(也稱為「多工」)上分割應用程式的邏輯。


簡介
每個命名空間都有其自己的
io.of("/orders").on("connection", (socket) => {
socket.on("order:list", () => {});
socket.on("order:create", () => {});
});
io.of("/users").on("connection", (socket) => {
socket.on("user:list", () => {});
});
const orderNamespace = io.of("/orders");
orderNamespace.on("connection", (socket) => {
socket.join("room1");
orderNamespace.to("room1").emit("hello");
});
const userNamespace = io.of("/users");
userNamespace.on("connection", (socket) => {
socket.join("room1"); // distinct from the room in the "orders" namespace
userNamespace.to("room1").emit("holà");
});
const orderNamespace = io.of("/orders");
orderNamespace.use((socket, next) => {
// ensure the socket has access to the "orders" namespace, and then
next();
});
const userNamespace = io.of("/users");
userNamespace.use((socket, next) => {
// ensure the socket has access to the "users" namespace, and then
next();
});
可能的用例
- 您想要建立一個只有授權使用者可以存取的特殊命名空間,因此與這些使用者相關的邏輯與應用程式的其他部分分開
const adminNamespace = io.of("/admin");
adminNamespace.use((socket, next) => {
// ensure the user has sufficient rights
next();
});
adminNamespace.on("connection", socket => {
socket.on("delete user", () => {
// ...
});
});
- 您的應用程式有多個租戶,因此您想要動態為每個租戶建立一個命名空間
const workspaces = io.of(/^\/\w+$/);
workspaces.on("connection", socket => {
const workspace = socket.nsp;
workspace.emit("hello");
});
主命名空間
到目前為止,您已與稱為 /
的主命名空間進行互動。io
實例繼承其所有方法
io.on("connection", (socket) => {});
io.use((socket, next) => { next() });
io.emit("hello");
// are actually equivalent to
io.of("/").on("connection", (socket) => {});
io.of("/").use((socket, next) => { next() });
io.of("/").emit("hello");
有些教學課程也可能會提到 io.sockets
,它只是 io.of("/")
的別名。
io.sockets === io.of("/")
自訂命名空間
若要設定自訂命名空間,您可以在伺服器端呼叫 of
函數
const nsp = io.of("/my-namespace");
nsp.on("connection", socket => {
console.log("someone connected");
});
nsp.emit("hi", "everyone!");
用戶端初始化
同源版本
const socket = io(); // or io("/"), the main namespace
const orderSocket = io("/orders"); // the "orders" namespace
const userSocket = io("/users"); // the "users" namespace
跨來源/Node.js 版本
const socket = io("https://example.com"); // or io("https://example.com/"), the main namespace
const orderSocket = io("https://example.com/orders"); // the "orders" namespace
const userSocket = io("https://example.com/users"); // the "users" namespace
在上述範例中,只會建立一個 WebSocket 連線,封包會自動路由到正確的命名空間。
請注意,在以下情況下多工處理會被停用
- 對同一個命名空間進行多重建立
const socket1 = io();
const socket2 = io(); // no multiplexing, two distinct WebSocket connections
- 不同的網域
const socket1 = io("https://first.example.com");
const socket2 = io("https://second.example.com"); // no multiplexing, two distinct WebSocket connections
- 使用 forceNew 選項
const socket1 = io();
const socket2 = io("/admin", { forceNew: true }); // no multiplexing, two distinct WebSocket connections
動態命名空間
也可以動態建立命名空間,使用正規表示法
io.of(/^\/dynamic-\d+$/);
或使用函數
io.of((name, auth, next) => {
next(null, true); // or false, when the creation is denied
});
您可以在 connection
事件中存取新的命名空間
io.of(/^\/dynamic-\d+$/).on("connection", (socket) => {
const namespace = socket.nsp;
});
of()
方法的回傳值是我們所稱的父命名空間,您可以從中
- 註冊 中間件
const parentNamespace = io.of(/^\/dynamic-\d+$/);
parentNamespace.use((socket, next) => { next() });
中間件會自動註冊在每個子命名空間上。
- 廣播 事件
const parentNamespace = io.of(/^\/dynamic-\d+$/);
parentNamespace.emit("hello"); // will be sent to users in /dynamic-1, /dynamic-2, ...
注意
現有命名空間優先於動態命名空間。例如
// register "dynamic-101" namespace
io.of("/dynamic-101");
io.of(/^\/dynamic-\d+$/).on("connection", (socket) => {
// will not be called for a connection on the "dynamic-101" namespace
});
完整 API
Namespace 實例公開的完整 API 可在此處找到 here。