# 调试服务器 每个 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` | 断开连接 |