• 作者:老汪软件技巧
  • 发表时间:2024-08-19 00:04
  • 浏览量:

在前端开发中,WebSocket是一种常用的实时通信技术。为了有效管理WebSocket命令的处理器,开发者通常会创建一套机制来注册、查找、和移除这些处理器。SocketStore类正是为此目的设计的工具,它通过一种高效的方式组织这些处理器,使得WebSocket通信变得更加灵活和强大。

本文将详细介绍SocketStore类的实现,分解各个代码片段,并一步步解析它们的功能和用途。

SocketStore类概述

SocketStore类的主要作用是管理与WebSocket命令相关的处理器。它通过一个内部的存储结构来管理这些处理器集合,每个命令ID(cmdID)可以对应一个或多个处理器。SocketStore类提供了添加、查找、移除和清理这些处理器的功能,确保WebSocket连接中的命令能够得到正确的处理。

主要功能存储命令处理器:为特定命令ID注册处理器。查找命令处理器:根据命令ID查找已注册的处理器集合。移除命令处理器:删除特定命令ID的处理器,或清空所有处理器。处理器缓存:缓存频繁访问的命令ID,以提升查询效率。SocketStore类实现

下面,我们将详细介绍SocketStore类的每个部分,并解释它们的功能。

1. 构造函数:初始化类的基本结构

首先,让我们看看SocketStore类的构造函数,它是类的起点,用于初始化存储和缓存机制。

constructor(maxCacheSize = 100) {
  this.store = new Map(); // 主存储命令ID和处理器集合
  this.cache = new Map(); // LRU缓存,缓存热点命令ID
  this.maxCacheSize = maxCacheSize; // 缓存的最大大小
}

解释

this.cache:

this.maxCacheSize:

2. 获取处理器集合:getStore方法

getStore方法用于根据命令ID查找已注册的处理器集合。如果命令ID已经被缓存,直接从缓存中获取,否则从主存储中查找。

getStore(cmdID) {
  // 先检查缓存
  if (this.cache.has(cmdID)) {
    return this.cache.get(cmdID);
  }
  // 如果缓存中没有,检查主存储
  const handlers = this.store.get(cmdID);
  // 如果找到了处理器集合,更新缓存
  if (handlers) {
    this._updateCache(cmdID, handlers);
  }
  return handlers;
}

解释

检查主存储:

更新缓存:

返回处理器集合:

3. 添加处理器:addStore方法

addStore方法用于将处理器注册到指定的命令ID下。如果命令ID对应的处理器集合不存在,它会创建一个新的集合。

addStore(cmdID, handler, isCmdHandler = true) {
  // 尝试获取现有的处理器集合
  let handlers = this.getStore(cmdID);
  if (!handlers) {
    handlers = new Set();
    this.store.set(cmdID, handlers);
  }
  // 为处理器定义属性
  Object.defineProperty(handler, 'isCmdHandler', {
    value: isCmdHandler,
    configurable: true,
    writable: false,
  });
  // 如果处理器是命令处理器,并且还没有 CmdHandler 属性,则创建一个新的 CmdHandler
  if (isCmdHandler && !handler.CmdHandler) {
    Object.defineProperty(handler, 'CmdHandler', {
      value: new CmdHandler(handler),
      configurable: true,
      writable: false,
    });
  }
  // 将处理器添加到集合中
  handlers.add(handler);
  // 更新缓存
  this._updateCache(cmdID, handlers);
  return this;
}

解释

定义属性:

王达深入理解计算机网络_深入理解计算机系统第三版_

创建CmdHandler实例:

添加处理器到集合中:

4. 移除处理器:removeStore方法

removeStore方法用于从存储中移除某个命令ID的指定处理器,或删除整个命令ID的处理器集合。

removeStore(cmdID, fn) {
  const handlers = this.getStore(cmdID);
  if (handlers === undefined) return;
  if (fn !== undefined) {
    if (handlers.delete(fn)) clearEffect(fn);
    if (handlers.size !== 0) return;
  }
  // 如果集合为空或未指定特定处理器,删除命令ID
  this.store.delete(cmdID);
  this.cache.delete(cmdID); // 同时从缓存中移除
}

解释

移除特定处理器:

删除命令ID:

5. 清空所有处理器:clearStore方法

clearStore方法用于清空SocketStore中的所有处理器和缓存。

clearStore() {
  this.store.forEach((handlers) => handlers.forEach((fn) => clearEffect(fn)));
  this.store.clear();
  this.cache.clear(); // 同时清空缓存
}

解释

清空存储和缓存:

6. 更新缓存:_updateCache方法

_updateCache方法用于管理命令ID的缓存,确保缓存的高效性和容量控制。

_updateCache(cmdID, handlers) {
  if (this.cache.has(cmdID)) {
    this.cache.delete(cmdID); // 先删除旧的位置
  }
  this.cache.set(cmdID, handlers); // 插入到最新位置
  // 如果缓存超过最大限制,移除最老的记录
  if (this.cache.size > this.maxCacheSize) {
    const oldestKey = this.cache.keys().next().value;
    this.cache.delete(oldestKey);
  }
}

解释

控制缓存大小:

7. 清除处理器的副作用:clearEffect函数

clearEffect函数用于在移除处理器时清理其副作用,确保不再保留多余的属性或引用。

function clearEffect(handler) {
  if (handler) {
    delete handler.isCmdHandler;
    delete handler.CmdHandler;
  }
}

解释总结

通过详细解析SocketStore类的每个部分,我们可以看到它是如何高效地管理WebSocket命令的处理器集合的。SocketStore类不仅能够动态地注册和管理命令ID下的处理器,还能够通过缓存机制快速响应对热点命令ID的访问。

这种设计使得SocketStore类在处理大量命令和复杂场景时表现出色,为WebSocket通信的稳定性和高效性提供了有力支持。