npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kevisual/remote-app

v0.0.7

Published

RemoteApp 是一个 WebSocket 远程应用连接类,支持断开自动重连机制。

Readme

RemoteApp

RemoteApp 是一个 WebSocket 远程应用连接类,支持断开自动重连机制。

功能特性

  • WebSocket 远程代理连接
  • 断开自动重连
  • 指数退避算法
  • 可配置重连策略参数
  • 手动重连/断开控制

安装

npm install @kevisual/remote-app

基本使用

import { RemoteApp } from '@kevisual/remote-app';

const app = new RemoteApp({
  url: 'https://kevisual.cn/ws/proxy',
  id: 'my-app',
  token: 'your-token',
  app: mainApp
});

// 等待连接建立
await app.isConnect();

// 监听代理消息
app.listenProxy();

断开重连配置

配置选项

| 选项 | 类型 | 默认值 | 说明 | |------|------|--------|------| | app | App | - | 本地应用实例 | | url | string | - | 远程服务地址 | | id | string | - | 应用 ID | | token | string | - | 认证令牌 | | emitter | EventEmitter | new EventEmitter() | 事件发射器 | | autoReconnect | boolean | true | 是否启用自动重连 | | maxReconnectAttempts | number | Infinity | 最大重连次数 | | reconnectDelay | number | 1000 | 初始重连延迟(毫秒) | | maxReconnectDelay | number | 30000 | 重连延迟最大值(毫秒) | | enableBackoff | boolean | true | 是否启用指数退避 |

配置示例

// 禁用自动重连
const app = new RemoteApp({
  url: 'https://kevisual.cn/ws/proxy',
  id: 'app1',
  token: 'your-token',
  autoReconnect: false
});

// 限制最大重连次数为 10 次
const app = new RemoteApp({
  url: 'https://kevisual.cn/ws/proxy',
  id: 'app1',
  token: 'your-token',
  maxReconnectAttempts: 10
});

// 自定义重连延迟策略(线性增长)
const app = new RemoteApp({
  url: 'https://kevisual.cn/ws/proxy',
  id: 'app1',
  token: 'your-token',
  enableBackoff: false,      // 禁用指数退避
  reconnectDelay: 2000,       // 固定 2 秒延迟
  maxReconnectAttempts5     // 最多重连 5 次
});

// 快速重连策略(适合内网环境)
const app = new RemoteApp({
  url: 'ws://internal-server/ws',
  id: 'app1',
  reconnectDelay: 500,          // 0.5 秒开始
  maxReconnectDelay: 5000,       // 最大 5 秒
  enableBackoff: true
});

方法

isConnect(): Promise<boolean>

检查或等待连接建立。

const connected = await app.isConnect();
console.log(connected ? '已连接' : '连接失败');

disconnect()

手动关闭连接并停止自动重连。

app.disconnect();

reconnect()

手动触发重连。

app.reconnect();

json(data: any)

发送 JSON 数据到远程服务。

app.json({ type: 'ping' });

listenProxy()

启动代理监听,处理远程请求。

app.listenProxy();

事件

可监听事件

| 事件 | 参数 | 说明 | |------|------|------| | open | id: string | 连接建立时触发 | | close | id: string | 连接关闭时时触发 | | message | data: any | 收到消息时触发 | | error | error: any | 发生错误时触发 | | maxReconnectAttemptsReached | id: string | 达到最大重连次数时触发 | | reconnectFailed | { id, attempt, error } | 单次重连失败时触发 |

事件监听示例

// 连接建立
app.on('open', (id) => {
  console.log(`应用 ${id} 已连接`);
});

// 连接关闭
app.on('close', (id) => {
  console.log(`应用 ${id} 连接已关闭`);
});

// 收到消息
app.on('message', (data) => {
  console.log('收到消息:', data);
});

// 发生错误
app.on('error', (error) => {
  console.error('连接错误:', error);
});

// 达到最大重连次数
app.on('maxReconnectAttemptsReached', (id) => {
  console.error(`应用 ${id} 已达到最大重连次数,停止重连`);
  // 可以在这里提示用户或采取其他措施
});

// 重连失败
app.on('reconnectFailed', ({ id, attempt, error }) => {
  console.error(`应用 ${id} 第 ${attempt} 次重连失败:`, error);
});

重连机制说明

重连流程

  1. 连接断开时触发 close 事件
  2. 检查是否满足自动重连条件(启用自动重连 + 非手动关闭)
  3. 计算重连延迟(使用指数退避算法)
  4. 达到最大重连次数则停止,触发 maxReconnectAttemptsReached 事件
  5. 延迟后尝试重新连接
  6. 连接成功则重置重连计数器,触发 open 事件
  7. 连接失败则触发 reconnectFailed 事件并继续尝试重连

指数退避算法

当启用指数退避时,重连延迟按以下公式计算:

delay = initialDelay * 2^(attempts - 1)

实际延迟取上述值与 maxReconnectDelay 的较小值。

例如,初始延迟为 1000ms 时:

  • 第 1 次重连:1000ms (1s)
  • 第 2 次重连:2000ms (2s)
  • 第 3 次重连:4000ms (4s)
  • 第 4 次重连:8000ms (8s)
  • 第 5 次重连:16000ms (16s)
  • 第 6 次重连:30000ms (30s,达到上限)

完整示例

import { RemoteApp } from '@kevisual/remote-app';

class MyService {
  private remoteApp: RemoteApp;

  constructor() {
    this.remoteApp = new RemoteApp({
      url: 'https://kevisual.cn/ws/proxy',
      id: 'my-service',
      token: process.env.REMOTE_TOKEN,
      maxReconnectAttempts: 10,
      reconnectDelay: 1000,
      maxReconnectDelay: 30000
    });

    this.setupEventListeners();
  }

  private setupEventListeners() {
    this.remoteApp.on('open', () => {
      console.log('远程连接已建立');
      this.remoteApp.listenProxy();
    });

    this.remoteApp.on('close', () => {
      console.log('远程连接已断开,正在尝试重连...');
    });

    this.remoteApp.on('maxReconnectAttemptsReached', () => {
      console.error('重连失败,请检查网络连接或服务状态');
      // 可以触发告警或通知管理员
    });
  }

  async connect() {
    const connected = await this.remoteApp.isConnect();
    if (connected) {
      console.log('连接成功');
    } else {
      console.error('连接超时');
    }
  }

  disconnect() {
    this.remoteApp.disconnect();
  }
}

const service = new MyService();
service.connect();

License

MIT