# Aster

UMP (Universal Message Protocol) broker. Transport-agnostic message routing between devices, over WebSocket and HTTP.

## 服务端口

| 端口 | 协议 | 用途 |
|------|------|------|
| 8765 | WebSocket | UMP 实时连接（hello/心跳/消息路由） |
| 8766 | HTTP | UMP HTTP 绑定 + 事件 API + 本文档 |

端口可通过 `ASTER_PORT` / `ASTER_API_PORT` 覆盖。

## 鉴权

所有接口共享 token（环境变量 `ASTER_AUTH_TOKEN`）。两种传递方式：
- 请求头：`Authorization: Bearer <token>`
- 查询参数：`?token=<token>`

`/health`（8765）和 `/`（本文档，8766）免鉴权。

## UMP 消息信封

```json
{"v":1,"id":"01HK...","from":"device:phone","to":"device:laptop","type":"data","ts":1721370000000,"payload":{}}
```

- `from`/`to`：`device:<id>`、`broadcast` 或 `server`。
- `type`：`hello` / `bye` / `ping` / `pong` / `data` / `error`。
- broker 按 `to` 路由，不解释 `payload`。

## WebSocket（8765）

```
wss://aster.xindoo.xyz/?token=<token>
```

连接后发送 `hello`（`from=device:<id>`，payload 含 `name`）声明身份。服务端回 `hello`（含 `heartbeat_interval`）+ `presence.list`，并向其他设备广播 `hello`。之后可收发 `data`/`ping`/`bye`。`to=broadcast` 广播（排除发送者），`to=device:X` 直发。

## HTTP（8766）

### POST /messages
发送一个 UMP 信封，按 `to` 路由。返回 `{id, ts}`。目标不在线返回 404。

### GET /messages?device=device:X&wait=30
long-poll 一条发给 X 的消息，超时返回 204。X 在轮询期间在线。

### GET /messages/stream?device=device:X
SSE 流，持续推送发给 X 的消息。每个事件一个信封。

### GET /presence
返回在线设备列表 `{"devices":[{"id","name"}]}`。

## 事件 API（8766，独立于 UMP）

### POST /event/push
`{"name":"temperature","data":{...}}` -> `{status, event, timestamp}`。覆盖同名旧值。

### GET /event/latest?name=temperature
返回该事件最新数据：`{event, data, timestamp}`。不存在返回 404。

## 健康检查

```
GET https://aster.xindoo.xyz/health  ->  {"status":"healthy","devices":3}
```
