npm package: @kevisual/remote-app
Description: RemoteApp 是一个 WebSocket 远程应用连接类，支持断开自动重连机制。
Author: abearxiong
Latest version: 0.0.7

# RemoteApp

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

## 功能特性

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

## 安装

```bash
npm install @kevisual/remote-app
```

## 基本使用

```typescript
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` | 是否启用指数退避 |

### 配置示例

```typescript
// 禁用自动重连
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>`

检查或等待连接建立。

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

### `disconnect()`

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

```typescript
app.disconnect();
```

### `reconnect()`

手动触发重连。

```typescript
app.reconnect();
```

### `json(data: any)`

发送 JSON 数据到远程服务。

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

### `listenProxy()`

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

```typescript
app.listenProxy();
````

## 事件

### 可监听事件

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

### 事件监听示例

```typescript
// 连接建立
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，达到上限)

## 完整示例

```typescript
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