JavaScript 📜
April 14

Broadcast Channel API

Пользователи могут открыть одно и то же приложение в нескольких вкладках одновременно. В некоторых случаях может потребоваться синхронизировать данные между этими вкладками.

Типичный пример - выход из системы. Пользователи могут выйти из системы в одной вкладке и остаться в системе во второй вкладке. Несмотря на то, что они вышли из системы на сервере, приложение в соседней вкладке не обрабатывает выход и далее будет показывать интерфейсы, которые должны быть скрыты.

Для решения таких задач может использоваться Broadcast Channel API. Он позволяет обмениваться сообщениями между контекстами просмотра с тем же происхождением (окна, вкладки, фреймы и iframe) в нашем приложении.

Рассмотрим простейший пример использования:

const authChannel = new BroadcastChannel('authChannel');

authChannel.addEventListener('message', () => {
  logout();
})

export function logout() {
  // logout logic
}

logoutButton.addEventListener('click', () => {
  authChannel.postMessage('logout');
  logout();
});

Все вкладки, кроме текущей, получат событие и вызовут логику выхода из системы. Также этот функционал можно использовать для синхронизации данных между вкладками, например:

import { render } from 'solid-js/web';
import { createSignal, For, onCleanup } from 'solid-js';

const todosChannel = new BroadcastChannel('todos');

function Todos() {
  const listener = todosChannel.addEventListener('message', e => {
    setTodos(e.data)
  });

  const [todos, setTodos] = createSignal(['One']);

  const addTodo = () => {
    setTodos(todos => [...todos, Math.random().toString()]);
    todosChannel.postMessage(todos());
  }

  onCleanup(() => {
    todosChannel.removeEventListener('message', listener);
  })

  return (
    <>
      <button onClick={addTodo}>Add Todo</button>

      <For each={todos()}>
        {(item) => <div>{item}</div>}
      </For>
    </>
  )
}

render(() => <Todos />, document.getElementById('root'));