backend

package
v0.2.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package backend 负责 brave 桌面壳与后端服务之间的连接。

当前阶段(阶段 1)的策略是「连接已运行的后端」:窗口启动时探测 http://127.0.0.1:<port>,外壳只把前端请求反向代理过去,不负责拉起进程。

后续在同一个包内增加 Start/Stop(sidecar 子进程或库内嵌方式), 对上层(cmd/desktop)与前端暴露的接口保持不变。

Index

Constants

View Source
const (
	// DefaultPort 是 gobrave 的默认监听端口(见 gobrave/config.yml 的 server 段)。
	DefaultPort = 8084
	// DefaultHost 是 gobrave 的默认监听地址。
	DefaultHost = "127.0.0.1"
)

Variables

View Source
var ProxyPrefixes = []string{
	"/api",
	"/health",
	"/swagger",
	"/docs",
	"/audio",
	"/images",
	"/images-data",
	"/brave-api",
	"/container",
	"/apps",
	"/onlyoffice",
	"/go-onlyoffice",
	"/data-analysis",
	"/data-project",
	"/c/analysis/apps",
}

ProxyPrefixes 是需要转发到后端(或由后端处理的)路径前缀。

该清单与 gobrave 的 internal/router/router.go 中 mountFrontendStatic 的白名单保持一致:凡是后端负责的路径,桌面外壳都不应该在本地前端资源里找文件。

Functions

func NewHandler

func NewHandler(opts HandlerOptions) http.Handler

NewHandler 返回一个 http.Handler:

  • `/wails/*` 交给 Wails 运行时中间件(runtime.js / 绑定调用);
  • 命中 ProxyPrefixes 的请求反向代理到后端;
  • 其余请求从 Assets 里取静态文件;
  • 找不到且看起来像路由(无扩展名)时回退到 index.html,支持 SPA 路由。

Types

type Config

type Config struct {
	// Scheme 为 http 或 https。
	Scheme string
	// Host 为后端主机名或 IP。
	Host string
	// Port 为后端端口。
	Port int
}

Config 描述后端连接参数。

func LoadConfig

func LoadConfig() Config

LoadConfig 依据环境变量与默认值构造后端连接配置。

func (Config) BaseURL

func (c Config) BaseURL() string

BaseURL 返回后端根地址,例如 http://127.0.0.1:8084。

type DevProxy added in v0.2.1

type DevProxy struct {
	// contains filtered or unexported fields
}

DevProxy 是「开发模式」下的小型前置代理。

背景:`-dev-url http://localhost:5174/` 时 WebView 直接加载 Vite dev server, 页面 origin 就是 Vite,而不是我们自己的 http.Server。此时前端发出的 请求会打到 Vite 上,导致两类问题:

  1. `POST /wails/runtime` → Vite 不认这个路径,404,原生窗口打不开;
  2. `/api/...`、`/c/analysis/apps/<id>/` 等后端路径 → 要么 404,要么被 Vite 代理到**另一个**后端(vite.config.ts 里写死的 localhost:8084), 而不是本进程内嵌的那个后端。

解决方式:在 Vite 前面再加一层本地代理(本文件),由它按路径分流:

