todesk-web-terminal-sdk
v1.0.1
Published
一个基于 xterm.js 和 socket.io 的 Web 终端工具库,支持 React、Vue 和 UMD 调用方式。所有依赖已打包到库内,无需额外安装。
Readme
ToDesk Web Terminal SDK
一个基于 xterm.js 和 socket.io 的 Web 终端工具库,支持 React、Vue 和 UMD 调用方式。所有依赖已打包到库内,无需额外安装。
✨ 特性
- 🚀 基于 xterm.js 的高性能终端模拟器
- 🔌 支持 Socket.IO 实时通信
- 📦 支持 ES 模块和 UMD 格式
- 🎨 可自定义主题和样式
- 📱 响应式设计,支持窗口大小调整
- 🔧 灵活的配置选项
- 🌐 支持多框架:React、Vue、原生 JavaScript
📦 安装
npm install todesk-web-terminal-sdk🚀 快速开始
React 项目中使用
import React, { useEffect, useRef } from 'react'
import ToDeskWebTerminal from 'todesk-web-terminal-sdk'
import 'todesk-web-terminal-sdk/styles'
function App() {
const terminalRef = useRef<HTMLDivElement>(null)
const terminalInstanceRef = useRef<ToDeskWebTerminal | null>(null)
useEffect(() => {
if (terminalRef.current) {
// 创建终端实例
terminalInstanceRef.current = new ToDeskWebTerminal({
element: terminalRef.current,
config: {
xterm: {
rows: 30,
cols: 80,
theme: {
foreground: '#ECECEC',
background: '#000000',
cursor: '#ECECEC'
}
},
ioSocket: {
url: 'http://localhost:8080',
eventNames: {
input: 'terminal-input',
output: 'terminal-data'
}
}
},
onConnect: () => console.log('已连接'),
onDisconnect: () => console.log('已断开'),
onError: (error) => console.error('错误:', error)
})
// 连接终端
terminalInstanceRef.current.connect()
}
return () => {
terminalInstanceRef.current?.dispose()
}
}, [])
return (
<div>
<div ref={terminalRef} style={{ width: '800px', height: '600px' }} />
</div>
)
}Vue 项目中使用
<template>
<div>
<div ref="terminal" style="width: 800px; height: 600px;"></div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import ToDeskWebTerminal from 'todesk-web-terminal-sdk'
import 'todesk-web-terminal-sdk/styles'
const terminal = ref(null)
const terminalInstance = ref(null)
onMounted(async () => {
if (terminal.value) {
// 创建终端实例
terminalInstance.value = new ToDeskWebTerminal({
element: terminal.value,
config: {
xterm: {
rows: 30,
cols: 80,
theme: {
foreground: '#ECECEC',
background: '#000000',
cursor: '#ECECEC'
}
},
ioSocket: {
url: 'http://localhost:8080',
eventNames: {
input: 'terminal-input',
output: 'terminal-data'
}
}
},
onConnect: () => console.log('已连接'),
onDisconnect: () => console.log('已断开'),
onError: (error) => console.error('错误:', error)
})
// 连接终端
await terminalInstance.value.connect()
}
})
onUnmounted(() => {
terminalInstance.value?.dispose()
})
</script>UMD 方式使用
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/todesk-web-terminal-sdk/lib/index.css">
</head>
<body>
<div id="terminal-container"></div>
<script src="https://unpkg.com/todesk-web-terminal-sdk/lib/index.umd.js"></script>
<script>
const container = document.getElementById('terminal-container')
// 创建终端实例
const terminal = new TodeskWebTerminal({
element: container,
config: {
xterm: {
rows: 30,
cols: 80,
theme: {
foreground: '#ECECEC',
background: '#000000',
cursor: '#ECECEC'
}
},
ioSocket: {
url: 'http://localhost:8080',
eventNames: {
input: 'terminal-input',
output: 'terminal-data'
}
}
},
onConnect: () => console.log('已连接'),
onDisconnect: () => console.log('已断开'),
onError: (error) => console.error('错误:', error)
})
// 连接终端
terminal.connect()
</script>
</body>
</html>📚 API 文档
ToDeskWebTerminal 类
主要的终端管理类,用于创建和管理 Web 终端实例。
构造函数
new ToDeskWebTerminal(options: ToDeskWebTerminalOptions)参数类型
interface ToDeskWebTerminalOptions {
element: HTMLElement // 必需:终端容器元素
config: {
xterm?: XtermConfig // 可选:xterm.js 配置
ioSocket?: IoSocketConfig // 可选:Socket.IO 配置
}
onConnect?: () => void // 可选:连接成功回调
onDisconnect?: () => void // 可选:断开连接回调
onError?: (error: any) => void // 可选:错误回调
onData?: (data: string) => void // 可选:数据接收回调
onResize?: (size: { cols: number; rows: number }) => void // 可选:大小变化回调
}XtermConfig 配置
interface XtermConfig {
rendererType?: 'canvas' | 'dom' // 渲染器类型,默认 'canvas'
rows?: number // 终端行数,默认 30
cols?: number // 终端列数,默认 80
convertEol?: boolean // 转换行结束符,默认 true
disableStdin?: boolean // 禁用标准输入,默认 false
windowsMode?: boolean // Windows 模式,默认 true
cursorStyle?: 'block' | 'underline' | 'bar' // 光标样式,默认 'underline'
cursorBlink?: boolean // 光标闪烁,默认 true
theme?: {
foreground?: string // 前景色,默认 '#ECECEC'
background?: string // 背景色,默认 '#000000'
cursor?: string // 光标颜色,默认 'help'
lineHeight?: number // 行高,默认 20
}
}IoSocketConfig 配置
interface IoSocketConfig {
url: string // 必需:WebSocket 服务器地址
managerOpts?: any // 可选:Socket.IO Manager 配置
eventNames?: {
input?: string // 可选:输入事件名,默认 'terminal-input'
output?: string // 可选:输出事件名,默认 'terminal-data'
}
}实例方法
| 方法 | 参数 | 返回值 | 描述 |
|------|------|--------|------|
| connect() | - | Promise<void> | 连接到 WebSocket 服务器 |
| disconnect() | - | void | 断开连接 |
| fit() | - | void | 自适应终端大小 |
| clear() | - | void | 清空终端内容 |
| send(data: string) | data: string | void | 发送数据到终端 |
| write(data: string) | data: string | void | 写入数据到终端显示 |
| getTerminal() | - | Terminal \| null | 获取 xterm.js 终端实例 |
| getSocket() | - | WebTerminalSocket \| null | 获取 WebSocket 实例 |
| isConnected() | - | boolean | 检查是否已连接 |
| socketOf(path: string, opts?: any) | path: string, opts?: any | Socket | 获取指定命名空间的 socket |
| dispose() | - | void | 销毁实例并清理资源 |
🎯 使用示例
基本使用
// 创建终端实例
const terminal = new ToDeskWebTerminal({
element: document.getElementById('terminal'),
config: {
xterm: {
rows: 25,
cols: 80,
theme: {
foreground: '#ECECEC',
background: '#000000',
cursor: '#ECECEC'
}
},
ioSocket: {
url: 'http://localhost:8080',
eventNames: {
input: 'terminal-input',
output: 'terminal-data'
}
}
},
onConnect: () => console.log('终端已连接'),
onDisconnect: () => console.log('终端已断开'),
onError: (error) => console.error('连接错误:', error),
onData: (data) => console.log('接收到数据:', data),
onResize: (size) => console.log('终端大小变化:', size)
})
// 连接终端
await terminal.connect()
// 控制终端
terminal.fit() // 自适应大小
terminal.clear() // 清空内容
terminal.send('ls\n') // 发送命令
terminal.write('Hello') // 写入文本
// 断开连接
terminal.disconnect()
// 销毁实例
terminal.dispose()高级配置
const terminal = new ToDeskWebTerminal({
element: document.getElementById('terminal'),
config: {
xterm: {
rendererType: 'canvas',
rows: 30,
cols: 120,
convertEol: true,
disableStdin: false,
windowsMode: true,
cursorStyle: 'block',
cursorBlink: true,
theme: {
foreground: '#ECECEC',
background: '#1a1a1a',
cursor: '#00ff00',
lineHeight: 1.2
}
},
ioSocket: {
url: 'ws://localhost:8080',
managerOpts: {
reconnection: true,
reconnectionAttempts: 5,
reconnectionDelay: 2000,
timeout: 10000,
transports: ['websocket']
},
eventNames: {
input: 'terminal-input',
output: 'terminal-output'
}
}
},
onConnect: () => {
console.log('✅ 终端连接成功')
// 连接成功后可以执行初始化操作
},
onDisconnect: (reason) => {
console.log('❌ 终端连接断开:', reason)
// 可以在这里处理重连逻辑
},
onError: (error) => {
console.error('🚨 终端错误:', error)
// 错误处理逻辑
},
onData: (data) => {
// 处理接收到的数据
console.log('📥 数据:', data)
},
onResize: (size) => {
console.log('📏 终端大小:', size.cols, 'x', size.rows)
// 可以通知服务器终端大小变化
}
})🔧 开发
# 安装依赖
npm install
# 启动开发服务器
npm run dev
# 构建库文件
npm run build:lib
# 构建演示应用
npm run build:app
# 启动完整演示
npm run demo
# 启动 WebSocket 服务器
npm run start📁 构建产物
lib/index.es.js- ES 模块格式lib/index.umd.js- UMD 格式lib/index.d.ts- TypeScript 类型声明lib/index.css- 样式文件
📚 文档
🌐 在线示例
启动服务器后可以访问以下示例:
- React 应用: http://localhost:8080/
- UMD 示例: http://localhost:8080/examples/umd-example.html
- 所有示例: http://localhost:8080/examples/
🛠️ 技术栈
- 核心: xterm.js 5.5, socket.io-client 4.8
- 构建: Vite 7, TypeScript 5.8
- 支持: React 18+, Vue 3+, 原生 JavaScript
- 样式: CSS3, 支持主题自定义
📝 注意事项
- 服务器要求: 需要支持 Socket.IO 的 WebSocket 服务器
- 浏览器兼容: 支持现代浏览器(Chrome 60+, Firefox 55+, Safari 12+)
- 内存管理: 使用完毕后请调用
dispose()方法清理资源 - 错误处理: 建议实现完整的错误处理机制
🤝 贡献
欢迎提交 Issue 和 Pull Request!
📄 许可证
MIT License
