generated from mononoki/pyproj
[+!] sio legacy
This commit is contained in:
110
src/transport/sio_legacy/README.md
Normal file
110
src/transport/sio_legacy/README.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Socket.IO для старого Artex-robot
|
||||
|
||||
Адаптер подключает старый `core/com/Connector` из Artex-robot к текущим
|
||||
`SessionManager`, `Session` и `Router`. Код ядра, TCP и `main.py` не изменяется.
|
||||
Все файлы адаптера, его зависимости и тесты находятся в этой папке.
|
||||
|
||||
## Подключение
|
||||
|
||||
Из папки `server` установите зависимости:
|
||||
|
||||
```powershell
|
||||
& 'D:\_Programs\anaconda\envs\sites\python.exe' -m pip install -r src/transport/sio_legacy/requirements.txt
|
||||
```
|
||||
|
||||
Интерфейс совпадает с TCP:
|
||||
|
||||
```python
|
||||
from transport.sio_legacy import SIO
|
||||
|
||||
# sessions — тот же менеджер, который используется TCP.
|
||||
sio = SIO("0.0.0.0", 9001, sessions)
|
||||
await sio.run()
|
||||
```
|
||||
|
||||
TCP и Socket.IO могут работать одновременно с одним менеджером и роутером:
|
||||
`await asyncio.gather(tcp.run(), sio.run())`. Им нужны разные порты.
|
||||
Отмена задачи `run()` закрывает listener и активные соединения Socket.IO.
|
||||
Для порта `0` выбранный порт доступен в `sio.bound_port` после
|
||||
`await sio.started.wait()`.
|
||||
|
||||
Сервер использует [python-socketio с aiohttp](https://python-socketio.readthedocs.io/en/stable/server.html),
|
||||
поддерживает polling и WebSocket, namespace `/robot` и обычный путь `/socket.io`.
|
||||
Это Socket.IO, не отдельный WebSocket-протокол.
|
||||
|
||||
## Соответствие протоколов
|
||||
|
||||
| Старый робот | Пакет для ядра / действие адаптера |
|
||||
| --- | --- |
|
||||
| Метаданные в `auth` при соединении | `connection`, диалект `v1` |
|
||||
| Ответ ACK на `token_ask` | `token_answer` без старого token/upf |
|
||||
| ACK на `heartbeat(["Ready", "d_meta"])`, `Ready == "ok"` | Успешный `handshake_answer` |
|
||||
| ACK на `heartbeat(["d_meta"])` | `heartbeat_ask`, обновление срока в ядре |
|
||||
| `telem` / `video` / другой event с `{"payload": value}` | `{"command": event, "payload": value}` |
|
||||
| Отправка ядром `command` | Event `command` с тем же `payload` |
|
||||
| Отправка ядром `com` / `force_com` / `sys_com` | Event `command`, `payload` содержит выбранную категорию |
|
||||
| Остальные отправки ядра | Event с именем `command` пакета и `{"payload": value}` |
|
||||
|
||||
`Ready` отправляется один раз при успешном handshake: старый клиент запускает
|
||||
по этому запросу потоки телеметрии и видео. Последующие heartbeat запрашивают
|
||||
только `d_meta`. Данные, отправленные этими потоками до ACK handshake, ждут
|
||||
завершения handshake и затем поступают в ядро.
|
||||
|
||||
Первый `Ready` задерживается на `heartbeat_interval`, чтобы исходный Connector
|
||||
успел завершить инициализацию после `socketio.Client.connect()`.
|
||||
По умолчанию `heartbeat_interval=1.0`, `ack_timeout=3.0` секунды.
|
||||
Интервал вместе с ожиданием ACK должен быть меньше пяти секунд.
|
||||
У ядра остаются прежние сроки: 60 секунд до первого heartbeat, 5 секунд после
|
||||
heartbeat, 60 секунд хранения отключённой сессии. Истечение ACK также
|
||||
закрывает соединение; удаление сессии и маршрутов выполняет менеджер.
|
||||
|
||||
`video.payload`, включая JPEG `bytes`, сохраняется в `Session.last_data`
|
||||
без преобразования. Отправка через Socket.IO передаёт тот же бинарный payload.
|
||||
Текущий JSON-транспорт TCP не кодирует bytes; преобразование для других
|
||||
транспортов здесь не добавлено.
|
||||
|
||||
Исходные `telem_can`, `video_can` и другие поля `auth` доступны в
|
||||
`Connection.metadata`; последнее `d_meta` — в `Connection.dynamic_meta`.
|
||||
Они не превращаются в `in/out`, активные порты или маршруты автоматически.
|
||||
Маршруты задаются существующими средствами Router.
|
||||
|
||||
`legacy` пока нужен: у старого робота метаданные передаются через `auth`,
|
||||
управляющие ответы приходят как Socket.IO ACK, а heartbeat инициирует сервер.
|
||||
Это отличается от пакетов `v1`. Старый клиент возвращает только `sid`, без
|
||||
`upf`, и в просмотренной реализации не сохраняет новый token.
|
||||
Адаптер сохраняет ответ в `Connection.legacy_sid`, но каждое соединение
|
||||
создаёт новую сессию. Маршруты и данные прежней сессии не восстанавливаются
|
||||
по одному sid или имени робота.
|
||||
|
||||
Ошибки приёма, отправки и heartbeat записываются в лог с sid/uid и закрывают
|
||||
только соответствующее соединение. `Session.send()` продолжает работать
|
||||
через фоновые задачи. Отправки одному SID упорядочены, чтобы бинарные
|
||||
вложения разных пакетов не перемешивались.
|
||||
|
||||
## Проверки
|
||||
|
||||
Из `server`, после установки зависимостей:
|
||||
|
||||
```powershell
|
||||
$env:PYTHONDONTWRITEBYTECODE = '1'
|
||||
& 'D:\_Programs\anaconda\envs\sites\python.exe' -B -m pytest -q -p no:cacheprovider tests src/transport/sio_legacy/tests
|
||||
```
|
||||
|
||||
Тесты используют настоящий сервер, ядро и сетевые клиенты. Проверяются
|
||||
polling/WebSocket, handshake, периодический heartbeat, ранние данные потоков,
|
||||
bytes, команды, общая маршрутизация TCP/Socket.IO, ошибки фоновой отправки,
|
||||
таймаут ACK, watcher ядра, повторное закрытие и остановка listener.
|
||||
Серверные cleanup-таймеры отменяются только при завершении теста.
|
||||
|
||||
Дополнительный `test_original_robot_connector` загружает исходные Connector,
|
||||
handlers, parsers и метаданные из `E:/robot_src`, запускает его настоящие
|
||||
сетевые обработчики и потоки. Только оборудование заменено источником
|
||||
тестовых кадров и приёмником команд. Другой путь задаётся через
|
||||
`$env:ARTEX_ROBOT_SRC = 'путь/к/artex-robot'`. При отсутствии исходников этот
|
||||
дополнительный тест пропускается; остальные тесты воспроизводимы без них.
|
||||
Ключ `-B` предотвращает запись pyc в каталог внешнего проекта.
|
||||
|
||||
Не проверяются физическое оборудование робота, восстановление сессии без
|
||||
upf, авторизация и доставка бинарных данных через TCP. API/GUI маршрутов,
|
||||
автоматическое создание маршрутов и сохранение состояния после перезапуска
|
||||
не реализуются этим адаптером.
|
||||
Reference in New Issue
Block a user