一个简洁、现代的 JavaScript API,用于在浏览器中使用 WebAssembly RDP 客户端。单文件引入,开箱即用!
- 🚀 简单易用 - 清晰的 API 设计,几行代码即可连接
- 📦 单文件引入 - 只需引入一个 JS 文件,无需多个依赖
- 🎯 类型安全 - 完整的参数验证和错误处理
- ⌨️ 完整键盘支持 - 内置键盘处理,支持 100+ 按键
- 🎨 事件驱动 - 灵活的事件系统,轻松处理各种状态
- 🔌 插件化 - 模块化设计,易于扩展
- 📱 响应式 - 自动适配画布大小
<!-- 只需引入一个文件! -->
<script src="rdpclient.js"></script><!DOCTYPE html>
<html>
<head>
<title>RDP Client Demo</title>
</head>
<body>
<canvas id="screen" width="1280" height="720"></canvas>
<script src="rdpclient.js"></script>
<script>
// 创建客户端实例
const client = new RDPClient({
canvas: document.getElementById('screen'),
url: 'ws://localhost:3390',
username: 'administrator',
password: 'your-password',
width: 1280,
height: 720
});
// 注册事件监听器
client
.on('connected', () => {
console.log('连接成功!');
})
.on('disconnected', () => {
console.log('连接已断开');
})
.on('error', (error) => {
console.error('错误:', error.message);
});
// 初始化并连接
(async () => {
await client.initialize('./js_client.js');
await client.connect();
})();
</script>
</body>
</html>new RDPClient(options)| 参数 | 类型 | 必需 | 默认值 | 说明 |
|---|---|---|---|---|
canvas |
HTMLCanvasElement | ✅ | - | 用于渲染的画布元素 |
url |
string | ✅ | - | WebSocket 服务器地址 |
username |
string | ✅ | - | 用户名 |
password |
string | ✅ | - | 密码 |
domain |
string | ❌ | '' |
域名 |
width |
number | ❌ | 800 |
屏幕宽度 |
height |
number | ❌ | 600 |
屏幕高度 |
bpp |
number | ❌ | 24 |
色深 (16/24/32) |
keyboard |
string | ❌ | 'en' |
键盘布局 |
en- English (US)fr- Françaisde- Deutsches- Españolit- Italianopt- Portuguêszh- 中文ja- 日本語ko- 한국어
初始化 WASM 模块。
await client.initialize('./js_client.js');参数:
wasmPath(string, 可选) - WASM 模块路径,默认'./js_client.js'
返回: Promise<void>
连接到 RDP 服务器。
await client.connect();返回: Promise<void>
断开与 RDP 服务器的连接。
await client.disconnect();返回: Promise<void>
发送键盘事件。
client.sendKeyEvent(0x1E, true); // 按下 'A' 键
client.sendKeyEvent(0x1E, false); // 释放 'A' 键参数:
scancode(number) - 键盘扫描码pressed(boolean) - 是否按下
发送 Unicode 字符。
client.sendUnicodeEvent(0x4E2D, true); // 输入中文字符 '中'参数:
unicode(number) - Unicode 码点pressed(boolean) - 是否按下
发送鼠标事件。
client.sendMouseEvent(100, 200, 0x1000); // 左键点击参数:
x(number) - X 坐标y(number) - Y 坐标flags(number) - 鼠标标志
发送剪贴板文本。
client.sendClipboard('Hello, World!');参数:
text(string) - 文本内容
注册事件监听器。
client.on('connected', () => {
console.log('已连接');
});参数:
event(string) - 事件名称handler(Function) - 事件处理函数
返回: RDPClient (支持链式调用)
移除事件监听器。
const handler = () => console.log('连接');
client.on('connected', handler);
client.off('connected', handler);参数:
event(string) - 事件名称handler(Function) - 事件处理函数
返回: RDPClient (支持链式调用)
检查连接状态。
if (client.isConnected()) {
console.log('客户端已连接');
}返回: boolean
获取画布尺寸。
const { width, height } = client.getCanvasSize();
console.log(`画布尺寸: ${width}×${height}`);返回: { width: number, height: number }
成功连接到服务器时触发。
client.on('connected', () => {
console.log('连接成功!');
});与服务器断开连接时触发。
client.on('disconnected', () => {
console.log('连接已断开');
});发生错误时触发。
client.on('error', (errorData) => {
console.error('错误:', errorData.message);
console.error('详情:', errorData.error);
});事件数据:
{
timestamp: string, // ISO 时间戳
message: string, // 错误消息
error: any // 错误详情
}屏幕尺寸改变时触发。
client.on('resize', (sizeData) => {
console.log(`新尺寸: ${sizeData.width}×${sizeData.height}`);
});事件数据:
{
width: number, // 新宽度
height: number // 新高度
}接收到剪贴板数据时触发。
client.on('clipboard', (clipboardData) => {
console.log('剪贴板内容:', clipboardData.text);
});记录日志时触发。
client.on('log', (logData) => {
console.log(`[${logData.level}] ${logData.message}`);
});事件数据:
{
timestamp: string, // ISO 时间戳
level: string, // 日志级别 (info/warn/error)
message: string // 日志消息
}const client = new RDPClient({
canvas: document.getElementById('screen'),
url: 'ws://192.168.1.100:3390',
username: 'admin',
password: 'password123',
domain: 'DOMAIN',
width: 1920,
height: 1080,
bpp: 24,
keyboard: 'en'
});
// 注册所有事件
client
.on('connected', () => {
console.log('✅ 连接成功');
document.getElementById('status').textContent = '已连接';
})
.on('disconnected', () => {
console.log('⚠️ 连接断开');
document.getElementById('status').textContent = '未连接';
})
.on('error', (error) => {
console.error('❌ 错误:', error.message);
alert(`连接错误: ${error.message}`);
})
.on('resize', ({ width, height }) => {
console.log(`📐 分辨率: ${width}×${height}`);
})
.on('log', ({ level, message }) => {
console.log(`📝 [${level}] ${message}`);
});
// 连接
async function connectToRDP() {
try {
await client.initialize('./js_client.js');
await client.connect();
} catch (error) {
console.error('连接失败:', error);
}
}
// 断开连接
async function disconnectFromRDP() {
try {
await client.disconnect();
} catch (error) {
console.error('断开失败:', error);
}
}
// 自动清理
window.addEventListener('beforeunload', () => {
if (client.isConnected()) {
client.disconnect();
}
});try {
const client = new RDPClient({
canvas: document.getElementById('screen'),
url: 'ws://localhost:3390',
username: 'user',
password: 'pass'
});
await client.initialize();
await client.connect();
} catch (error) {
if (error.message.includes('canvas')) {
console.error('画布元素无效');
} else if (error.message.includes('url')) {
console.error('WebSocket 地址无效');
} else {
console.error('未知错误:', error);
}
}# 使用 b2 构建
b2 -j$(nproc) js_client
# 或使用 bjam
bjam -j$(nproc) js_client- 构建 WebAssembly 模块
- 启动本地 HTTP 服务器
- 打开
example.html
# 使用 Python 启动服务器
python -m http.server 8000
# 或使用 Node.js
npx http-serverGPL-2.0+
欢迎提交 Issue 和 Pull Request!
如有问题,请在 GitHub 上创建 Issue。