桌面客户端
浏览器里能用,但有些事浏览器做不了:关窗就断、没法常驻、不能在游戏画面上叠个成员列表。
桌面客户端就是补这些的。它把同一套界面装进系统 WebView,再补上原生能力。
什么时候该用它
| 你在干什么 | 用浏览器 | 用桌面端 |
|---|---|---|
| 偶尔进来说两句 | 够用 | 没必要 |
| 长时间挂着语音 | 得一直留着标签页 | 关窗进托盘,随时能说话 |
| 边打游戏边听语音 | 切窗口很烦 | 有浮在游戏上的成员浮窗 |
| 想让开机就自动连上 | 不行 | 可以 |
| 想用快捷键一键闭麦 | 得先切回浏览器 | 全局快捷键,在游戏里也生效 |
下载安装
从 Releases 页面找 desktop-v 开头的版本:
| 平台 | 文件 | 怎么装 |
|---|---|---|
| macOS | .dmg | 打开,把 GOSpeak 拖进「应用程序」 |
| Windows | .exe | 双击安装 |
| Linux | 二进制 | 直接运行 |
macOS 有 Apple Silicon 和 Intel 两个版本,下错版本打不开。
首次打开如果被系统拦住,去「系统设置 → 隐私与安全性」点「仍要打开」。这是因为安装包没有签名,不是病毒。
第一次打开要填服务器地址
桌面端不连任何默认服务器——你得告诉它连哪台。
打开后会停在登录页,那里有个「服务器地址」输入框:
https://voice.example.com填你自己部署的地址,点保存。窗口会重载一次,之后所有请求都发给这台服务器。
为什么是本地代理
填完地址后,桌面端会在你本机 127.0.0.1 上起一个小代理:
桌面窗口 ──► 127.0.0.1:随机端口(本机代理)
├─ 前端页面(内置在客户端里)
├─ /api ──► 你的服务器
├─ /ws ──► 你的服务器
└─ /uploads ──► 你的服务器这样做的好处:
- 页面和接口同源,没有跨域问题
- 后端的 HttpOnly Cookie 能正常用,登录态和浏览器里一样
- 换服务器只改代理目标,页面不用跳转
服务器地址存在本地,下次启动自动用。想换在设置里改,换的时候会清掉旧站点的登录态,避免串号。
自定义标题栏
窗口没有系统标题栏,是应用自己画的。但窗口按钮还是系统的:
- macOS:红绿灯,位置和系统一致
- Windows:最小化、最大化、关闭,还有贴靠布局
- Linux:你桌面环境的按钮
标题栏高度 28px,跟网页版顶栏一样高。整条栏能拖窗口,双击按系统习惯缩放。深色模式下按钮和菜单会跟着变。
任务栏、Mission Control、Alt+Tab 上永远显示 GOSpeak,不跟着页面变——窗口切换器里看着更干净。
游戏内浮窗
这是桌面端最有用的功能。一个透明的、置顶的、不占任务栏的小窗口,叠在游戏画面上,显示谁在说话。
打开它
设置 → 桌面端 → 启用游戏内覆盖层。默认是关的。
什么时候显示
两种模式:
| 模式 | 行为 |
|---|---|
| 自动 | 检测到前台有全屏应用,并且你已经进了语音频道,才显示。任一条件消失就自动藏起来 |
| 手动 | 只在你按快捷键时切换 |
自动模式适合打游戏——切进游戏自动出现,切出来自动消失,不用管。
快捷键
可以设两个全局快捷键(在别的应用里也生效):
- 显示/隐藏浮窗
- 锁定/解锁浮窗
锁定状态下浮窗不拦截鼠标,你在游戏里点它也不会误触。解锁后可以拖动它到任意位置。
不透明度
可以调,想让它更透明一点就调低。
它会不会重复进房
不会。浮窗不自己连服务器,也不建音频会话——它显示的内容是主窗口推过来的。所以开着浮窗不会导致回声或者双重加入。
托盘和后台
关窗口不会退出程序,只是藏到托盘。想真正退出得从托盘菜单点「退出」。
这是故意的——游戏语音需要一直在后台跑。
托盘菜单有:
- 打开 GOSpeak
- 退出
点 Dock 图标或者托盘图标都能把窗口叫回来。
开机自启
设置 → 桌面端 → 开机自启。开了之后登录系统就自动启动,直接进托盘。
系统通知
房间邀请、有人找你,会走系统原生通知,点一下直接跳过去。不需要像浏览器那样授权。
从源码构建
需要 Go 1.27 或更新(MyGo 的要求,比后端的 1.26 高)。
pnpm install
cd app/desktop && go mod download && cd ../..
# 开发模式:先起前端,再起宿主
pnpm dev:web # 前端在 localhost:3000
pnpm --filter @gospeak/desktop-app dev # 宿主指向上面那个地址
# 打包
GOSPEAK_TARGET=desktop pnpm --filter @gospeak/web build
rm -rf app/desktop/webui/dist && mkdir -p app/desktop/webui/dist
cp -R app/web/dist/. app/desktop/webui/dist/
pnpm --filter @gospeak/desktop-app build打包时那个 cp 不能省——前端产物要拷进 app/desktop/webui/dist/,Go 的 go:embed 会把它打进二进制。
加一个新的原生能力
- 在
app/desktop里找个*.go,给已绑定的结构体加个方法(第一个参数是context.Context,用mygo.CallerWindow(ctx)拿到调用它的窗口) - 在
packages/desktop/src/capabilities/加对应封装:一个接口、一个原生实现、一个浏览器兜底 - 跑
node scripts/check-desktop-commands.mjs检查命令名
第三步不能跳过。命令名写错时 MyGo 只会返回一个 rejected Promise,而大部分封装会静默吞掉错误——表现就是「功能没反应,也不报错」,很难查。
常见问题
提示「无法连接到服务器」 先确认浏览器能打开这个地址。如果浏览器能开、桌面端不能,多半是证书问题——自签名证书桌面端不认。
换了服务器登录态丢了 正常。换服务器会清 Cookie,需要重新登录,这是为了防止串号。
浮窗不显示 检查三件事:设置里启用了没、显示策略是不是自动、有没有真的进了语音频道(自动模式要求已连接)。
浮窗挡着游戏操作 按解锁快捷键之后能拖走,或者锁定它——锁定状态下鼠标事件会穿透。
macOS 提示「已损坏,无法打开」
xattr -cr /Applications/GOSpeak.app安装包没签名,系统打了隔离标记,这条命令清掉就行。
