我们相信:世界是美好的,你是我也是。 来玩一下解压小游戏吧!

默认情况下,socket.io的代码中,是不体现命名空间的,或者说命名空间就是/。如果代码日益复杂,增加命名空间就有必要性了。命名空间的作用,就类似苏南大叔的博客文章链接一样,使用路径目录来作为文章链接的命名空间。

苏南大叔:Socket.io双向通信教程,如何理解使用命名空间? - socket
Socket.io双向通信教程,如何理解使用命名空间?(图3-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。测试环境:win10nodejs@20.18.0express@4.21.2socket.io@4.8.1

前文回顾

socket.io的路径及跨域相关的话题里面,就有提到在客户端初始化的时候,可以传递服务端地址。如果在这个地址后面加上一个目录的话,就是个命名空间了。

客户端代码

基本版,不带命名空间:

<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
//...
</script>

带命名空间:

const socket = io("/sunan");
const socket = io("ws://localhost:3000/sunan");
const socket = io("http://localhost:3000/sunan");

服务端代码

就是在原来的io后面加个.of()就是命名空间了。

//...
const socketio = require("socket.io");
const io = socketio(expressServer);
io.of("/sunan").on("connection", (socket) => {
  //...
});

测试代码

这个例子里面,一共两个命名空间,

  • 分别是/milk/beer,对应两个产品线。
  • 房间并不是单独的存在,它隶属于某个命名空间。
  • io.of().to(),只能向它名下的房间发消息。

客户端:

业务(namespace):<select id="namespace" onchange="switch__io(this.value)">
  <option value="/">默认</option>
  <option value="/milk">牛奶(/milk)</option>
  <option value="/beer">啤酒(/beer)</option>
</select>
分组(room):<select id="room" onchange="join(this.value)">
  <option value="0">--</option>
  <option value="1">绩效监控组</option>
  <option value="2">碌碌无为组</option>
</select>
<button onclick="go(1)">业务代码(+1)</button>
<button onclick="go(3)">业务代码(+3)</button>
<script src="/socket.io/socket.io.js"></script>
<script>
  let namespaces = document.getElementById('namespace');
  let all_io = [];
  for (let i = 0; i < namespaces.options.length; i++) {
    const _io = io(namespaces.options.item(i).value);
    _io.on('message', message => {
      console.log(message);
    });
    all_io.push(_io);
  }
  let current_io = all_io[0];
  function switch__io(namespace) {
    current_io = all_io.find(io => io.nsp === namespace);
    document.getElementById('room').value = '0'; // Reset room dropdown to default
  }
  function go(num) {
    current_io.emit('message', num);
  }
  function join(room) {
    // all_io[0].emit('join', room);
    current_io.emit('join', room);
  }
</script>

苏南大叔:Socket.io双向通信教程,如何理解使用命名空间? - 客户端代码
Socket.io双向通信教程,如何理解使用命名空间?(图3-2)

服务端:

let express = require("express");
let app = express();
app.use(express.static('public'));
let expressServer = app.listen(80, () => console.log('http://localhost:%s', expressServer.address().port));
const socketio = require("socket.io");
const io = socketio(expressServer);
io.on("connection", (socket) => {
    socket.on("join", (room) => {
        room = parseInt(room) || 0;
        socket.leave(1);
        socket.leave(2);
        if (room > 0) {
            socket.join(room);
            io.to(socket.id).emit("message", "欢迎" + socket.id + "加入房间" + room);
            console.log("加入房间" + room);
        }
    });
    socket.on("message", (msg) => {
        console.log("收到消息:" + msg);
        io.to(1).emit("message", "监控消息:"+socket.id + "卖了" + msg + "单");
    });
});
io.of("/milk").on("connection", (socket) => {
    socket.on("join", (room) => {
        room = parseInt(room) || 0;
        socket.leave(1);
        socket.leave(2);
        if (room > 0) {
            socket.join(room);
        }
    });
    socket.on("message", (num) => {
        io.emit("message", "全体广播:牛奶组" + socket.id + "出了" + num + "单");
        io.of("/beer").emit("message", "啤酒组发来全局贺电");
        io.of("/milk").to(1).emit("message", "监控消息:" + socket.id + "卖了牛奶" + num + "单");
    });
});
io.of("/beer").on("connection", (socket) => {
    socket.on("join", (room) => {
        room = parseInt(room) || 0;
        socket.leave(1);
        socket.leave(2);
        if (room > 0) {
            socket.join(room);
        }
    });
    socket.on("message", (num) => {
        io.emit("message", "全体广播:啤酒组" + socket.id + "出了" + num + "单");
        io.of("/milk").emit("message", "牛奶组发来全局贺电");
        io.of("/beer").to(1).emit("message", "监控消息:" + socket.id + "卖了啤酒" + num + "单");
    });
});

苏南大叔:Socket.io双向通信教程,如何理解使用命名空间? - 服务端代码
Socket.io双向通信教程,如何理解使用命名空间?(图3-3)

结语

更多苏南大叔的socket经验文章,请参考:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   socket