Обновления в реальном времени¶
Когда обновления включены, открытая вкладка рабочей области или портала показывает изменения без перезагрузки: новый ответ или заметка появляются в открытой заявке (ваш неотправленный черновик остаётся на месте), списки заявок обновляются, счётчик уведомлений и значок боковой панели следуют за колокольчиком, а клиент, смотрящий на своё обращение, видит приход вашего ответа. Рабочая область также показывает, у кого ещё открыта заявка и пишет ли он в ней.
Обновления необязательны. Без них рабочая область заново запрашивает то, что на экране, при возвращении на вкладку, защита от конфликтов в редакторе всё равно останавливает ответ, пересекшийся с чужим, а присутствие продолжает работать.
Включение обновлений¶
Установите и включите плагин Sync. В Helpdesk Pro настраивать нечего. Sync предлагает три способа доставки обновлений, и Helpdesk Pro использует тот, который Sync ставит первым:
| Транспорт | Что нужно | Насколько быстро |
|---|---|---|
| Опрос | Ничего, кроме плагина Sync. Работает всегда. | Каждые 4 секунды, пока кто-то пользуется вкладкой (realtime.poll_idle_ms). |
| Mercure | Плагин Sync Mercure 1.2.2 или новее и хаб Mercure. | Сразу. |
| Ably | Плагин Sync Ably и учётная запись Ably. Только рабочая область; портал опрашивает. | Сразу. |
Важно
Sync Mercure 1.2.2 публикует каждое обновление как приватное и не пускает анонимных подписчиков в хаб. Более старый Sync Mercure публиковал бы обновления Helpdesk Pro публично, поэтому при его наличии Helpdesk Pro вообще ничего ему не передаёт: браузеры переходят на опрос, и отчёт о состоянии сообщает об этом в realtime.reason.
Установите realtime.enabled в false, чтобы отключить обновления, не удаляя Sync.
В рабочей области¶
- Открытая заявка заново запрашивает переписку и детали, когда приходит обновление о ней. Редактор сохраняет черновик, а переименовываемая тема остаётся такой, как её набрали.
- Остальные экраны («Моя работа», «Все заявки», «Уведомления») обновляются после окончания серии обновлений, никогда при наличии несохранённых изменений и никогда в фоновой вкладке.
- Каждое обновление обновляет счётчики: числа в боковом меню, счётчик уведомлений и значок боковой панели Admin Next.
- Строка присутствия над редактором называет тех, у кого ещё открыта заявка: «Ben is viewing», «Ben is replying…» (неотправленный текст на вкладке Reply), «Ben is writing a note…» (вкладка Note) и «The client is viewing this request».
В портале¶
На странице «Your requests» и на одном обращении вошедшие клиенты тоже получают обновления. Обновление об открытом обращении заменяет его заголовок и переписку; поле ответа и всё, что в нём набрано, не затрагиваются, а скринридеры слышат «A new reply arrived.» На странице списка список заменяется свежим, если только человек не печатает в поле поиска.
Страница обращения также отправляет сигнал присутствия, поэтому сотрудники видят «The client is viewing this request». Клиенты никогда не видят присутствие сотрудников.
Присутствие¶
Открытая заявка отправляет сигнал каждые realtime.presence_heartbeat_seconds (15), а также сразу, когда её редактор начинает или перестаёт содержать неотправленный текст. Вкладка, переставшая отправлять сигналы, исчезает через 45 секунд после последнего. Присутствию не нужен плагин Sync: каждый сигнал возвращает других смотрящих заявку. Push-транспорт только делает это быстрее.
- Присутствие доступно сотрудникам, работающим с проектом заявки. Клиент всегда только «смотрит», никогда не видит никого другого и не получает обновлений присутствия.
- Сотрудники видят клиента только как «The client is viewing this request».
- Один человек с несколькими открытыми вкладками показывается один раз, с самым сильным состоянием (отвечает, затем пишет заметку, затем смотрит).
- Присутствие — предупреждение, а не блокировка. Именно защита от конфликтов останавливает перекрёстные ответы.
Как это работает¶
У каждого человека есть один приватный канал — его входящий канал. Подписаться на него может только сам человек, и никто не может публиковать в него из браузера. Имена каналов несут тег HMAC под секретом, который хранит сайт, поэтому их нельзя угадать.
Когда в заявке что-то происходит, Helpdesk Pro определяет, кто может об этом услышать, по тем же правилам доступа, что и остальной плагин, оставляет только людей с открытой живой вкладкой и отправляет каждому небольшой кадр в его входящий канал. Вкладка слушает один канал, сколько бы заявок и списков она ни показывала, поэтому опрос стоит одного запроса каждые несколько секунд на открытую вкладку.
Кадры несут идентификаторы, а не содержимое:
| Поле | Значение |
|---|---|
e |
Событие, например ticket.updated, ticket.status_changed, message.created или attachment.added, либо notification и presence |
t |
id заявки |
m |
id сообщения для событий сообщений и вложений |
at |
Когда произошло (секунды эпохи) |
a, v |
Только для кадров сотрудников: кто это сделал и было ли это public или internal |
Затем браузер читает изменения через обычные маршруты с проверкой прав, поэтому кадр, ушедший не туда, не несёт ничего, что стоило бы читать.
Что может передавать канал клиента¶
Входящий канал клиента несёт кадры только для публичных событий: ответ, публичная веха статуса (решено, открыто снова, закрыто), публичное вложение, новое обращение, в котором он участвует. Внутреннее событие вообще не создаёт кадр для клиента: ни заметка, ни изменение или удаление заметки, ни файл в заметке, ни смена исполнителя или приоритета. Кадр клиента содержит ровно e, t, at и, для ответа, m.
Кто получает кадры¶
Только люди с открытой живой вкладкой: вкладкой рабочей области или портала, которая запрашивала свою живую конфигурацию или забирала входящий канал последние десять минут. Простаивающие учётные записи ничего не стоят, поэтому публичный проект с тысячами клиентов не означает тысячи записей на каждый ответ. Браузер заново запрашивает конфигурацию каждые пять минут, что также обновляет его токен хаба.
При опросе вкладка спрашивает каждые 4 секунды, пока кто-то ею пользуется, каждые 1,5 секунды в течение полуминуты после отправки, постепенно реже (до раза в 15 секунд), когда страницу не трогали две минуты, и каждые 30 секунд в фоне. Оборвавшееся push-соединение возвращается к опросу, пока не переподключится.
Проверка¶
В отчёте о состоянии (bin/plugin helpdesk-pro status, Operations → System или GET /helpdesk-pro/status) есть блок realtime: enabled, используемый transport, reason, когда его нет (Sync отсутствует или отключён, realtime.enabled выключен, Sync Mercure слишком старый), сколько людей держат открытую живую вкладку (live_listeners) и сколько вкладок прямо сейчас держат открытую заявку (presence_rows).
При опросе можно наблюдать за собственным входящим каналом через curl с токеном рабочей области:
TOKEN=... # из POST /api/v1/auth/token
curl -s https://example.test/api/v1/helpdesk-pro/live-config -H "X-API-Token: $TOKEN"
curl -s "https://example.test/api/v1/sync/channels/pull?id=<channel>&since=<serverTimeMs>" -H "X-API-Token: $TOKEN"
Настройки¶
На вкладке Live Updates настроек плагина:
| Ключ | По умолчанию | Что делает |
|---|---|---|
realtime.enabled |
true |
Отправлять обновления через плагин Sync, когда он установлен и включён. Присутствие работает в любом случае. |
realtime.poll_idle_ms |
4000 |
При опросе — как часто открытая вкладка спрашивает новости, пока кто-то ею пользуется (не менее 1000). |
realtime.presence_heartbeat_seconds |
15 |
Как часто открытая заявка отправляет сигнал присутствия (от 5 до 40). |
Маршруты¶
Ни у одного маршрута рабочей области нет инструмента MCP: оба имеют смысл только для открытой вкладки браузера.
| Маршрут | Право | Что делает |
|---|---|---|
GET /helpdesk-pro/live-config |
desk | Живая конфигурация для вашего входящего канала: enabled, channel, transport (polling, mercure или ably), pullUrl, pullPath, mercure, ably, serverTimeMs, pollIdleMs, heartbeatSeconds, refreshSeconds и presencePath. Когда обновления выключены: {enabled: false, reason, …}. |
POST /helpdesk-pro/tickets/{id}/presence |
desk | {client_id, state}: собственный случайный id вкладки и viewing, replying, noting или leave. Отвечает {peers: [{person, kind, state, age}]}. |
GET {mount}/_live/config |
Вошедший клиент | Та же живая конфигурация для входящего канала посетителя, никогда с Ably, плюс presenceUrl и nonce формы. |
POST {mount}/_live/presence |
Вошедший клиент | Сигнал присутствия страницы обращения: ticket_id, client_id, state и nonce helpdesk-portal. Клиент всегда записывается как смотрящий, а ответ всегда {peers: []}. |
Портал опрашивает эндпоинт pull-канала Sync (GET /api/v1/sync/channels/pull) напрямую с сессионной cookie сайта; проверка доступа канала позволяет вошедшему клиенту забирать только свой входящий канал.