# 调试服务器
每个 Deft 运行时都可以暴露一个进程内调试服务器,外部进程
(shell 应用、编辑器、VS Code 扩展、自定义工具)可通过 TCP 连接
到它。协议是基于换行分隔 TCP 的 JSON-RPC 2.0。
使用场景:
- 从外部 REPL 进行实时内省。
- 编辑器集成:列出 def、获取源码、检查变量、补全符号。
- 步进调试器后端。
- 热重载工作流。
## `debug/*` 标准库函数
| 函数 | 返回值 | 用途 |
|---|---|---|
| `[debug/serve :name $port]` | 服务器资源 | 启动调试服务器 |
| `[debug/stop $server]` | nil | 停止服务器 |
| `[debug/list]` | 列表 | 列出活动调试服务器 |
## 启动服务器
def srv [debug/serve :my-app 8765] echo "debug server on :8765"
现在外部进程可以连接到 `127.0.0.1:8765`,并开始发送
JSON-RPC 请求。
## 协议
基于换行分隔 TCP 的 JSON-RPC 2.0。每个请求是单行 JSON
对象;每个响应也是单行 JSON 对象。
```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "eval",
"params": { "code": "(+ 1 2)" }
}
````
```json
{
"jsonrpc": "2.0",
"id": 1,
"result": { "value": 3, "print": "" }
}
````
通知(不带 `id`)用于服务器自发发出的事件——跟踪输出、
断点触发等。
## 常用方法
| 方法 | 用途 |
|---|---|
| `eval` | 在运行时中求值一个代码字符串 |
| `list-defs` | 列出当前命名空间中的 def |
| `list-vars` | 列出当前命名空间中的变量 |
| `inspect` | 检查命名值 |
| `get-source` | 获取某个 def 的源代码 |
| `complete` | 在光标位置补全符号 |
| `reload` | 重新加载模块 |
宿主端实现请参见 `packages/stdext/src/debug-host.dft`;
可嵌入你自己工具中的 Deft 级客户端请参见
`packages/stdext/src/debug-client.dft`。
## 连接客户端
任何支持 TCP 的进程都可以连接。一个最小的 Deft 客户端:
import "deft/stdext/debug-client" as dbg def session [dbg/connect 8765] set result [dbg/eval $session "(+ 1 2)"] echo $result~value # => 3 set defs [dbg/list-defs $session] for name $defs { echo $name } dbg/_close $session
`packages/stdext/src/debug-client.dft` 提供了一个完整客户端,
支持重连、重试和请求/响应关联。
## shell 的用法
TUI 的 `shell` 应用使用调试协议提供进程内 REPL。当你把
shell“附加”到某个运行时,它会派生一个运行调试服务器的子
运行时,然后从 shell 面板驱动它:
# packages/stdext/src/repl.dft (simplified) def create {|name| if [runtime/exists? $name] { return $name } if [err? [runtime/create $name]] { return nil } runtime/spawn $name [launcher-path] %{ :repl-name $name } | }
启动的 REPL 宿主会在按名称分配的端口上打开调试服务器;
shell 连接后通过 `eval` 转发用户输入。
## 编辑器集成
编辑器应用连接到活动 shell 的调试服务器,以提供:
- 符号补全(`complete` 方法)
- 跳转到定义(`inspect` + `get-source`)
- 内联文档(`get-source` + `info/props`)
- 在 REPL 中求值(`eval`)
生产代码请参见 `packages/editor/src/editor.dft` 和
`packages/stdext/src/debug-client.dft`。
## 限制
- 每个进程最多 8 个调试服务器。
- 每个服务器最多 16 个会话。
- 会话按行缓冲;非常大的 eval 载荷应当分块发送。
## 生命周期
def srv [debug/serve :dev 8765] # ... server runs in the background, dispatching requests on the # event loop ... debug/stop $srv # graceful shutdown
`debug/stop` 关闭监听器及所有活动会话。会话会收到干净的
EOF;若想继续通信,应当重新连接。
## 快速参考
| 形式 | 用途 |
|---|---|
| `[debug/serve :name $port]` | 启动服务器 |
| `[debug/stop $server]` | 停止服务器 |
| `[debug/list]` | 活动服务器 |
| 客户端:`dbg/connect $port`(来自 stdext/debug-client) | 连接 |
| 客户端:`dbg/eval $session $code` | 求值 |
| 客户端:`dbg/list-defs $session` | 列出 def |
| 客户端:`dbg/_close $session` | 断开连接 |