-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SocketIO Возвращается (Снова) #110
Conversation
Кто такие эти ваши ack-и?!Специально для фронтендеров МатчастьAck (сокращ. от acknowledgement) — концепт из SocketIO, позволяющий после emit-а события получить подтвеждение его успешной (или не очень) обработки. По сути небольшой островок request-response общения в SocketIO Особенности реализации в проектеВсе приходящие на сервер события проекта будут возвращать ack. Он представляет из себя один объект, содержажий:
Получается, что отправка события начинает напоминать POST-запрос: отправляем что-то, а в ответ приходит 200 или проблема, которую выводим пользователю. Думаю, это удобнее, чем перед отправкой начинать ждать какого-то ответного события и отдельно обрабатывать событие ПрименениеРаботает просто: socket.emit(
"new-community", // эмитим событие new-community
{ name: "Сообщество" }, // передаём какую-то инфу
({code, message, data}) => {
// когда сервер всё обработает, вернётся ack и тригернет этот callback
console.log(code, message); // 200 "Success"
console.log(data); // {id: 4, name: "Сообщество" }
}
); Теперь для создания события не нужно начитать слушать ГлобальнееВсе системы с этим нововведениям сводятся к примерно-одинаковому потоку событий:
Что с доками?В доках у PUB-событий теперь будет по две модели: одна показывает входящий формат, вторая — формат ack-а. Скорее всего в таком порядке они в доках и будут, но в любом случае можно понять по названию модели. В дальнейшем там же могут появится и описания возможных ошибок |
Фронтендерам, ищущим инфу про ack-и, это тут, хотя можно и весь пост почитать
SocketIO снова снова с бэком
Нововведения
Фичи
common
(не соглашаться, если IDE предлагает другие пути!)Моменты по коду
Виды событий
Серверные события (ServerEvent) [SUB, subscribe]
Используются редко, нужны для добавления в документацию и emit-а их через другие события или даже ReST-методы. Создаются всё ещё внутри класса, наследующего EventSpace, но теперь в формате:
Клиентские события (ClientEvent) [PUB, publish]
Такие события нужны для обработки входящих от клиента emit-ов. Они создаются через применение декораторов (см. ниже) к методам, объявленным внутри сабкласса к EventSpace-у.
Дуплексные события (DuplexEvent) [SUB & PUB]
Многие события являются одновременно серверными и клиентскими. Тогда они называются duplex-ными. Соответственно DuplexEvent умеет всё то, что умеет ClientEvent, и всё то, что умеет SeverEvent. Если серверное и клиентское события должны иметь одно и тоже название, то нужно объявить всего одно изначально клиентское событие и сделать его дуплексным через декораторы (см. ниже).
Декораторы
.argument_parser
Этот декоратор нужен всем методам класса, наследуемого от
EventSpace
, чтобы они стали ClientEvent-ами (клиентские события). Всего один необязательный агрумент: модель, которая и будет обрабатывать приходящий JSON. Модель может быть как одна из описанных в #94, так и стандартная pydantic-модель. По-умолчанию применяется пустая модель..mark_duplex
Помечает клиентское событие как дуплекное, чтобы его можно было emit-ить. Все аргументы опциональны:
server_model
это модель, которая будет обрабатывать данные, уходящие с эмитом этого события. По-умолчанию будет использоваться та же модель, что используется для клиентского событияuse_event
позволяет получить keyword-аргументevent
в функции обработчике, чтобы событие могло эмитить само себя. False по-умолчанию.marshal_ack
Добавляет acknowledgement с моделью к событию. Используется, если из handler-а возвращается что-то, что нужно обработыть моделью, будь то словарь, объект-модель или ORM-объект (чаще последний). По сути декоратор делает тоже самое, что и
.marshal_with
, откуда и название.ack_model
это модель, которая будет обрабатывать данные, она обязательна. Если модели нет, нужно использовать декоратор.force_ack
force_wrap
сделан ради библиотечной натуры__lib__
, в нашем проекте он всегда будетTrue
, что установлено по-умолчанию.force_ack
Добавляет acknowledgement без модели к событию. Единственный аргумент,
force_wrap
, сделан ради библиотечной натуры__lib__
, в нашем проекте он всегда будетTrue
, что установлено по-умолчаниюПорядок декораторов
Новые декораторы описаны в том же порядке, в котором должны применяться в коде, сверху вниз. При использовании с другими декораторами, сначала идёт превращение функции в event (
.argument_parser
и.mark_duplex
), затем другие декораторы в стандартном порядке (описан в #27) и только потом один из декораторов обработки ack-а (.marshal_ack
или.force_ack
)Прочее
Привязка готового события
Делается, как обычно, внизу файла
api.py
(protected=True
практически всегда нужен):EventController-ов можно перечислять несколько через запятую:
Отправка серверных событий
Делается через метод
ServerEvent.emit
(или его проксиDuplexEvent.emit
) с аргументами:_room
(str | None): строка-название комнаты, на которую нужно отправить событие. Комнатаuser-<id>
для всех сокетов этого пользователя создаётся в protected-namespace-ах автоматически_include_self
(bool, True по-умолчанию): включать ли отправителя текущего клиентского события в рассылку_namespace
(str | None): переопределяет пространство имён, в котором будет отправлено событие. По-умолчанию заполнено текущим namespace-ом. Менять не рекомендуется_data
(словарь, объект модели или ORM-объект): те данных, которые должна конвертировать модель. Опциоально, при отсутствии будут использоватьсяkwargs
**kwargs
: keyword-аргументы, которые используются при создании возвращаемой модели. Используются только если в_data
лежитNone
Для удобства также существует метод
.emit_convert
, в котором чуть проще задавать параметры:.emit
, но без лидирующих_
include_self
теперьFalse
по умолчаниюuser_id
аналогичен заданиюroom=f"user-{user_id}"
, заменяетroom
если заданПриклепление к SocketIO
Контроллер нужно импортировать в
__init__
-(е/ах) и в файлеapi.py
, назвать можно<...>_events
. Чтобы он присоединился к инстанции SockeIO, нужно создатьnamespace
или добавить контроллер к существующемуnamespace
-у: