npm package: @siyic/livemedia-client
Description: A simple and powerful WebSocket client SDK for real-time media applications, inspired by LiveKit
Author: danny
Latest version: 1.0.2

# WebSocket Client SDK

一个简单而强大的 WebSocket 客户端 SDK，用于 JavaScript/TypeScript 应用程序。参考了 LiveKit 项目的设计，提供了类似的功能。

## 特性

- 简单易用的 API
- 自动重连机制
- 请求-响应模式支持
- 类型安全（使用 TypeScript）
- 支持浏览器和 Node.js 环境
- 心跳检测
- 完整的事件系统
- API 定义和协议封装

## 安装

```bash
npm install @siyic/livemedia-client
```

或者

```bash
yarn add @siyic/livemedia-client
```

## 基本用法

```typescript
import {
  WebSocketApiClient,
  WebSocketApiClientEvent,
  ConnectionState,
  DataApi,
  UserApi,
  SystemApi,
  mergeApiDefinitions
} from '@siyic/livemedia-client';

// 创建合并的 API 定义
const mergedApi = mergeApiDefinitions(DataApi, UserApi, SystemApi);

// 创建客户端实例
const client = new WebSocketApiClient(mergedApi, {
  maxRetries: 3,
  pingInterval: 30000,
  requestTimeout: 10000
});

// 监听连接状态变化
client.on(WebSocketApiClientEvent.STATE_CHANGED, (state) => {
  console.log(`连接状态变化: ${state}`);
});

// 监听错误
client.on(WebSocketApiClientEvent.ERROR, (error) => {
  console.error('错误:', error.message);
});

// 监听事件
client.on(WebSocketApiClientEvent.EVENT, (eventType, payload) => {
  console.log(`收到事件: ${eventType}`, payload);
});

// 连接到 WebSocket 服务器
async function connect() {
  try {
    const api = await client.connect('ws://localhost:3000');
    console.log('连接成功');
    return api;
  } catch (error) {
    console.error('连接失败:', error.message);
    throw error;
  }
}

// 调用 API 方法
async function callApi() {
  try {
    // 方法 1: 使用 api 代理对象
    const data = await client.api.getData({ page: 1, pageSize: 10 });
    console.log('获取数据:', data);

    // 方法 2: 使用 call 方法
    const userInfo = await client.call('getUserInfo', { userId: 'user123' });
    console.log('获取用户信息:', userInfo);
  } catch (error) {
    console.error('API 调用失败:', error.message);
  }
}

// 发送事件
function sendEvent() {
  client.sendEvent('userAction', { action: 'click', target: 'button' });
}

// 断开连接
function disconnect() {
  client.disconnect();
}
```

## 高级用法

### 自定义 API 定义

```typescript
import { WebSocketApiClient, ApiDefinition } from '@siyic/livemedia-client';

// 自定义 API 定义
const customApi: ApiDefinition = {
  name: 'CustomAPI',
  methods: {
    getCustomData: {
      name: 'getCustomData',
      description: '获取自定义数据',
      validateParams: (params) => {
        return params && typeof params.id === 'number';
      },
      transformResult: (result) => {
        return {
          ...result,
          timestamp: new Date(result.timestamp)
        };
      }
    },
    updateCustomData: {
      name: 'updateCustomData',
      description: '更新自定义数据'
    }
  }
};

// 创建客户端实例
const client = new WebSocketApiClient(customApi, {
  maxRetries: 3,
  connectionTimeout: 10000,
  pingInterval: 15000,
  pingTimeout: 5000,
  requestTimeout: 8000,
});
```

### 使用低级 Protocol 类

```typescript
import { Protocol, ProtocolEvent, MessageType } from '@siyic/livemedia-client';

// 创建协议实例
const protocol = new Protocol();

// 监听协议事件
protocol.on(ProtocolEvent.REQUEST, (request) => {
  console.log('收到请求:', request);
});

protocol.on(ProtocolEvent.RESPONSE, (response) => {
  console.log('收到响应:', response);
});

protocol.on(ProtocolEvent.EVENT, (event) => {
  console.log('收到事件:', event);
});

// 创建请求
const request = protocol.createRequest('getData', { id: 123 });

// 序列化请求
const serializedRequest = protocol.serialize(request);

// 反序列化消息
const message = protocol.deserialize(serializedRequest);

// 处理收到的消息
protocol.handleMessage(serializedRequest);
```

## API 文档

### WebSocketApiClient

主要的 WebSocket API 客户端类，提供完整的 API 调用功能。

#### 方法

- `connect(url: string): Promise<Record<string, (...args: any[]) => Promise<any>>>` - 连接到 WebSocket 服务器
- `disconnect(code?: number, reason?: string): void` - 断开连接
- `call<TParams = any, TResult = any>(methodName: string, params?: TParams, options?: RequestOptions): Promise<TResult>` - 调用 API 方法
- `sendEvent(eventType: string, payload?: any): void` - 发送事件

#### 属性

- `connectionState: ConnectionState` - 当前连接状态
- `api: Record<string, (...args: any[]) => Promise<any>>` - API 代理对象

#### 事件

- `WebSocketApiClientEvent.CONNECTED` - 已连接
- `WebSocketApiClientEvent.DISCONNECTED` - 已断开连接
- `WebSocketApiClientEvent.RECONNECTING` - 正在重连
- `WebSocketApiClientEvent.RECONNECTED` - 已重连
- `WebSocketApiClientEvent.STATE_CHANGED` - 状态变化
- `WebSocketApiClientEvent.ERROR` - 发生错误
- `WebSocketApiClientEvent.EVENT` - 收到事件

### Protocol

协议类，负责消息的序列化、反序列化和处理。

#### 方法

- `createRequest(method: string, payload?: any): RequestMessage` - 创建请求消息
- `createResponse(requestId: string, status: ResponseStatus, payload?: any, error?: string): ResponseMessage` - 创建响应消息
- `createEvent(eventType: string, payload?: any): EventMessage` - 创建事件消息
- `serialize(message: Message): string` - 序列化消息
- `deserialize(data: string): Message` - 反序列化消息
- `handleMessage(data: string): void` - 处理收到的消息
- `request<T = any>(sendFn: (data: string) => void, method: string, payload?: any, options?: RequestOptions): Promise<T>` - 发送请求并等待响应

#### 事件

- `ProtocolEvent.MESSAGE` - 收到消息
- `ProtocolEvent.REQUEST` - 收到请求
- `ProtocolEvent.RESPONSE` - 收到响应
- `ProtocolEvent.EVENT` - 收到事件
- `ProtocolEvent.ERROR` - 发生错误

### ApiClient

API 客户端类，负责将协议封装成易用的 API 函数。

#### 方法

- `call<TParams = any, TResult = any>(methodName: string, params?: TParams, options?: RequestOptions): Promise<TResult>` - 调用 API 方法
- `sendEvent(eventType: string, payload?: any): void` - 发送事件
- `handleMessage(data: string): void` - 处理收到的消息
- `createApiProxy(): Record<string, (...args: any[]) => Promise<any>>` - 创建 API 代理对象

#### 事件

- `ApiClientEvent.EVENT` - 收到事件
- `ApiClientEvent.ERROR` - 发生错误

## 示例

查看 `examples` 目录中的示例。

## 发布到NPM

cd livemedia-client
npm login 
npm whoami 
npm publish --access=public

## 许可证

MIT