WebView → DevProxy(127.0.0.1:随机端口)
            ├── /wails/*            → Wails transport 中间件
            ├── /api、/c/analysis/apps/… → 内嵌后端(appHandler)
            └── 其余(页面、静态资源、HMR)→ Vite

这样开发模式与生产模式(本地 http.Server)行为一致:后端相关请求始终打到 **本进程内嵌后端**,前端资源与热更新始终来自 Vite。

func StartDevProxy added in v0.2.1

func StartDevProxy(
	target string,
	wailsHandler func(next http.Handler) http.Handler,
	appHandler http.Handler,
) (*DevProxy, error)

StartDevProxy 启动开发模式代理。

  • target 是 Vite 的地址(如 http://localhost:5174/);
  • wailsHandler 是 Wails transport 中间件(处理 /wails/*);
  • appHandler 是后端 handler,负责静态资源/反代后端/SPA 回退, 与生产模式的本地 http.Server 完全相同,用于服务**后端路径**, 同时在 Vite 不可用时兼作兜底(避免白屏)。

返回的 URL 应当作为 WebView 的加载地址。

func (*DevProxy) Shutdown added in v0.2.1

func (p *DevProxy) Shutdown() error

Shutdown 关闭代理。

func (*DevProxy) URL added in v0.2.1

func (p *DevProxy) URL() string

URL 返回代理根地址,例如 http://127.0.0.1:41234。

type HandlerOptions

type HandlerOptions struct {
	// Assets 是以 index.html 所在目录为根的前端文件系统。
	Assets fs.FS
	// BackendBaseURL 是反向代理的目标地址,例如 http://127.0.0.1:8084。
	BackendBaseURL string
	// WailsHandler 是 Wails 运行时的中间件(由 HTTPTransport.Handler() 提供)。
	//
	// 为什么必须注入:
	// Wails v3 的 HTTP transport 只提供「中间件」,它本该挂在 Wails 自己的
	// AssetServer 上;而桌面端为了让 POST body / WebSocket 正常工作,WebView
	// 加载的是我们自己的本地 http.Server,请求根本不经过 Wails 的 AssetServer。
	// 如果不在本地 server 上显式挂载它,`/wails/runtime`、`/wails/runtime.js`
	// 会一路穿透到 SPA 回退,前端拿到的是一段 index.html 而不是绑定结果,
	// 表现为「调用没有报错但什么也没发生」。
	WailsHandler func(next http.Handler) http.Handler
}

HandlerOptions 描述前端静态资源与后端地址。

type LocalServer

type LocalServer struct {
	// contains filtered or unexported fields
}

LocalServer 在 127.0.0.1 上启动一个真实 HTTP 服务,供 WebView 加载页面。

为什么不直接用 Wails 的 AssetServer(wails:// 自定义协议): WebKitGTK 的 URI-scheme handler 不会把 POST 请求体传给 handler (见 Wails internal/assetserver/assetserver_webview.go), 导致所有 POST 请求到达后端时 ContentLength=0, 服务端 ShouldBindJSON 读不到数据而返回 EOF。

改用真实 HTTP 端口后,POST/PUT body、SSE、WebSocket 全部走标准 HTTP, 前端也处于正常的 http:// origin 下,行为与浏览器一致。

func StartLocalServer

func StartLocalServer(handler http.Handler) (*LocalServer, error)

StartLocalServer 启动本机 HTTP 服务,返回监听地址(如 http://127.0.0.1:39217)。

func (*LocalServer) Shutdown

func (s *LocalServer) Shutdown(ctx context.Context) error

Shutdown 关闭本地服务。

func (*LocalServer) URL

func (s *LocalServer) URL() string

URL 返回服务根地址,例如 http://127.0.0.1:39217。

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager 负责探测后端可用性。

阶段 1 它只是「已运行后端的探针」;后续接入 sidecar 或库内嵌时, 在这里增加 Start/Stop 即可,调用方无需修改。

func NewManager

func NewManager(cfg Config) *Manager

NewManager 创建 Manager。

func (*Manager) BaseURL

func (m *Manager) BaseURL() string

BaseURL 返回后端根地址。

func (*Manager) Config

func (m *Manager) Config() Config

Config 返回当前配置。

func (*Manager) Health

func (m *Manager) Health(ctx context.Context) Status

Health 请求后端的 /health 探针。

func (*Manager) SetBaseURL

func (m *Manager) SetBaseURL(baseURL string)

SetBaseURL 覆盖后端根地址。

桌面端以库方式启动后端时,实际监听端口可能与配置不同 (例如 --port=0 用随机空闲端口),启动后需要回填真实地址。

type Status

type Status struct {
	BaseURL string `json:"baseURL"`
	Healthy bool   `json:"healthy"`
	Message string `json:"message"`
}

Status 描述后端连接状态,供前端调试面板展示。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL