Documentation
¶
Overview ¶
Package server 是 Cloudpath 中心服务:chi REST + WS hub(edge 接入 / 浏览器 fan-out) + SQLite 持久化 + 内嵌 webui。
并发不变量(改代码前先读):
- s.mu 只保护内存态(devices/edges/browsers/限流器),**锁内绝不做磁盘 I/O**; 需要落库时在锁内收集数据、锁外调用 persistXxx。
- broadcast 只读 browsers 集合,慢消费者丢帧不阻塞(历史可从 REST 补)。
- Store 可为 nil(API-only 模式):所有落库路径必须先判空。
Index ¶
- Constants
- func InstalledApplicationPlugins(pluginsDir, lockPath string) (map[string]string, error)
- type AppHost
- func (h *AppHost) Close()
- func (h *AppHost) DispatchDeviceEvent(deviceTenantID int64, deviceKey, entityID, eventType string, ts int64)
- func (h *AppHost) DispatchDeviceObservations(tenantID int64, deviceKey string, online bool, sets []api.EntityObservationSet)
- func (h *AppHost) InstanceBindings(tenantID int64, instanceID string) ([]api.AppBindingView, bool)
- func (h *AppHost) InstanceJobDescriptors(tenantID int64, instanceID string) []api.AppJobView
- func (h *AppHost) InstanceJobs(tenantID int64, instanceID string) ([]string, bool)
- func (h *AppHost) NotifyCommandAck(commandID int64, status, detail string)
- func (h *AppHost) Start(ctx context.Context) error
- type AppHostConfig
- type Config
- type Server
Constants ¶
const AppHostEdgeID = "server"
AppHostEdgeID 是 Server 侧应用实例的部署约定 edge_id:真实 Edge 的 desired 快照按 edge_id 过滤,天然不会收到它;AppHost 以该 id 上报 observed 投影。 同一个标识符也用作应用运行时的 NodeID(中心服务就是一个节点)。 生产代码不得再写裸 "server" 字面量——那正是 overview.go 曾经绕过这个常量的方式; 测试里保留字面量是有意的,用来钉住常量对外的值。
Variables ¶
This section is empty.
Functions ¶
Types ¶
type AppHost ¶ added in v0.2.3
type AppHost struct {
// contains filtered or unexported fields
}
AppHost 在 Server 进程内运行 Application Plugin 实例(设计归属见 docs/architecture/plugin-system.md「Application Plugin → Server Plugin Host」)。
组成(各积木均已存在,本文件只做接线):
- pluginhost.Manager + plugincontrol.Host:进程面(与 Edge 同款:注册安装物、 拉起/监督插件进程、kind 感知地建立 ApplicationClient);
- appruntime.Runtime:协议面(Initialize→Describe→ConfigureInstance→ ValidateBinding→HandleEvents 流 + 效果安全边界);
- desired 事实源:Server DB 的 plugin_desired_instances(不是 Edge 期望态、 不是 plugincontrol 本地文件态)。
实例配置约定:plugin_desired_instances.config_json 是 map[string]string(租户安全 契约),而应用配置是结构化 JSON。约定应用配置 JSON 字符串放在键 app_config 下, AppHost 解出后原样交给 appruntime.ConfigureInstance。
部署约定:Application 实例的 edge_id 使用保留伪 edge "server"——真实 Edge 不会 收到它的期望态(desired 快照按 edge_id 过滤),AppHost 以该 edge_id 上报 observed 投影,UI 上即呈现为 server 侧运行的实例。
func NewAppHost ¶ added in v0.2.3
func NewAppHost(srv *Server, cfg AppHostConfig) (*AppHost, error)
NewAppHost 构造 AppHost(不启动;调用 Start)。
func (*AppHost) Close ¶ added in v0.2.3
func (h *AppHost) Close()
Close 幂等停止(外部主动停机路径)。从未 Start 过时直接释放底层资源。
func (*AppHost) DispatchDeviceEvent ¶ added in v0.2.3
func (h *AppHost) DispatchDeviceEvent(deviceTenantID int64, deviceKey, entityID, eventType string, ts int64)
DispatchDeviceEvent 把一条设备事件路由到绑定了该实体的应用实例。 nil 接收者安全(未启用 AppHost 时 Server 直接调用)。 成功路由与无路由都留痕:实体事件是稀疏高信号面(key/hall/vib/nav), 静默丢弃会让「按了没反应」类问题无从排查(2026-09-05 D3 真板实测教训)。
func (*AppHost) DispatchDeviceObservations ¶ added in v0.2.15
func (h *AppHost) DispatchDeviceObservations(tenantID int64, deviceKey string, online bool, sets []api.EntityObservationSet)
DispatchDeviceObservations delivers real property samples to bound apps. Values/quality/sampling timestamps remain intact; offline transport is never promoted to good data. No domain event, sensor name or driver id is assumed.
func (*AppHost) InstanceBindings ¶ added in v0.2.7
InstanceBindings 返回实例的 Capability 绑定投影(运行态)。ok=false 表示 实例未运行或 AppHost 未启用——绑定只存在于实例运行期间。 instance id 不跨租户全局唯一,因此运行记录按 (tenant, instance) 寻址。
func (*AppHost) InstanceJobDescriptors ¶ added in v0.2.15
func (h *AppHost) InstanceJobDescriptors(tenantID int64, instanceID string) []api.AppJobView
InstanceJobDescriptors is tenant-scoped and returns a detached projection.
func (*AppHost) InstanceJobs ¶ added in v0.2.7
InstanceJobs 返回实例声明的 job id 列表(运行态)。
func (*AppHost) NotifyCommandAck ¶ added in v0.2.3
NotifyCommandAck 在应用发起的命令收到最终回执时通知应用(RequestCompleted)。 nil 接收者安全;非最终态(sent)保留引用,等最终回执再消费。
type AppHostConfig ¶ added in v0.2.3
type AppHostConfig struct {
Enabled bool
PluginsDir string
LockPath string
StateDir string // plugincontrol 进程面本地状态目录(非 desired SSOT)
}
AppHostConfig 是 Server 侧 Application Plugin Host 的配置(Config.AppHost)。
type Config ¶
type Config struct {
Store *store.Store
Token string // 共享令牌;空 = 无鉴权(仅限本机/内网)
Version string
WebUIDir string // 开发模式:从磁盘目录服务前端(优先于内嵌)
// RetentionDays 是事件/命令保留天数,超期由 sweeper 清理。<=0 用默认 30 天。
RetentionDays int
// CmdRatePerMin 是单设备每分钟命令下发上限(防跑飞的 UI/脚本刷串口)。<=0 用默认 20。
CmdRatePerMin int
// AllowedOrigins 是 WS 握手允许的浏览器 Origin 模式(如 "console.example.com"、
// "*.example.com:8443")。留空 = 开发策略:同源 + localhost/127.0.0.1 任意端口。
// 公网部署必须显式配置(非浏览器客户端不带 Origin,不受影响)。
AllowedOrigins []string
// RequireAuth 在无用户时也强制读/写鉴权(L2 公网形态,配合服务令牌)。
RequireAuth bool
// LoginRatePerMin 是单 IP 每分钟登录尝试上限。<=0 用默认 5。
LoginRatePerMin int
// SessionDays 是服务端会话 TTL(天)。<=0 用默认 7。
SessionDays int
// SetupToken 是一次性首装令牌:非本机直连来源执行 /api/auth/setup 时必须携带
// (同机反代转发的请求也算非本机直连,见 setupFromLocalClient);
// 首次成功 setup 后进程内失效。空 = 仅允许本机直连 setup。
SetupToken string
// TrustedProxies 是可信反代 CIDR allowlist(已解析);nil = 不采信任何转发头。
TrustedProxies *auth.TrustedProxies
// PluginCatalog 是只读插件目录(可选)。nil 时默认用 Server 自己的插件控制面
// 投影构造(真实数据源),因此插件端点永不返回内置/静态样例。
PluginCatalog plugincatalog.Catalog
// PluginStore 是插件控制面持久化端口(internal/server/storeport,§3 契约)。
// nil = 未接线:插件写 API 返回 503,WS plugin_* 消息按旧协议忽略,读面为空。
// 生产必须由 SQLite 适配器注入(见 storeport/adapter_sqlite.go)。
PluginStore storeport.PluginStore
// PluginStaleAfter 是 observed 投影过期阈值;<=0 用默认 2 分钟。
PluginStaleAfter time.Duration
// AppHost 启用 Server 侧 Application Plugin Host(进程面 + 协议面 + 调度;
// 见 internal/server/apphost.go)。Enabled=false 时全部钩子 nil 安全跳过。
AppHost AppHostConfig
}
Config 是服务配置。
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server 持有全部运行态。
func (*Server) CloseAll ¶
func (s *Server) CloseAll()
CloseAll 断开全部 WS 客户端(优雅停机用,避免 Shutdown 等长连接挂死)。 用 cancel 而非 close(chan):与 broadcast 的并发发送零竞态。
func (*Server) PluginControlPlaneWired ¶
PluginControlPlaneWired 报告插件控制面持久化是否已接线(启动日志/健康自检用)。
func (*Server) RunSweeper ¶
RunSweeper 后台维护协程:命令超时标记(30s)+ 保留期清理(1h)。ctx 取消即退出。
func (*Server) SetAppHost ¶ added in v0.2.3
SetAppHost 注入 Application Plugin Host(main 在 -app-host 启用时调用; 事件/回执钩子经 nil 安全方法分发,未注入即跳过)。
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package storeadapter 是 Captain 在 STORE / SERVER 两条 lane 合并后的唯一接线点: 把 *store.Store 接到 internal/server/storeport.PluginStore 端口。
|
Package storeadapter 是 Captain 在 STORE / SERVER 两条 lane 合并后的唯一接线点: 把 *store.Store 接到 internal/server/storeport.PluginStore 端口。 |
|
Package storeport 是 Server lane 对插件控制面持久化的本地端口(依赖倒置接缝)。
|
Package storeport 是 Server lane 对插件控制面持久化的本地端口(依赖倒置接缝)。 |