Broadcast Client
Client
Simple client implementation to make it easier to use Broadcast Channel for multi-tab communication. Using broadcast-channel for polyfill. You can also use the Broadcast Channel API.
/src/**/broadcast-client.ts
import type { OnMessageHandler } from 'broadcast-channel';
import { BroadcastChannel } from 'broadcast-channel';
// Add channels as needed
type AvailableChannel = 'logout';
class BroadcastClient {
private channels: Map<AvailableChannel, BroadcastChannel>;
constructor() {
this.channels = new Map();
}
private getChannel<T>(channelName: AvailableChannel): BroadcastChannel<T> {
let channel = this.channels.get(channelName);
if (!channel) {
channel = new BroadcastChannel(channelName);
this.channels.set(channelName, channel);
}
return channel;
}
listen<T>(channelName: AvailableChannel, onmessage: OnMessageHandler<T>) {
const channel = this.getChannel<T>(channelName);
channel.onmessage = onmessage;
return () => {
this.close(channelName);
};
}
post<T>(channelName: AvailableChannel, message: T, includeSelf = false) {
if (includeSelf) {
// Broadcast channel ignore messages from the same instance
const inclusiveChannel = new BroadcastChannel<T>(channelName);
inclusiveChannel.postMessage(message);
inclusiveChannel.close();
} else {
const channel = this.getChannel<T>(channelName);
channel.postMessage(message);
}
}
close(channelName: AvailableChannel): void {
const channel = this.channels.get(channelName);
if (channel) {
channel.close();
this.channels.delete(channelName);
}
}
}
export const broadcastClient = new BroadcastClient();
Usage
/src/index.html
<script>
import {broadcastClient} from "/src/**/broadcast-client";
let logoutListener;
function handleLoad() {
logoutListener = broadcastClient.listen('logout', () => {
window.location.assign('/logged-out');
});
}
function handleUnload() {
logoutListener?.close();
}
window.addEventListener('load', handleLoad, {once: true});
window.addEventListener('beforeunload', handleUnload, {once: true});
</script>
/src/**/logoutButton.html
<script>
import {broadcastClient} from "/src/**/broadcast-client";
function propagateLogout() {
broadcastClient.post('logout', true);
}
</script>
<a href="/logged-out" onclick="propagateLogout()">Log Out</a>