60 lines
2.4 KiB
Text
60 lines
2.4 KiB
Text
@startuml seq-telemetry
|
||
title Слежение: загрузка истории и приём телеметрии в реальном времени
|
||
autonumber
|
||
|
||
actor "Пользователь" as user
|
||
participant "TelemetryPanel" as ui
|
||
participant "TelemetryStore\n(.svelte.ts)" as store
|
||
participant "telemetryApi" as tapi
|
||
participant "client.ts" as client
|
||
participant "Backend REST" as rest
|
||
participant "Backend\nWebSocket" as ws
|
||
participant "track/+page\n($effect)" as page
|
||
participant "MapLibre\n(карта)" as map
|
||
|
||
user -> ui : ввод UUID, «Подключиться»
|
||
ui -> store : connect(id)
|
||
activate store
|
||
|
||
store -> store : проверка UUID регулярным выражением
|
||
alt UUID невалиден
|
||
store -> store : status = 'error'
|
||
store --> ui : (выход без соединения)
|
||
end
|
||
|
||
store -> store : disconnect()\nзакрыть прежний WS, очистить points
|
||
store -> store : status = 'connecting'
|
||
|
||
== Загрузка истории (некритическая) ==
|
||
store -> tapi : fetchHistory(id)
|
||
tapi -> client : get('/{id}/telemetry/')
|
||
client -> rest : GET /api/{id}/telemetry/?from&till
|
||
rest --> client : RawTelemetryPacket[] | { results }
|
||
client --> tapi : массив пакетов
|
||
tapi --> store : RawTelemetryPacket[]
|
||
store -> store : reverse() → хронологический порядок,\npoints = [...history]
|
||
note right of store : сбой сети → console.warn,\nподключение не прерывается
|
||
|
||
== WebSocket-соединение ==
|
||
store -> tapi : buildWsUrl(id)
|
||
tapi --> store : ws(s)://host/api/ws/satellite/{id}/telemetry/
|
||
store -> ws : new WebSocket(url)
|
||
ws --> store : onopen → status = 'connected'
|
||
|
||
loop каждый новый пакет
|
||
ws --> store : onmessage(JSON)
|
||
store -> store : RawPacket → TelemetryPoint\n(unix-сек → ISO 8601),\npoints = [...points, point]
|
||
store --> page : реактивное изменение points (Svelte $state)
|
||
page -> map : scene.clear()
|
||
page -> map : addLine(трек) + addMarker(старт)\n+ plotAnimatedMarker(текущая точка)
|
||
page -> map : fitBounds() — однократно (fittedBounds)
|
||
end
|
||
|
||
== Отключение ==
|
||
user -> ui : «Отключиться»
|
||
ui -> store : disconnect()
|
||
store -> ws : close()
|
||
ws --> store : onclose → status = 'idle'
|
||
store -> store : points = [], satelliteId = null
|
||
deactivate store
|
||
@enduml
|